commit 49828f2766f7208804e6d556be6a22f444b4a2cb Author: wserver/wangdisen <1065498738@qq.com> Date: Wed Nov 23 16:58:19 2022 +0800 第一次提交 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4db9fe4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +.buildpath +.hgignore.swp +.project +.orig +.swp +.idea/ +.settings/ +.vscode/ +vendor/ +composer.lock +gitpush.sh +pkg/ +bin/ +cbuild +**/.DS_Store +.vscode/ +.test/ +main +output/ +manifest/output/ +*.exe +tmp/ +resource/log/ +manifest/config/config.yaml +GFastV3 +/manifest/config/db.yaml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..6abf245 --- /dev/null +++ b/README.MD @@ -0,0 +1,166 @@ +# GFast-V3 +
+ +

+

GFast V3.0

+

+

+ + goframe + + + vue + + + element plus + + + typescript + + + vite + + + license + +

+
+ + + +## 平台简介 +* 基于全新Go Frame 2.0+Vue3+Element Plus开发的全栈前后端分离的管理系统 +* 前端采用vue-next-admin 、Vue、Element UI。 +* 本项目由奇讯科技团队开发。 +* 如您想购买云服务器请先领取阿里云优惠券:[点我进入](https://www.aliyun.com/minisite/goods?userCode=fcor2omk ),腾讯云优惠券:[点我领取](https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=20b1c3842f74986b2894e2c5fcde7ea2&from=console ) + +## 特征 +* 高生产率:几分钟即可搭建一个后台管理系统 +* 模块化:单应用多系统的模式,将一个完整的应用拆分为多个系统,后续扩展更加便捷,增加代码复用性。 +* 插件化: 可通过插件的方式扩展系统功能 +* 认证机制:采用gtoken的用户状态认证及casbin的权限认证 +* 路由模式:得利于goframe2.0提供了规范化的路由注册方式,无需注解自动生成api文档 +* 面向接口开发 + + +## 内置功能 + +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 +3. 岗位管理:配置系统用户所属担任职务。 +4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 +5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 参数管理:对系统动态配置常用参数。 +8. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +9. 登录日志:系统登录日志记录查询包含登录异常。 +10. 在线用户:当前系统中活跃用户状态监控。 +11. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +12. 代码生成:前后端代码的生成。 +13. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 +14. 在线构建器:拖动表单元素生成相应的HTML代码。 +15. 文件上传,缓存标签等。 + +> 项目使用模块化与插件化的方式开发,目前正在升级的插件有:cms系统、万能模型、微信管理、工单系统、问答系统、工作流引擎...,同时也欢迎大家把写好的插件上传到商城,我们来帮您实现技术变现,获取收益! + +> GFast开源以来得到了大家的很多支持,如果您愿意为GFast贡献代码或提供建议,请加微信:qixun007(备注:gfast) + +## 演示地址 +[http://v3.g-fast.cn/sys](http://v3.g-fast.cn/sys) +账号:demo 密码:123456 +## 配置 +项目数据库文件 `resource/data/db.sql` 创建数据库导入后修改配置 `manifest/config/config.yaml.bak` 复制改为`manifest/config/config.yaml` + +其中gfToken配置 +```yaml +gfToken: + cacheKey: "gfToken_" #缓存前缀 + timeOut: 10800 #token超时时间(秒) + maxRefresh: 5400 #token自动刷新时间(秒) + multiLogin: true #是否允许一个账号多人同时登录 + encryptKey: "49c54195e750b04e74a8429b17896586" #加密key (32位) + cacheModel: "redis" #存储引擎 (memory使用内存|redis使用redis) + excludePaths: #排除不做登录验证的路由地址 + - "/api/v1/system/login" +``` + +项目为前后端分离,前端地址: + +github地址:[https://tyj_admin-ui](https://tyj_admin-ui) + +gitee地址:[https://gitee.com/tiger1103/gfast-ui](https://gitee.com/tiger1103/gfast-ui) + +## 文档地址 +> 文档正在书写中,请耐心等一等。 + +## 相关视频 +[https://space.bilibili.com/254192571/channel/seriesdetail?sid=223204](https://space.bilibili.com/254192571/channel/seriesdetail?sid=223204) + +## 演示图 + + + + + + + + + + + + + + + + + + +
+ +## 感谢(排名不分先后) +> gf框架 [https://github.com/gogf/gf](https://github.com/gogf/gf) +> +> vue-next-admin [https://gitee.com/lyt-top/vue-next-admin](https://gitee.com/lyt-top/vue-next-admin) +> +> swaggo [https://github.com/swaggo/swag](https://github.com/swaggo/swag) +> +>gtoken [https://github.com/goflyfox/gtoken](https://github.com/goflyfox/gtoken) +> +>casbin [https://github.com/casbin/casbin](https://github.com/casbin/casbin) + + +PHP开源工作流引擎tpflow [https://gitee.com/ntdgg/tpflow](https://gitee.com/ntdgg/tpflow) + +CCflow 国内最优秀的开源流程引擎 [https://gitee.com/opencc/ccflow](https://gitee.com/opencc/ccflow) + +## 交流QQ群 + +> + +> 感谢你使用GFast,公司团队精力时间有限,因此我们不再提供免费的技术服务,目前Gfast QQ交流群有部分用户进行了捐赠,捐赠后请联系作者进vip用户群,vip群中问题将得到优先解答,同时也会根据您的需求进行分析和优先安排,vip群也会提供Gfast的其它福利。 +> 同时您也可以联系我们,雇佣我们团队为您干活,谢谢合作! +>快来加入群聊【Gfast框架交流群】(1群:865697297-已满,2群:444129379),发现精彩内容,记得备注加群来意。 + +## 免责声明: +> 1、Gfast仅限自己学习使用,一切商业行为与Gfast无关。 + +> 2、用户不得利用Gfast从事非法行为,用户应当合法合规的使用,发现用户在使用产品时有任何的非法行为,Gfast有权配合有关机关进行调查或向政府部门举报,Gfast不承担用户因非法行为造成的任何法律责任,一切法律责任由用户自行承担,如因用户使用造成第三方损害的,用户应当依法予以赔偿。 + +> 3、所有与使用Gfast相关的资源直接风险均由用户承担。 + + +## 商用说明 +> 商用注意事项 +如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。 + +* GFast快速开发平台采用Apache-2.0技术协议 +* 二次开发如用于商业性质或开源竞品请不要删除和修改GFast源码头部的版权与作者声明及出处 +* 允许进行商用,但是不允许二次开源出来并进行收费 +* 我们已经申请了相关的软件著作权和相关登记(证书号:软著登字第7511736号) +* 如果您在自己的项目中使用了我们项目中的扩展或模块,请在项目介绍中进行明确说明 + +## 支持开源 +如果您喜爱gfast,请给常熬夜的作者来杯咖啡吧! 点我送咖啡 + +## [感谢JetBrains提供的免费GoLand](https://jb.gg/OpenSource) +[![avatar](https://camo.githubusercontent.com/323657c6e81419b8e151e9da4c71f409e3fcc65d630535170c59fe4807dbc905/68747470733a2f2f676f6672616d652e6f72672f646f776e6c6f61642f7468756d626e61696c732f313131343131392f6a6574627261696e732e706e67)](https://jb.gg/OpenSource) diff --git a/api/v1/common/captcha.go b/api/v1/common/captcha.go new file mode 100644 index 0000000..8f8061d --- /dev/null +++ b/api/v1/common/captcha.go @@ -0,0 +1,19 @@ +/* +* @desc:验证码参数 +* +* +* @Date: 2022/3/2 17:47 + */ + +package common + +import "github.com/gogf/gf/v2/frame/g" + +type CaptchaReq struct { + g.Meta `path:"/get" tags:"验证码" method:"get" summary:"获取验证码"` +} +type CaptchaRes struct { + g.Meta `mime:"application/json"` + Key string `json:"key"` + Img string `json:"img"` +} diff --git a/api/v1/common/req.go b/api/v1/common/req.go new file mode 100644 index 0000000..22d392b --- /dev/null +++ b/api/v1/common/req.go @@ -0,0 +1,22 @@ +/* +* @desc:公共接口相关 +* +* +* @Date: 2022/3/30 9:28 + */ + +package common + +// PageReq 公共请求参数 +type PageReq struct { + DateRange []string `p:"dateRange"` //日期范围 + PageNum int `p:"pageNum"` //当前页码 + PageSize int `p:"pageSize"` //每页数 + OrderBy string //排序方式 +} + +// ListRes 列表公共返回 +type ListRes struct { + CurrentPage int `json:"currentPage"` + Total int `json:"total"` +} diff --git a/api/v1/common/upload.go b/api/v1/common/upload.go new file mode 100644 index 0000000..9925364 --- /dev/null +++ b/api/v1/common/upload.go @@ -0,0 +1,38 @@ +package common + +import "github.com/gogf/gf/v2/frame/g" + +// 单图上传 +type UploadSingleImgReq struct { + g.Meta `path:"/singleImg" tags:"上传图片" method:"post" summary:"上传图片"` +} + +// 单文件上传 +type UploadSingleFileReq struct { + g.Meta `path:"/singleFile" tags:"上传文件" method:"post" summary:"上传文件"` +} + +type UploadSingleRes struct { + g.Meta `mime:"application/json"` + UploadResponse +} + +// 多图上传 +type UploadMultipleImgReq struct { + g.Meta `path:"/multipleImg" tags:"上传多图片" method:"post" summary:"上传多图片"` +} + +// 多文件上传 +type UploadMultipleFileReq struct { + g.Meta `path:"/multipleFile" tags:"上传多文件" method:"post" summary:"上传多文件"` +} + +type UploadMultipleRes []*UploadResponse + +type UploadResponse struct { + Size int64 `json:"size"` + Path string `json:"path"` + FullPath string `json:"full_path"` + Name string `json:"name"` + Type string `json:"type"` +} diff --git a/api/v1/demo/demo.go b/api/v1/demo/demo.go new file mode 100644 index 0000000..29d905d --- /dev/null +++ b/api/v1/demo/demo.go @@ -0,0 +1,18 @@ +/* +* @desc:demo +* +* +* @Date: 2022/3/2 15:25 + */ + +package demo + +import "github.com/gogf/gf/v2/frame/g" + +type DmReq struct { + g.Meta `path:"/demo" tags:"Demo" method:"get" summary:"demo api"` +} +type DmRes struct { + g.Meta `mime:"text/html"` + Name string `json:"name"` +} diff --git a/api/v1/system/sys_auth_rule.go b/api/v1/system/sys_auth_rule.go new file mode 100644 index 0000000..d614525 --- /dev/null +++ b/api/v1/system/sys_auth_rule.go @@ -0,0 +1,111 @@ +/* +* @desc:菜单api +* +* +* @Date: 2022/3/18 10:27 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + "tyj_admin/internal/model/entity" + "tyj_admin/internal/model" +) + +type RuleSearchReq struct { + g.Meta `path:"/menu/list" tags:"菜单管理" method:"get" summary:"菜单列表"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` + Title string `p:"menuName" ` + Component string `p:"component"` +} + +type RuleListRes struct { + g.Meta `mime:"application/json"` + Rules []*model.SysAuthRuleTreeRes `json:"rules"` +} + +type RuleAddReq struct { + g.Meta `path:"/menu/add" tags:"菜单管理" method:"post" summary:"添加菜单"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` + MenuType uint `p:"menuType" v:"min:0|max:2#菜单类型最小值为:min|菜单类型最大值为:max"` + Pid uint `p:"parentId" v:"min:0"` + Name string `p:"name" v:"required#请填写规则名称"` + Title string `p:"menuName" v:"required|length:1,100#请填写标题|标题长度在:min到:max位"` + Icon string `p:"icon"` + Weigh int `p:"menuSort" ` + Condition string `p:"condition" ` + Remark string `p:"remark" ` + IsHide uint `p:"isHide"` + Path string `p:"path"` + Redirect string `p:"redirect"` // 路由重定向 + Roles []uint `p:"roles"` // 角色ids + Component string `p:"component" v:"required-if:menuType,1#组件路径不能为空"` + IsLink uint `p:"isLink"` + IsIframe uint `p:"isIframe"` + IsCached uint `p:"isKeepAlive"` + IsAffix uint `p:"isAffix"` + LinkUrl string `p:"linkUrl"` +} + +type RuleAddRes struct { +} + +type RuleGetParamsReq struct { + g.Meta `path:"/menu/getParams" tags:"菜单管理" method:"get" summary:"获取添加、编辑菜单相关参数"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` +} + +type RuleGetParamsRes struct { + g.Meta `mime:"application/json"` + Roles []*entity.SysRole `json:"roles"` + Menus []*model.SysAuthRuleInfoRes `json:"menus"` +} + +type RuleInfoReq struct { + g.Meta `path:"/menu/get" tags:"菜单管理" method:"get" summary:"获取菜单信息"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` + Id uint `p:"required#菜单id必须"` +} + +type RuleInfoRes struct { + g.Meta `mime:"application/json"` + Rule *entity.SysAuthRule `json:"rule"` + RoleIds []uint `json:"roleIds"` +} + +type RuleUpdateReq struct { + g.Meta `path:"/menu/update" tags:"菜单管理" method:"put" summary:"修改菜单"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` + Id uint `p:"id" v:"required#id必须"` + MenuType uint `p:"menuType" v:"min:0|max:2#菜单类型最小值为:min|菜单类型最大值为:max"` + Pid uint `p:"parentId" v:"min:0"` + Name string `p:"name" v:"required#请填写规则名称"` + Title string `p:"menuName" v:"required|length:1,100#请填写标题|标题长度在:min到:max位"` + Icon string `p:"icon"` + Weigh int `p:"menuSort" ` + Condition string `p:"condition" ` + Remark string `p:"remark" ` + IsHide uint `p:"isHide"` + Path string `p:"path"` + Redirect string `p:"redirect"` // 路由重定向 + Roles []uint `p:"roles"` // 角色ids + Component string `p:"component" v:"required-if:menuType,1#组件路径不能为空"` + IsLink uint `p:"isLink"` + IsIframe uint `p:"isIframe"` + IsCached uint `p:"isKeepAlive"` + IsAffix uint `p:"isAffix"` + LinkUrl string `p:"linkUrl"` +} + +type RuleUpdateRes struct { +} + +type RuleDeleteReq struct { + g.Meta `path:"/menu/delete" tags:"菜单管理" method:"delete" summary:"删除菜单"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` + Ids []int `p:"ids" v:"required#菜单id必须"` +} + +type RuleDeleteRes struct { +} diff --git a/api/v1/system/sys_config.go b/api/v1/system/sys_config.go new file mode 100644 index 0000000..2c7a15c --- /dev/null +++ b/api/v1/system/sys_config.go @@ -0,0 +1,71 @@ +/* +* @desc:系统参数配置 +* +* +* @Date: 2022/4/18 21:11 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + commonApi "tyj_admin/api/v1/common" + "tyj_admin/internal/model/entity" +) + +type ConfigSearchReq struct { + g.Meta `path:"/config/list" tags:"系统参数管理" method:"get" summary:"系统参数列表"` + ConfigName string `p:"configName"` //参数名称 + ConfigKey string `p:"configKey"` //参数键名 + ConfigType string `p:"configType"` //状态 + commonApi.PageReq +} + +type ConfigSearchRes struct { + g.Meta `mime:"application/json"` + List []*entity.SysConfig `json:"list"` + commonApi.ListRes +} + +type ConfigReq struct { + ConfigName string `p:"configName" v:"required#参数名称不能为空"` + ConfigKey string `p:"configKey" v:"required#参数键名不能为空"` + ConfigValue string `p:"configValue" v:"required#参数键值不能为空"` + ConfigType int `p:"configType" v:"required|in:0,1#系统内置不能为空|系统内置类型只能为0或1"` + Remark string `p:"remark"` +} + +type ConfigAddReq struct { + g.Meta `path:"/config/add" tags:"系统参数管理" method:"post" summary:"添加系统参数"` + *ConfigReq +} + +type ConfigAddRes struct { +} + +type ConfigGetReq struct { + g.Meta `path:"/config/get" tags:"系统参数管理" method:"get" summary:"获取系统参数"` + Id int `p:"id"` +} + +type ConfigGetRes struct { + g.Meta `mime:"application/json"` + Data *entity.SysConfig `json:"data"` +} + +type ConfigEditReq struct { + g.Meta `path:"/config/edit" tags:"系统参数管理" method:"put" summary:"修改系统参数"` + ConfigId int64 `p:"configId" v:"required|min:1#主键ID不能为空|主键ID参数错误"` + *ConfigReq +} + +type ConfigEditRes struct { +} + +type ConfigDeleteReq struct { + g.Meta `path:"/config/delete" tags:"系统参数管理" method:"delete" summary:"删除系统参数"` + Ids []int `p:"ids"` +} + +type ConfigDeleteRes struct { +} diff --git a/api/v1/system/sys_dept.go b/api/v1/system/sys_dept.go new file mode 100644 index 0000000..eee0ab9 --- /dev/null +++ b/api/v1/system/sys_dept.go @@ -0,0 +1,71 @@ +/* +* @desc:部门管理参数 +* +* +* @Date: 2022/4/6 15:07 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + "tyj_admin/internal/model" + "tyj_admin/internal/model/entity" +) + +type DeptSearchReq struct { + g.Meta `path:"/dept/list" tags:"部门管理" method:"get" summary:"部门列表"` + DeptName string `p:"deptName"` + Status string `p:"status"` +} + +type DeptSearchRes struct { + g.Meta `mime:"application/json"` + DeptList []*entity.SysDept `json:"deptList"` +} + +type DeptAddReq struct { + g.Meta `path:"/dept/add" tags:"部门管理" method:"post" summary:"添加部门"` + ParentID int `p:"parentId" v:"required#父级不能为空"` + DeptName string `p:"deptName" v:"required#部门名称不能为空"` + OrderNum int `p:"orderNum" v:"required#排序不能为空"` + Leader string `p:"leader"` + Phone string `p:"phone"` + Email string `p:"email" v:"email#邮箱格式不正确"` + Status uint `p:"status" v:"required#状态必须"` +} + +type DeptAddRes struct { +} + +type DeptEditReq struct { + g.Meta `path:"/dept/edit" tags:"部门管理" method:"put" summary:"修改部门"` + DeptId int `p:"deptId" v:"required#deptId不能为空"` + ParentID int `p:"parentId" v:"required#父级不能为空"` + DeptName string `p:"deptName" v:"required#部门名称不能为空"` + OrderNum int `p:"orderNum" v:"required#排序不能为空"` + Leader string `p:"leader"` + Phone string `p:"phone"` + Email string `p:"email" v:"email#邮箱格式不正确"` + Status uint `p:"status" v:"required#状态必须"` +} + +type DeptEditRes struct { +} + +type DeptDeleteReq struct { + g.Meta `path:"/dept/delete" tags:"部门管理" method:"delete" summary:"删除部门"` + Id int64 `p:"id" v:"required#id不能为空"` +} + +type DeptDeleteRes struct { +} + +type DeptTreeSelectReq struct { + g.Meta `path:"/dept/treeSelect" tags:"部门管理" method:"get" summary:"获取部门树形菜单"` +} + +type DeptTreeSelectRes struct { + g.Meta `mime:"application/json"` + Deps []*model.SysDeptTreeRes `json:"deps"` +} diff --git a/api/v1/system/sys_dict_data.go b/api/v1/system/sys_dict_data.go new file mode 100644 index 0000000..76225fe --- /dev/null +++ b/api/v1/system/sys_dict_data.go @@ -0,0 +1,93 @@ +/* +* @desc:字典数据api +* +* +* @Date: 2022/3/18 11:59 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + commonApi "tyj_admin/api/v1/common" + "tyj_admin/internal/model" + "tyj_admin/internal/model/entity" +) + +// GetDictReq 获取字典信息请求参数 +type GetDictReq struct { + g.Meta `path:"/dict/data/getDictData" tags:"字典管理" method:"get" summary:"获取字典数据公共方法"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` + DictType string `p:"dictType" v:"required#字典类型不能为空"` + DefaultValue string `p:"defaultValue"` +} + +// GetDictRes 完整的一个字典信息 +type GetDictRes struct { + g.Meta `mime:"application/json"` + Info *model.DictTypeRes `json:"info"` + Values []*model.DictDataRes `json:"values"` +} + +// DictDataSearchReq 分页请求参数 +type DictDataSearchReq struct { + g.Meta `path:"/dict/data/list" tags:"字典管理" method:"get" summary:"字典数据列表"` + DictType string `p:"dictType"` //字典类型 + DictLabel string `p:"dictLabel"` //字典标签 + Status string `p:"status"` //状态 + commonApi.PageReq +} + +// DictDataSearchRes 字典数据结果 +type DictDataSearchRes struct { + g.Meta `mime:"application/json"` + List []*entity.SysDictData `json:"list"` + commonApi.ListRes +} + +type DictDataReq struct { + DictLabel string `p:"dictLabel" v:"required#字典标签不能为空"` + DictValue string `p:"dictValue" v:"required#字典键值不能为空"` + DictType string `p:"dictType" v:"required#字典类型不能为空"` + DictSort int `p:"dictSort" v:"integer#排序只能为整数"` + CssClass string `p:"cssClass"` + ListClass string `p:"listClass"` + IsDefault int `p:"isDefault" v:"required|in:0,1#系统默认不能为空|默认值只能为0或1"` + Status int `p:"status" v:"required|in:0,1#状态不能为空|状态只能为0或1"` + Remark string `p:"remark"` +} + +type DictDataAddReq struct { + g.Meta `path:"/dict/data/add" tags:"字典管理" method:"post" summary:"添加字典数据"` + *DictDataReq +} + +type DictDataAddRes struct { +} + +type DictDataGetReq struct { + g.Meta `path:"/dict/data/get" tags:"字典管理" method:"get" summary:"获取字典数据"` + DictCode uint `p:"dictCode"` +} + +type DictDataGetRes struct { + g.Meta `mime:"application/json"` + Dict *entity.SysDictData `json:"dict"` +} + +type DictDataEditReq struct { + g.Meta `path:"/dict/data/edit" tags:"字典管理" method:"put" summary:"修改字典数据"` + DictCode int `p:"dictCode" v:"required|min:1#主键ID不能为空|主键ID不能小于1"` + *DictDataReq +} + +type DictDataEditRes struct { +} + +type DictDataDeleteReq struct { + g.Meta `path:"/dict/data/delete" tags:"字典管理" method:"delete" summary:"删除字典数据"` + Ids []int `p:"ids"` +} + +type DictDataDeleteRes struct { +} diff --git a/api/v1/system/sys_dict_type.go b/api/v1/system/sys_dict_type.go new file mode 100644 index 0000000..4164508 --- /dev/null +++ b/api/v1/system/sys_dict_type.go @@ -0,0 +1,70 @@ +/* +* @desc:字典类型 +* +* +* @Date: 2022/4/14 21:30 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + commonApi "tyj_admin/api/v1/common" + "tyj_admin/internal/model" + "tyj_admin/internal/model/entity" +) + +type DictTypeSearchReq struct { + g.Meta `path:"/dict/type/list" tags:"字典管理" method:"get" summary:"字典类型列表"` + DictName string `p:"dictName"` //字典名称 + DictType string `p:"dictType"` //字典类型 + Status string `p:"status"` //字典状态 + commonApi.PageReq +} + +type DictTypeSearchRes struct { + g.Meta `mime:"application/json"` + DictTypeList []*model.SysDictTypeInfoRes `json:"dictTypeList"` + commonApi.ListRes +} + +type DictTypeAddReq struct { + g.Meta `path:"/dict/type/add" tags:"字典管理" method:"post" summary:"添加字典类型"` + DictName string `p:"dictName" v:"required#字典名称不能为空"` + DictType string `p:"dictType" v:"required#字典类型不能为空"` + Status uint `p:"status" v:"required|in:0,1#状态不能为空|状态只能为0或1"` + Remark string `p:"remark"` +} + +type DictTypeAddRes struct { +} + +type DictTypeGetReq struct { + g.Meta `path:"/dict/type/get" tags:"字典管理" method:"get" summary:"获取字典类型"` + DictId uint `p:"dictId" v:"required#类型id不能为空"` +} + +type DictTypeGetRes struct { + g.Meta `mime:"application/json"` + DictType *entity.SysDictType `json:"dictType"` +} + +type DictTypeEditReq struct { + g.Meta `path:"/dict/type/edit" tags:"字典管理" method:"put" summary:"修改字典类型"` + DictId int64 `p:"dictId" v:"required|min:1#主键ID不能为空|主键ID必须为大于0的值"` + DictName string `p:"dictName" v:"required#字典名称不能为空"` + DictType string `p:"dictType" v:"required#字典类型不能为空"` + Status uint `p:"status" v:"required|in:0,1#状态不能为空|状态只能为0或1"` + Remark string `p:"remark"` +} + +type DictTypeEditRes struct { +} + +type DictTypeDeleteReq struct { + g.Meta `path:"/dict/type/delete" tags:"字典管理" method:"delete" summary:"删除字典类型"` + DictIds []int `p:"dictIds" v:"required#字典类型id不能为空"` +} + +type DictTypeDeleteRes struct { +} diff --git a/api/v1/system/sys_init.go b/api/v1/system/sys_init.go new file mode 100644 index 0000000..1e2eba3 --- /dev/null +++ b/api/v1/system/sys_init.go @@ -0,0 +1,66 @@ +package system + +import ( + "fmt" + "github.com/gogf/gf/v2/frame/g" + "tyj_admin/internal/model" +) + +type DbInitIsInitReq struct { + g.Meta `path:"/dbInit/isInit" tags:"系统初始化" method:"get" summary:"系统初始化"` +} + +type DbInitIsInitRes bool + +type DbInitGetEnvInfoReq struct { + g.Meta `path:"/dbInit/getEnvInfo" tags:"系统初始化" method:"get" summary:"获取环境信息"` +} + +type DbInitGetEnvInfoRes g.Map + +type DbInitCreateDbReq struct { + g.Meta `path:"/dbInit/createDb" tags:"系统初始化" method:"post" summary:"创建配置文件"` + DbHost string `json:"dbHost" p:"dbHost" v:"required#数据库地址必须"` + DbPort int `json:"dbPort" p:"dbPort" v:"required#数据库端口必须"` + DbUser string `json:"dbUser" p:"dbUser" v:"required#数据库用户名称必须"` + DbPass string `json:"dbPass"` + DbName string `json:"dbName" p:"dbName" v:"required#数据库名称必须"` + DbCharset string `json:"dbCharset" p:"dbCharset" v:"required#数据库编码必须"` + RedisAddress string `json:"redisAddress" p:"redisAddress" v:"required#Redis地址必须"` + RedisPort int `json:"redisPort" p:"redisPort" v:"required#Redis端口必须"` + RedisDb int `json:"redisDb" p:"redisDb" v:"required#Redis索引必须"` + RedisPass string `json:"redisPass"` +} + +type DbInitCreateDbRes bool + +func (req *DbInitCreateDbReq) ToDbInitConfig() *model.DbInitConfig { + return &model.DbInitConfig{ + Database: model.Database{ + Default: model.DbDefault{ + Host: req.DbHost, + Port: req.DbPort, + User: req.DbUser, + Pass: req.DbPass, + Name: req.DbName, + Type: "mysql", + Role: "master", + Debug: true, + Charset: req.DbCharset, + DryRun: false, + MaxIdle: 10, + MaxOpen: 10, + MaxLifetime: 10, + }, + }, + Redis: model.Redis{ + Default: model.RedisDefault{ + Address: fmt.Sprintf("%s:%d", req.RedisAddress, req.RedisPort), + Db: req.RedisDb, + Pass: req.RedisPass, + IdleTimeout: 600, + MaxActive: 100, + }, + }, + } +} diff --git a/api/v1/system/sys_login.go b/api/v1/system/sys_login.go new file mode 100644 index 0000000..eee9db0 --- /dev/null +++ b/api/v1/system/sys_login.go @@ -0,0 +1,37 @@ +/* +* @desc:登录 +* +* +* @Date: 2022/4/27 21:51 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + model2 "tyj_admin/internal/model" +) + +type UserLoginReq struct { + g.Meta `path:"/login" tags:"登录" method:"post" summary:"用户登录"` + Username string `p:"username" v:"required#用户名不能为空"` + Password string `p:"password" v:"required#密码不能为空"` + VerifyCode string `p:"verifyCode" v:"required#验证码不能为空"` + VerifyKey string `p:"verifyKey"` +} + +type UserLoginRes struct { + g.Meta `mime:"application/json"` + UserInfo *model2.LoginUserRes `json:"userInfo"` + Token string `json:"token"` + MenuList []*model2.UserMenus `json:"menuList"` + Permissions []string `json:"permissions"` +} + +type UserLoginOutReq struct { + g.Meta `path:"/loginOut" tags:"登录" method:"delete" summary:"退出登录"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` +} + +type UserLoginOutRes struct { +} diff --git a/api/v1/system/sys_login_log.go b/api/v1/system/sys_login_log.go new file mode 100644 index 0000000..8ecf56e --- /dev/null +++ b/api/v1/system/sys_login_log.go @@ -0,0 +1,47 @@ +/* +* @desc:登录日志 +* +* +* @Date: 2022/4/24 22:09 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + commonApi "tyj_admin/api/v1/common" + "tyj_admin/internal/model/entity" +) + +// LoginLogSearchReq 查询列表请求参数 +type LoginLogSearchReq struct { + g.Meta `path:"/loginLog/list" tags:"登录日志管理" method:"get" summary:"日志列表"` + LoginName string `p:"userName"` //登陆名 + Status string `p:"status"` //状态 + Ipaddr string `p:"ipaddr"` //登录地址 + SortName string `p:"orderByColumn"` //排序字段 + SortOrder string `p:"isAsc"` //排序方式 + LoginLocation string `p:"loginLocation"` //登录地点 + commonApi.PageReq +} + +type LoginLogSearchRes struct { + g.Meta `mime:"application/json"` + commonApi.ListRes + List []*entity.SysLoginLog `json:"list"` +} + +type LoginLogDelReq struct { + g.Meta `path:"/loginLog/delete" tags:"登录日志管理" method:"delete" summary:"删除日志"` + Ids []int `p:"ids" v:"required#ids必须"` +} + +type LoginLogDelRes struct { +} + +type LoginLogClearReq struct { + g.Meta `path:"/loginLog/clear" tags:"登录日志管理" method:"delete" summary:"清除日志"` +} + +type LoginLogClearRes struct { +} diff --git a/api/v1/system/sys_monitor.go b/api/v1/system/sys_monitor.go new file mode 100644 index 0000000..d22ee1c --- /dev/null +++ b/api/v1/system/sys_monitor.go @@ -0,0 +1,11 @@ +package system + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +type MonitorSearchReq struct { + g.Meta `path:"/monitor/server" tags:"服务监控" method:"get" summary:"服务监控"` +} + +type MonitorSearchRes g.Map diff --git a/api/v1/system/sys_post.go b/api/v1/system/sys_post.go new file mode 100644 index 0000000..5bd424d --- /dev/null +++ b/api/v1/system/sys_post.go @@ -0,0 +1,61 @@ +/* +* @desc:岗位相关参数 +* +* +* @Date: 2022/4/7 23:09 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + commonApi "tyj_admin/api/v1/common" + "tyj_admin/internal/model/entity" +) + +type PostSearchReq struct { + g.Meta `path:"/post/list" tags:"岗位管理" method:"get" summary:"岗位列表"` + PostCode string `p:"postCode"` //岗位编码 + PostName string `p:"postName"` //岗位名称 + Status string `p:"status"` //状态 + commonApi.PageReq +} + +type PostSearchRes struct { + g.Meta `mime:"application/json"` + commonApi.ListRes + PostList []*entity.SysPost `json:"postList"` +} + +type PostAddReq struct { + g.Meta `path:"/post/add" tags:"岗位管理" method:"post" summary:"添加岗位"` + PostCode string `p:"postCode" v:"required#岗位编码不能为空"` + PostName string `p:"postName" v:"required#岗位名称不能为空"` + PostSort int `p:"postSort" v:"required#岗位排序不能为空"` + Status uint `p:"status" v:"required#状态不能为空"` + Remark string `p:"remark"` +} + +type PostAddRes struct { +} + +type PostEditReq struct { + g.Meta `path:"/post/edit" tags:"岗位管理" method:"put" summary:"修改岗位"` + PostId int64 `p:"postId" v:"required#id必须"` + PostCode string `p:"postCode" v:"required#岗位编码不能为空"` + PostName string `p:"postName" v:"required#岗位名称不能为空"` + PostSort int `p:"postSort" v:"required#岗位排序不能为空"` + Status uint `p:"status" v:"required#状态不能为空"` + Remark string `p:"remark"` +} + +type PostEditRes struct { +} + +type PostDeleteReq struct { + g.Meta `path:"/post/delete" tags:"岗位管理" method:"delete" summary:"删除岗位"` + Ids []int `p:"ids"` +} + +type PostDeleteRes struct { +} diff --git a/api/v1/system/sys_role.go b/api/v1/system/sys_role.go new file mode 100644 index 0000000..97327f7 --- /dev/null +++ b/api/v1/system/sys_role.go @@ -0,0 +1,81 @@ +/* +* @desc:角色api +* +* +* @Date: 2022/3/30 9:16 + */ + +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + commonApi "tyj_admin/api/v1/common" + "tyj_admin/internal/model" + "tyj_admin/internal/model/entity" +) + +type RoleListReq struct { + g.Meta `path:"/role/list" tags:"角色管理" method:"get" summary:"角色列表"` + RoleName string `p:"roleName"` //参数名称 + Status string `p:"roleStatus"` //状态 + commonApi.PageReq +} + +type RoleListRes struct { + g.Meta `mime:"application/json"` + commonApi.ListRes + List []*entity.SysRole `json:"list"` +} + +type RoleGetParamsReq struct { + g.Meta `path:"/role/getParams" tags:"角色管理" method:"get" summary:"角色编辑参数"` +} + +type RoleGetParamsRes struct { + g.Meta `mime:"application/json"` + Menu []*model.SysAuthRuleInfoRes `json:"menu"` +} + +type RoleAddReq struct { + g.Meta `path:"/role/add" tags:"角色管理" method:"post" summary:"添加角色"` + Name string `p:"name" v:"required#角色名称不能为空"` + Status uint `p:"status" ` + ListOrder uint `p:"listOrder" ` + Remark string `p:"remark" ` + MenuIds []uint `p:"menuIds"` +} + +type RoleAddRes struct { +} + +type RoleGetReq struct { + g.Meta `path:"/role/get" tags:"角色管理" method:"get" summary:"获取角色信息"` + Id uint `p:"id" v:"required#角色id不能为空""` +} + +type RoleGetRes struct { + g.Meta `mime:"application/json"` + Role *entity.SysRole `json:"role"` + MenuIds []int `json:"menuIds"` +} + +type RoleEditReq struct { + g.Meta `path:"/role/edit" tags:"角色管理" method:"put" summary:"修改角色"` + Id int64 `p:"id" v:"required#角色id必须"` + Name string `p:"name" v:"required#角色名称不能为空"` + Status uint `p:"status" ` + ListOrder uint `p:"listOrder" ` + Remark string `p:"remark" ` + MenuIds []uint `p:"menuIds"` +} + +type RoleEditRes struct { +} + +type RoleDeleteReq struct { + g.Meta `path:"/role/delete" tags:"角色管理" method:"delete" summary:"删除角色"` + Ids []int64 `p:"ids" v:"required#角色id不能为空"` +} + +type RoleDeleteRes struct { +} diff --git a/api/v1/system/sys_user.go b/api/v1/system/sys_user.go new file mode 100644 index 0000000..134ac0f --- /dev/null +++ b/api/v1/system/sys_user.go @@ -0,0 +1,121 @@ +package system + +import ( + "github.com/gogf/gf/v2/frame/g" + commonApi "tyj_admin/api/v1/common" + "tyj_admin/internal/model" + "tyj_admin/internal/model/entity" +) + +type UserMenusReq struct { + g.Meta `path:"/user/getUserMenus" tags:"用户管理" method:"get" summary:"获取用户菜单"` + Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"` +} + +type UserMenusRes struct { + g.Meta `mime:"application/json"` + MenuList []*model.UserMenus `json:"menuList"` + Permissions []string `json:"permissions"` +} + +// UserSearchReq 用户搜索请求参数 +type UserSearchReq struct { + g.Meta `path:"/user/list" tags:"用户管理" method:"get" summary:"用户列表"` + DeptId string `p:"deptId"` //部门id + Mobile string `p:"mobile"` + Status string `p:"status"` + KeyWords string `p:"keyWords"` + commonApi.PageReq +} + +type UserSearchRes struct { + g.Meta `mime:"application/json"` + UserList []*model.SysUserRoleDeptRes `json:"userList"` + commonApi.ListRes +} + +type UserGetParamsReq struct { + g.Meta `path:"/user/params" tags:"用户管理" method:"get" summary:"用户维护参数获取"` +} + +type UserGetParamsRes struct { + g.Meta `mime:"application/json"` + RoleList []*entity.SysRole `json:"roleList"` + Posts []*entity.SysPost `json:"posts"` +} + +// SetUserReq 添加修改用户公用请求字段 +type SetUserReq struct { + DeptId uint64 `p:"deptId" v:"required#用户部门不能为空"` //所属部门 + Email string `p:"email" v:"email#邮箱格式错误"` //邮箱 + NickName string `p:"nickName" v:"required#用户昵称不能为空"` + Mobile string `p:"mobile" v:"required|phone#手机号不能为空|手机号格式错误"` + PostIds []int64 `p:"postIds"` + Remark string `p:"remark"` + RoleIds []int64 `p:"roleIds"` + Sex int `p:"sex"` + Status uint `p:"status"` + IsAdmin int `p:"isAdmin"` // 是否后台管理员 1 是 0 否 +} + +// UserAddReq 添加用户参数 +type UserAddReq struct { + g.Meta `path:"/user/add" tags:"用户管理" method:"post" summary:"添加用户"` + *SetUserReq + UserName string `p:"userName" v:"required#用户账号不能为空"` + Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"` + UserSalt string +} + +type UserAddRes struct { +} + +// UserEditReq 修改用户参数 +type UserEditReq struct { + g.Meta `path:"/user/edit" tags:"用户管理" method:"put" summary:"修改用户"` + *SetUserReq + UserId int64 `p:"userId" v:"required#用户id不能为空"` +} + +type UserEditRes struct { +} + +type UserGetEditReq struct { + g.Meta `path:"/user/getEdit" tags:"用户管理" method:"get" summary:"获取用户信息"` + Id uint64 `p:"id"` +} + +type UserGetEditRes struct { + g.Meta `mime:"application/json"` + User *entity.SysUser `json:"user"` + CheckedRoleIds []uint `json:"checkedRoleIds"` + CheckedPosts []int64 `json:"checkedPosts"` +} + +// UserResetPwdReq 重置用户密码状态参数 +type UserResetPwdReq struct { + g.Meta `path:"/user/resetPwd" tags:"用户管理" method:"put" summary:"重置用户密码"` + Id uint64 `p:"userId" v:"required#用户id不能为空"` + Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"` +} + +type UserResetPwdRes struct { +} + +// UserStatusReq 设置用户状态参数 +type UserStatusReq struct { + g.Meta `path:"/user/setStatus" tags:"用户管理" method:"put" summary:"设置用户状态"` + Id uint64 `p:"userId" v:"required#用户id不能为空"` + UserStatus uint `p:"status" v:"required#用户状态不能为空"` +} + +type UserStatusRes struct { +} + +type UserDeleteReq struct { + g.Meta `path:"/user/delete" tags:"用户管理" method:"delete" summary:"删除用户"` + Ids []int `p:"ids"` +} + +type UserDeleteRes struct { +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c33dea8 --- /dev/null +++ b/go.mod @@ -0,0 +1,54 @@ +module tyj_admin + +go 1.19 + +require ( + github.com/casbin/casbin/v2 v2.57.0 + github.com/gogf/gf/contrib/drivers/mysql/v2 v2.2.4 + github.com/gogf/gf/v2 v2.2.4 + github.com/mojocn/base64Captcha v1.3.5 + github.com/mssola/user_agent v0.5.3 + github.com/shirou/gopsutil v2.21.11+incompatible + github.com/tencentyun/cos-go-sdk-v5 v0.7.40 + github.com/tiger1103/gfast-cache v0.1.1 + github.com/tiger1103/gfast-token v1.0.1 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/BurntSushi/toml v1.1.0 // indirect + github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/clbanning/mxj v1.8.4 // indirect + github.com/clbanning/mxj/v2 v2.5.5 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/golang-jwt/jwt/v4 v4.4.2 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/google/go-querystring v1.0.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/grokify/html-strip-tags-go v0.0.1 // indirect + github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-colorable v0.1.9 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mozillazg/go-httpheader v0.2.1 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.opentelemetry.io/otel v1.7.0 // indirect + go.opentelemetry.io/otel/sdk v1.7.0 // indirect + go.opentelemetry.io/otel/trace v1.7.0 // indirect + golang.org/x/image v0.0.0-20190501045829-6d32002ffd75 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/sys v0.2.0 // indirect + golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..678a394 --- /dev/null +++ b/go.sum @@ -0,0 +1,230 @@ +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= +github.com/casbin/casbin/v2 v2.57.0 h1:J7PTgUe13Ag5WzwZe2l/hpj0/hRKuQlqyO8+1+FAWug= +github.com/casbin/casbin/v2 v2.57.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= +github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= +github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E= +github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogf/gf/contrib/drivers/mysql/v2 v2.2.4 h1:dUT1BbQ6RRiEDiBLj57jBx0y/WkD9KiDbmcCp9vE0w8= +github.com/gogf/gf/contrib/drivers/mysql/v2 v2.2.4/go.mod h1:z+/0qiOwMroAnj5ESuobTv0l5P83rf+XR3r6Fj8WJyk= +github.com/gogf/gf/v2 v2.0.0/go.mod h1:apktt6TleWtCIwpz63vBqUnw8MX8gWKoZyxgDpXFtgM= +github.com/gogf/gf/v2 v2.2.4 h1:Y2c0F4dDDYlQswHPtoGJ0l9kvQjE0a9jmM02qCAZoqo= +github.com/gogf/gf/v2 v2.2.4/go.mod h1:thvkyb43RWUu/m05sRm4CbH9r7t7/FrW2M56L9Ystwk= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0= +github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= +github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= +github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= +github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= +github.com/mssola/user_agent v0.5.3 h1:lBRPML9mdFuIZgI2cmlQ+atbpJdLdeVl2IDodjBR578= +github.com/mssola/user_agent v0.5.3/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shirou/gopsutil v2.21.11+incompatible h1:lOGOyCG67a5dv2hq5Z1BLDUqqKp3HkbjPcz5j6XMS0U= +github.com/shirou/gopsutil v2.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4= +github.com/tencentyun/cos-go-sdk-v5 v0.7.40 h1:W6vDGKCHe4wBACI1d2UgE6+50sJFhRWU4O8IB2ozzxM= +github.com/tencentyun/cos-go-sdk-v5 v0.7.40/go.mod h1:4dCEtLHGh8QPxHEkgq+nFaky7yZxQuYwgSJM87icDaw= +github.com/tiger1103/gfast-cache v0.1.1 h1:qwhw0VUyr539lLmiJCNCoU2dDdHZxozHMuXlvaTPm5Q= +github.com/tiger1103/gfast-cache v0.1.1/go.mod h1:jAmIERI//MmLpUcOI3+7axmSir+t/ufpVc2N3Ryw6VE= +github.com/tiger1103/gfast-token v1.0.1 h1:507HTgEmq+dZ+TnFndy+hC+Ezj/jTQR74qhM85Szw/E= +github.com/tiger1103/gfast-token v1.0.1/go.mod h1:TE1qxSWuEbFeBme5hM0x0EIoBNoxGi3J4yUAyKotRSA= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg= +go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM= +go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= +go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= +go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs= +go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/image v0.0.0-20190501045829-6d32002ffd75 h1:TbGuee8sSq15Iguxu4deQ7+Bqq/d2rsQejGcEtADAMQ= +golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 h1:GLw7MR8AfAG2GmGcmVgObFOHXYypgGjnGno25RDwn3Y= +golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go new file mode 100644 index 0000000..50e270e --- /dev/null +++ b/internal/cmd/cmd.go @@ -0,0 +1,44 @@ +package cmd + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/net/goai" + "github.com/gogf/gf/v2/os/gcmd" + "tyj_admin/internal/consts" + "tyj_admin/internal/router" +) + +var ( + Main = gcmd.Command{ + Name: "main", + Usage: "main", + Brief: "start http server", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + s := g.Server() + s.Group("/", func(group *ghttp.RouterGroup) { + router.BindController(group) + }) + enhanceOpenAPIDoc(s) + s.Run() + return nil + }, + } +) + +func enhanceOpenAPIDoc(s *ghttp.Server) { + openapi := s.GetOpenApi() + openapi.Config.CommonResponse = ghttp.DefaultHandlerResponse{} + openapi.Config.CommonResponseDataField = `Data` + + // API description. + openapi.Info = goai.Info{ + Title: consts.OpenAPITitle, + Description: consts.OpenAPIDescription, + Contact: &goai.Contact{ + Name: consts.OpenAPIContactName, + URL: consts.OpenAPIContactUrl, + }, + } +} diff --git a/internal/consts/cache.go b/internal/consts/cache.go new file mode 100644 index 0000000..ff71504 --- /dev/null +++ b/internal/consts/cache.go @@ -0,0 +1,42 @@ +/* +* @desc:缓存键 +* +* +* @Date: 2022/3/9 12:06 + */ + +package consts + +const ( + // CacheSysAuthMenu 缓存菜单key + CacheSysAuthMenu = "sysAuthMenu" + // CacheSysDept 缓存部门key + CacheSysDept = "sysDept" + + // CacheSysRole 角色缓存key + CacheSysRole = "sysRole" + // CacheSysWebSet 站点配置缓存key + CacheSysWebSet = "sysWebSet" + // CacheSysCmsMenu cms缓存key + CacheSysCmsMenu = "sysCmsMenu" + + // CacheSysAuthTag 权限缓存TAG标签 + CacheSysAuthTag = "sysAuthTag" + // CacheSysModelTag 模型缓存标签 + CacheSysModelTag = "sysModelTag" + // CacheSysCmsTag cms缓存标签 + CacheSysCmsTag = "sysCmsTag" +) + +const ( + CacheModelMem = "memory" + CacheModelRedis = "redis" + + // CacheSysDict 字典缓存菜单KEY + CacheSysDict = "sysDict" + + // CacheSysDictTag 字典缓存标签 + CacheSysDictTag = "sysDictTag" + // CacheSysConfigTag 系统参数配置 + CacheSysConfigTag = "sysConfigTag" +) diff --git a/internal/consts/consts.go b/internal/consts/consts.go new file mode 100644 index 0000000..c0c0da5 --- /dev/null +++ b/internal/consts/consts.go @@ -0,0 +1,5 @@ +package consts + +const ( + PageSize = 10 //分页长度 +) diff --git a/internal/consts/consts_openapi.go b/internal/consts/consts_openapi.go new file mode 100644 index 0000000..0b1663b --- /dev/null +++ b/internal/consts/consts_openapi.go @@ -0,0 +1,8 @@ +package consts + +const ( + OpenAPITitle = `GFast-v3` + OpenAPIDescription = `基于 GoFrame2.0的后台管理系统。 Enjoy 💖 ` + OpenAPIContactName = "GFast" + OpenAPIContactUrl = "http://www.g-fast.cn" +) diff --git a/internal/consts/context.go b/internal/consts/context.go new file mode 100644 index 0000000..3a48d0b --- /dev/null +++ b/internal/consts/context.go @@ -0,0 +1,13 @@ +/* +* @desc:context 相关常量 +* +* +* @Date: 2022/3/16 14:52 + */ + +package consts + +const ( + // CtxKey 上下文变量存储键名,前后端系统共享 + CtxKey = "GFastContext" +) diff --git a/internal/consts/upload.go b/internal/consts/upload.go new file mode 100644 index 0000000..af4f580 --- /dev/null +++ b/internal/consts/upload.go @@ -0,0 +1,19 @@ +package consts + +const ( + UploadPath = "upload_file" + ImgTypeKey = "sys.uploadFile.imageType" + ImgSizeKey = "sys.uploadFile.imageSize" + FileTypeKey = "sys.uploadFile.fileType" + FileSizeKey = "sys.uploadFile.fileSize" + CheckFileTypeImg = "img" // 文件类型(图片) + CheckFileTypeFile = "file" // 文件类型(任意) +) + +const ( + SourceLocal = iota // 上传到本地 + SourceTencent // 上传至腾讯云 + SourceAli // 上传到阿里云 + SourceQiniu // 上传到七牛云 + //................... +) diff --git a/internal/consts/version.go b/internal/consts/version.go new file mode 100644 index 0000000..8c24e97 --- /dev/null +++ b/internal/consts/version.go @@ -0,0 +1,12 @@ +/* +* @desc:版本号 +* +* +* @Date: 2022/3/11 11:24 + */ + +package consts + +const ( + Version = "3.0.0" +) diff --git a/internal/controller/base.go b/internal/controller/base.go new file mode 100644 index 0000000..05da051 --- /dev/null +++ b/internal/controller/base.go @@ -0,0 +1,19 @@ +/* +* @desc:system base controller +* +* +* @Date: 2022/3/4 18:12 + */ + +package controller + +import ( + "github.com/gogf/gf/v2/net/ghttp" +) + +type BaseController struct { +} + +// Init 自动执行的初始化方法 +func (c *BaseController) Init(r *ghttp.Request) { +} diff --git a/internal/controller/captcha.go b/internal/controller/captcha.go new file mode 100644 index 0000000..0e1e4e6 --- /dev/null +++ b/internal/controller/captcha.go @@ -0,0 +1,32 @@ +/* +* @desc:验证码获取 +* +* +* @Date: 2022/3/2 17:45 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/common" + "tyj_admin/internal/service" +) + +var Captcha = captchaController{} + +type captchaController struct { +} + +// Get 获取验证码 +func (c *captchaController) Get(ctx context.Context, req *common.CaptchaReq) (res *common.CaptchaRes, err error) { + var ( + idKeyC, base64stringC string + ) + idKeyC, base64stringC, err = service.Captcha().GetVerifyImgString(ctx) + res = &common.CaptchaRes{ + Key: idKeyC, + Img: base64stringC, + } + return +} diff --git a/internal/controller/demo.go b/internal/controller/demo.go new file mode 100644 index 0000000..4e7a8c2 --- /dev/null +++ b/internal/controller/demo.go @@ -0,0 +1,24 @@ +/* +* @desc:demo +* +* +* @Date: 2022/3/2 15:24 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/demo" +) + +var Demo = cDemo{} + +type cDemo struct { +} + +func (c *cDemo) Demo(ctx context.Context, req *demo.DmReq) (res *demo.DmRes, err error) { + res = &demo.DmRes{Name: "赵四"} + panic("demo wrong") + return +} diff --git a/internal/controller/sys_auth_rule.go b/internal/controller/sys_auth_rule.go new file mode 100644 index 0000000..008503a --- /dev/null +++ b/internal/controller/sys_auth_rule.go @@ -0,0 +1,79 @@ +/* +* @desc:菜单 +* +* +* @Date: 2022/3/16 10:36 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/model" + "tyj_admin/internal/service" +) + +var Menu = menuController{} + +type menuController struct { + BaseController +} + +func (c *menuController) List(ctx context.Context, req *system.RuleSearchReq) (res *system.RuleListRes, err error) { + var list []*model.SysAuthRuleInfoRes + res = &system.RuleListRes{ + Rules: make([]*model.SysAuthRuleTreeRes, 0), + } + list, err = service.Rule().GetMenuListSearch(ctx, req) + if req.Title != "" || req.Component != "" { + for _, menu := range list { + res.Rules = append(res.Rules, &model.SysAuthRuleTreeRes{ + SysAuthRuleInfoRes: menu, + }) + } + } else { + res.Rules = service.Rule().GetMenuListTree(0, list) + } + return +} + +func (c *menuController) Add(ctx context.Context, req *system.RuleAddReq) (res *system.RuleAddRes, err error) { + err = service.Rule().Add(ctx, req) + return +} + +// GetAddParams 获取菜单添加及编辑相关参数 +func (c *menuController) GetAddParams(ctx context.Context, req *system.RuleGetParamsReq) (res *system.RuleGetParamsRes, err error) { + // 获取角色列表 + res = new(system.RuleGetParamsRes) + res.Roles, err = service.Role().GetRoleList(ctx) + if err != nil { + return + } + res.Menus, err = service.Rule().GetIsMenuList(ctx) + return +} + +// Get 获取菜单信息 +func (c *menuController) Get(ctx context.Context, req *system.RuleInfoReq) (res *system.RuleInfoRes, err error) { + res = new(system.RuleInfoRes) + res.Rule, err = service.Rule().Get(ctx, req.Id) + if err != nil { + return + } + res.RoleIds, err = service.Rule().GetMenuRoles(ctx, req.Id) + return +} + +// Update 菜单修改 +func (c *menuController) Update(ctx context.Context, req *system.RuleUpdateReq) (res *system.RuleUpdateRes, err error) { + err = service.Rule().Update(ctx, req) + return +} + +// Delete 删除菜单 +func (c *menuController) Delete(ctx context.Context, req *system.RuleDeleteReq) (res *system.RuleDeleteRes, err error) { + err = service.Rule().DeleteMenuByIds(ctx, req.Ids) + return +} diff --git a/internal/controller/sys_config.go b/internal/controller/sys_config.go new file mode 100644 index 0000000..ed3de7d --- /dev/null +++ b/internal/controller/sys_config.go @@ -0,0 +1,50 @@ +/* +* @desc:系统参数配置 +* +* +* @Date: 2022/4/18 21:17 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/service" +) + +var Config = configController{} + +type configController struct { + BaseController +} + +// List 系统参数列表 +func (c *configController) List(ctx context.Context, req *system.ConfigSearchReq) (res *system.ConfigSearchRes, err error) { + res, err = service.Config().List(ctx, req) + return +} + +// Add 添加系统参数 +func (c *configController) Add(ctx context.Context, req *system.ConfigAddReq) (res *system.ConfigAddRes, err error) { + err = service.Config().Add(ctx, req, service.Context().GetUserId(ctx)) + return +} + +// Get 获取系统参数 +func (c *configController) Get(ctx context.Context, req *system.ConfigGetReq) (res *system.ConfigGetRes, err error) { + res, err = service.Config().Get(ctx, req.Id) + return +} + +// Edit 修改系统参数 +func (c *configController) Edit(ctx context.Context, req *system.ConfigEditReq) (res *system.ConfigEditRes, err error) { + err = service.Config().Edit(ctx, req, service.Context().GetUserId(ctx)) + return +} + +// Delete 删除系统参数 +func (c *configController) Delete(ctx context.Context, req *system.ConfigDeleteReq) (res *system.ConfigDeleteRes, err error) { + err = service.Config().Delete(ctx, req.Ids) + return +} diff --git a/internal/controller/sys_dept.go b/internal/controller/sys_dept.go new file mode 100644 index 0000000..82bf2d8 --- /dev/null +++ b/internal/controller/sys_dept.go @@ -0,0 +1,60 @@ +/* +* @desc:部门管理 +* +* +* @Date: 2022/4/6 15:15 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/model/entity" + "tyj_admin/internal/service" +) + +var Dept = sysDeptController{} + +type sysDeptController struct { + BaseController +} + +// List 部门列表 +func (c *sysDeptController) List(ctx context.Context, req *system.DeptSearchReq) (res *system.DeptSearchRes, err error) { + res = new(system.DeptSearchRes) + res.DeptList, err = service.Dept().GetList(ctx, req) + return +} + +// Add 添加部门 +func (c *sysDeptController) Add(ctx context.Context, req *system.DeptAddReq) (res *system.DeptAddRes, err error) { + err = service.Dept().Add(ctx, req) + return +} + +// Edit 修改部门 +func (c *sysDeptController) Edit(ctx context.Context, req *system.DeptEditReq) (res *system.DeptEditRes, err error) { + err = service.Dept().Edit(ctx, req) + return +} + +// Delete 删除部门 +func (c *sysDeptController) Delete(ctx context.Context, req *system.DeptDeleteReq) (res *system.DeptDeleteRes, err error) { + err = service.Dept().Delete(ctx, req.Id) + return +} + +// TreeSelect 获取部门数据结构数据 +func (c *sysDeptController) TreeSelect(ctx context.Context, req *system.DeptTreeSelectReq) (res *system.DeptTreeSelectRes, err error) { + var deptList []*entity.SysDept + deptList, err = service.Dept().GetList(ctx, &system.DeptSearchReq{ + Status: "1", //正常状态数据 + }) + if err != nil { + return + } + res = new(system.DeptTreeSelectRes) + res.Deps = service.Dept().GetListTree(0, deptList) + return +} diff --git a/internal/controller/sys_dict_data.go b/internal/controller/sys_dict_data.go new file mode 100644 index 0000000..70aa872 --- /dev/null +++ b/internal/controller/sys_dict_data.go @@ -0,0 +1,54 @@ +/* +* @desc:字典数据管理 +* +* +* @Date: 2022/3/18 11:57 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/service" +) + +var DictData = dictDataController{} + +type dictDataController struct { +} + +// GetDictData 获取字典数据 +func (c *dictDataController) GetDictData(ctx context.Context, req *system.GetDictReq) (res *system.GetDictRes, err error) { + res, err = service.DictData().GetDictWithDataByType(ctx, req) + return +} + +// List 获取字典数据列表 +func (c *dictDataController) List(ctx context.Context, req *system.DictDataSearchReq) (res *system.DictDataSearchRes, err error) { + res, err = service.DictData().List(ctx, req) + return +} + +// Add 添加字典数据 +func (c *dictDataController) Add(ctx context.Context, req *system.DictDataAddReq) (res *system.DictDataAddRes, err error) { + err = service.DictData().Add(ctx, req, service.Context().GetUserId(ctx)) + return +} + +// Get 获取对应的字典数据 +func (c *dictDataController) Get(ctx context.Context, req *system.DictDataGetReq) (res *system.DictDataGetRes, err error) { + res, err = service.DictData().Get(ctx, req.DictCode) + return +} + +// Edit 修改字典数据 +func (c *dictDataController) Edit(ctx context.Context, req *system.DictDataEditReq) (res *system.DictDataEditRes, err error) { + err = service.DictData().Edit(ctx, req, service.Context().GetUserId(ctx)) + return +} + +func (c *dictDataController) Delete(ctx context.Context, req *system.DictDataDeleteReq) (res *system.DictDataDeleteRes, err error) { + err = service.DictData().Delete(ctx, req.Ids) + return +} diff --git a/internal/controller/sys_dict_type.go b/internal/controller/sys_dict_type.go new file mode 100644 index 0000000..ba57929 --- /dev/null +++ b/internal/controller/sys_dict_type.go @@ -0,0 +1,49 @@ +/* +* @desc:字典类型 +* +* +* @Date: 2022/3/18 11:57 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/service" +) + +var DictType = &SysDictTypeController{} + +type SysDictTypeController struct { +} + +// List 字典类型列表 +func (c *SysDictTypeController) List(ctx context.Context, req *system.DictTypeSearchReq) (res *system.DictTypeSearchRes, err error) { + res, err = service.DictType().List(ctx, req) + return +} + +// Add 添加字典类型 +func (c *SysDictTypeController) Add(ctx context.Context, req *system.DictTypeAddReq) (res *system.DictTypeAddRes, err error) { + err = service.DictType().Add(ctx, req, service.Context().GetUserId(ctx)) + return +} + +// Get 获取字典类型 +func (c *SysDictTypeController) Get(ctx context.Context, req *system.DictTypeGetReq) (res *system.DictTypeGetRes, err error) { + res = new(system.DictTypeGetRes) + res.DictType, err = service.DictType().Get(ctx, req) + return +} + +// Edit 修改字典数据 +func (c *SysDictTypeController) Edit(ctx context.Context, req *system.DictTypeEditReq) (res *system.DictTypeEditRes, err error) { + err = service.DictType().Edit(ctx, req, service.Context().GetUserId(ctx)) + return +} + +func (c *SysDictTypeController) Delete(ctx context.Context, req *system.DictTypeDeleteReq) (res *system.DictTypeDeleteRes, err error) { + err = service.DictType().Delete(ctx, req.DictIds) + return +} diff --git a/internal/controller/sys_init.go b/internal/controller/sys_init.go new file mode 100644 index 0000000..70fa474 --- /dev/null +++ b/internal/controller/sys_init.go @@ -0,0 +1,73 @@ +package controller + +import ( + "context" + "github.com/shirou/gopsutil/host" + "runtime" + "tyj_admin/api/v1/system" + "tyj_admin/internal/service" +) + +var DbInit = sysDbInitController{} + +type sysDbInitController struct { + BaseController +} + +// 系统是否已经初始化 +func (c *sysDbInitController) IsInit(ctx context.Context, req *system.DbInitIsInitReq) (res *system.DbInitIsInitRes, err error) { + res = new(system.DbInitIsInitRes) + // autoInit=false则前端将不走自动初始化的流程 + if service.SysInitConfig["autoInit"].Bool() == false { + *res = system.DbInitIsInitRes(true) + return + } + // 判断是否已经生成配置文件 + *res = system.DbInitIsInitRes(service.SysInit().IsCreateConfigFile()) + return +} + +// 获取环境检测信息 +func (c *sysDbInitController) GetEnvInfo(ctx context.Context, req *system.DbInitGetEnvInfoReq) (res *system.DbInitGetEnvInfoRes, err error) { + sysInfo, err := host.Info() + if err != nil { + return + } + res = new(system.DbInitGetEnvInfoRes) + *res = system.DbInitGetEnvInfoRes{ + "sysOsName": sysInfo.OS, + "goVersion": runtime.Version(), + } + return +} + +// 创建配置文件及数据库等 +func (c *sysDbInitController) CreateDb(ctx context.Context, req *system.DbInitCreateDbReq) (res *system.DbInitCreateDbRes, err error) { + // 生成数据库 + err = service.SysInit().CreateDataBaseByName(ctx, req) + if err != nil { + return + } + + // 生成配置文件 + err = service.SysInit().CreateConfigFile(ctx, req) + if err != nil { + return + } + + // 加载配置文件 + err = service.SysInit().LoadConfigFile() + if err != nil { + return + } + + // 生成数据库表机构及数据 + err = service.SysInit().CreateDataBase(ctx, req.DbName) + if err != nil { + return + } + + res = new(system.DbInitCreateDbRes) + *res = true + return +} diff --git a/internal/controller/sys_login.go b/internal/controller/sys_login.go new file mode 100644 index 0000000..91d5771 --- /dev/null +++ b/internal/controller/sys_login.go @@ -0,0 +1,101 @@ +/* +* @desc:登录 +* +* +* @Date: 2022/4/27 21:52 + */ + +package controller + +import ( + "context" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" + "github.com/gogf/gf/v2/util/gmode" + "tyj_admin/api/v1/system" + "tyj_admin/internal/model" + "tyj_admin/internal/service" + "tyj_admin/library/libUtils" +) + +var ( + Login = loginController{} +) + +type loginController struct { + BaseController +} + +func (c *loginController) Login(ctx context.Context, req *system.UserLoginReq) (res *system.UserLoginRes, err error) { + var ( + user *model.LoginUserRes + token string + permissions []string + menuList []*model.UserMenus + ) + //判断验证码是否正确 + debug := gmode.IsDevelop() + if !debug { + if !service.Captcha().VerifyString(req.VerifyKey, req.VerifyCode) { + err = gerror.New("验证码输入错误") + return + } + } + ip := libUtils.GetClientIp(ctx) + userAgent := libUtils.GetUserAgent(ctx) + user, err = service.User().GetAdminUserByUsernamePassword(ctx, req) + if err != nil { + // 保存登录失败的日志信息 + service.SysLoginLog().Invoke(ctx, &model.LoginLogParams{ + Status: 0, + Username: req.Username, + Ip: ip, + UserAgent: userAgent, + Msg: err.Error(), + Module: "系统后台", + }) + return + } + err = service.User().UpdateLoginInfo(ctx, user.Id, ip) + if err != nil { + return + } + // 报存登录成功的日志信息 + service.SysLoginLog().Invoke(ctx, &model.LoginLogParams{ + Status: 1, + Username: req.Username, + Ip: ip, + UserAgent: userAgent, + Msg: "登录成功", + Module: "系统后台", + }) + key := gconv.String(user.Id) + "-" + gmd5.MustEncryptString(user.UserName) + gmd5.MustEncryptString(user.UserPassword) + if g.Cfg().MustGet(ctx, "gfToken.multiLogin").Bool() { + key = gconv.String(user.Id) + "-" + gmd5.MustEncryptString(user.UserName) + gmd5.MustEncryptString(user.UserPassword+ip+userAgent) + } + user.UserPassword = "" + token, err = service.SysGfToken().GenerateToken(ctx, key, user) + if err != nil { + return + } + //获取用户菜单数据 + menuList, permissions, err = service.User().GetAdminRules(ctx, user.Id) + if err != nil { + return + } + res = &system.UserLoginRes{ + UserInfo: user, + Token: token, + MenuList: menuList, + Permissions: permissions, + } + return +} + +// LoginOut 退出登录 +func (c *loginController) LoginOut(ctx context.Context, req *system.UserLoginOutReq) (res *system.UserLoginOutRes, err error) { + err = service.SysGfToken().RemoveToken(ctx, service.SysGfToken().GetRequestToken(g.RequestFromCtx(ctx))) + return +} diff --git a/internal/controller/sys_login_log.go b/internal/controller/sys_login_log.go new file mode 100644 index 0000000..03e5307 --- /dev/null +++ b/internal/controller/sys_login_log.go @@ -0,0 +1,35 @@ +/* +* @desc:登录日志管理 +* +* +* @Date: 2022/4/24 22:14 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/service" +) + +var LoginLog = loginLogController{} + +type loginLogController struct { + BaseController +} + +func (c *loginLogController) List(ctx context.Context, req *system.LoginLogSearchReq) (res *system.LoginLogSearchRes, err error) { + res, err = service.SysLoginLog().List(ctx, req) + return +} + +func (c *loginLogController) Delete(ctx context.Context, req *system.LoginLogDelReq) (res *system.LoginLogDelRes, err error) { + err = service.SysLoginLog().DeleteLoginLogByIds(ctx, req.Ids) + return +} + +func (c *loginLogController) Clear(ctx context.Context, req *system.LoginLogClearReq) (res *system.LoginLogClearRes, err error) { + err = service.SysLoginLog().ClearLoginLog(ctx) + return +} diff --git a/internal/controller/sys_monitor.go b/internal/controller/sys_monitor.go new file mode 100644 index 0000000..5ab4a86 --- /dev/null +++ b/internal/controller/sys_monitor.go @@ -0,0 +1,142 @@ +package controller + +import ( + "context" + "fmt" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/util/gconv" + "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/disk" + "github.com/shirou/gopsutil/host" + "github.com/shirou/gopsutil/load" + "github.com/shirou/gopsutil/mem" + "os" + "runtime" + "strconv" + "time" + "tyj_admin/api/v1/system" + "tyj_admin/library/libUtils" +) + +var Monitor = sysMonitorController{ + startTime: gtime.Now(), +} + +type sysMonitorController struct { + BaseController + startTime *gtime.Time +} + +func (c *sysMonitorController) List(ctx context.Context, req *system.MonitorSearchReq) (res *system.MonitorSearchRes, err error) { + cpuNum := runtime.NumCPU() //核心数 + var cpuUsed float64 = 0 //用户使用率 + var cpuAvg5 float64 = 0 //CPU负载5 + var cpuAvg15 float64 = 0 //当前空闲率 + + cpuInfo, err := cpu.Percent(time.Duration(time.Second), false) + if err == nil { + cpuUsed, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", cpuInfo[0]), 64) + } + + loadInfo, err := load.Avg() + if err == nil { + cpuAvg5, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", loadInfo.Load5), 64) + cpuAvg15, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", loadInfo.Load5), 64) + } + + var memTotal uint64 = 0 //总内存 + var memUsed uint64 = 0 //总内存 := 0 //已用内存 + var memFree uint64 = 0 //剩余内存 + var memUsage float64 = 0 //使用率 + + v, err := mem.VirtualMemory() + if err == nil { + memTotal = v.Total + memUsed = v.Used + memFree = memTotal - memUsed + memUsage, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", v.UsedPercent), 64) + } + + var goTotal uint64 = 0 //go分配的总内存数 + var goUsed uint64 = 0 //go使用的内存数 + var goFree uint64 = 0 //go剩余的内存数 + var goUsage float64 = 0 //使用率 + + var gomem runtime.MemStats + runtime.ReadMemStats(&gomem) + goUsed = gomem.Sys + goUsage = gconv.Float64(fmt.Sprintf("%.2f", gconv.Float64(goUsed)/gconv.Float64(memTotal)*100)) + sysComputerIp := "" //服务器IP + + ip, err := libUtils.GetLocalIP() + if err == nil { + sysComputerIp = ip + } + + sysComputerName := "" //服务器名称 + sysOsName := "" //操作系统 + sysOsArch := "" //系统架构 + + sysInfo, err := host.Info() + + if err == nil { + sysComputerName = sysInfo.Hostname + sysOsName = sysInfo.OS + sysOsArch = sysInfo.KernelArch + } + + goName := "GoLang" //语言环境 + goVersion := runtime.Version() //版本 + gtime.Date() + goStartTime := c.startTime //启动时间 + + goRunTime := gtime.Now().Timestamp() - c.startTime.Timestamp() //运行时长(秒) + goHome := runtime.GOROOT() //安装路径 + goUserDir := "" //项目路径 + + curDir, err := os.Getwd() + + if err == nil { + goUserDir = curDir + } + + //服务器磁盘信息 + diskList := make([]disk.UsageStat, 0) + diskInfo, err := disk.Partitions(true) //所有分区 + if err == nil { + for _, p := range diskInfo { + diskDetail, err := disk.Usage(p.Mountpoint) + if err == nil { + diskDetail.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", diskDetail.UsedPercent), 64) + diskList = append(diskList, *diskDetail) + } + } + } + res = new(system.MonitorSearchRes) + res = &system.MonitorSearchRes{ + "cpuNum": cpuNum, + "cpuUsed": cpuUsed, + "cpuAvg5": gconv.String(cpuAvg5), + "cpuAvg15": gconv.String(cpuAvg15), + "memTotal": memTotal, + "goTotal": goTotal, + "memUsed": memUsed, + "goUsed": goUsed, + "memFree": memFree, + "goFree": goFree, + "memUsage": memUsage, + "goUsage": goUsage, + "sysComputerName": sysComputerName, + "sysOsName": sysOsName, + "sysComputerIp": sysComputerIp, + "sysOsArch": sysOsArch, + "goName": goName, + "goVersion": goVersion, + "goStartTime": goStartTime, + "goRunTime": goRunTime, + "goHome": goHome, + "goUserDir": goUserDir, + "diskList": diskList, + } + return +} diff --git a/internal/controller/sys_post.go b/internal/controller/sys_post.go new file mode 100644 index 0000000..ac05380 --- /dev/null +++ b/internal/controller/sys_post.go @@ -0,0 +1,44 @@ +/* +* @desc:岗位管理 +* +* +* @Date: 2022/4/7 23:12 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/service" +) + +var Post = postController{} + +type postController struct { + BaseController +} + +// List 岗位列表 +func (c *postController) List(ctx context.Context, req *system.PostSearchReq) (res *system.PostSearchRes, err error) { + res, err = service.Post().List(ctx, req) + return +} + +// Add 添加岗位 +func (c *postController) Add(ctx context.Context, req *system.PostAddReq) (res *system.PostAddRes, err error) { + err = service.Post().Add(ctx, req) + return +} + +// Edit 修改岗位 +func (c *postController) Edit(ctx context.Context, req *system.PostEditReq) (res *system.PostEditRes, err error) { + err = service.Post().Edit(ctx, req) + return +} + +// Delete 删除岗位 +func (c *postController) Delete(ctx context.Context, req *system.PostDeleteReq) (res *system.PostDeleteRes, err error) { + err = service.Post().Delete(ctx, req.Ids) + return +} diff --git a/internal/controller/sys_role.go b/internal/controller/sys_role.go new file mode 100644 index 0000000..f432b0f --- /dev/null +++ b/internal/controller/sys_role.go @@ -0,0 +1,62 @@ +/* +* @desc:角色管理 +* +* +* @Date: 2022/3/30 9:08 + */ + +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/service" +) + +var Role = roleController{} + +type roleController struct { + BaseController +} + +// List 角色列表 +func (c *roleController) List(ctx context.Context, req *system.RoleListReq) (res *system.RoleListRes, err error) { + res, err = service.Role().GetRoleListSearch(ctx, req) + return +} + +// GetParams 获取角色表单参数 +func (c *roleController) GetParams(ctx context.Context, req *system.RoleGetParamsReq) (res *system.RoleGetParamsRes, err error) { + res = new(system.RoleGetParamsRes) + res.Menu, err = service.Rule().GetMenuList(ctx) + return +} + +// Add 添加角色信息 +func (c *roleController) Add(ctx context.Context, req *system.RoleAddReq) (res *system.RoleAddRes, err error) { + err = service.Role().AddRole(ctx, req) + return +} + +// Get 获取角色信息 +func (c *roleController) Get(ctx context.Context, req *system.RoleGetReq) (res *system.RoleGetRes, err error) { + res = new(system.RoleGetRes) + res.Role, err = service.Role().Get(ctx, req.Id) + if err != nil { + return + } + res.MenuIds, err = service.Role().GetFilteredNamedPolicy(ctx, req.Id) + return +} + +// Edit 修改角色信息 +func (c *roleController) Edit(ctx context.Context, req *system.RoleEditReq) (res *system.RoleEditRes, err error) { + err = service.Role().EditRole(ctx, req) + return +} + +// Delete 删除角色 +func (c *roleController) Delete(ctx context.Context, req *system.RoleDeleteReq) (res *system.RoleDeleteRes, err error) { + err = service.Role().DeleteByIds(ctx, req.Ids) + return +} diff --git a/internal/controller/sys_user.go b/internal/controller/sys_user.go new file mode 100644 index 0000000..21172d8 --- /dev/null +++ b/internal/controller/sys_user.go @@ -0,0 +1,95 @@ +package controller + +import ( + "context" + "tyj_admin/api/v1/system" + "tyj_admin/internal/model" + "tyj_admin/internal/model/entity" + "tyj_admin/internal/service" +) + +var ( + User = userController{} +) + +type userController struct { + BaseController +} + +// GetUserMenus 获取用户菜单及按钮权限 +func (c *userController) GetUserMenus(ctx context.Context, req *system.UserMenusReq) (res *system.UserMenusRes, err error) { + var ( + permissions []string + menuList []*model.UserMenus + ) + userId := service.Context().GetUserId(ctx) + menuList, permissions, err = service.User().GetAdminRules(ctx, userId) + res = &system.UserMenusRes{ + MenuList: menuList, + Permissions: permissions, + } + return +} + +// List 用户列表 +func (c *userController) List(ctx context.Context, req *system.UserSearchReq) (res *system.UserSearchRes, err error) { + var ( + total int + userList []*entity.SysUser + ) + res = new(system.UserSearchRes) + total, userList, err = service.User().List(ctx, req) + if err != nil || total == 0 { + return + } + res.Total = total + res.UserList, err = service.User().GetUsersRoleDept(ctx, userList) + return +} + +// GetParams 获取用户维护相关参数 +func (c *userController) GetParams(ctx context.Context, req *system.UserGetParamsReq) (res *system.UserGetParamsRes, err error) { + res = new(system.UserGetParamsRes) + res.RoleList, err = service.Role().GetRoleList(ctx) + if err != nil { + return + } + res.Posts, err = service.Post().GetUsedPost(ctx) + return +} + +// Add 添加用户 +func (c *userController) Add(ctx context.Context, req *system.UserAddReq) (res *system.UserAddRes, err error) { + err = service.User().Add(ctx, req) + return +} + +// GetEditUser 获取修改用户信息 +func (c *userController) GetEditUser(ctx context.Context, req *system.UserGetEditReq) (res *system.UserGetEditRes, err error) { + res, err = service.User().GetEditUser(ctx, req.Id) + return +} + +// Edit 修改用户 +func (c *userController) Edit(ctx context.Context, req *system.UserEditReq) (res *system.UserEditRes, err error) { + err = service.User().Edit(ctx, req) + return +} + +// ResetPwd 重置密码 +func (c *userController) ResetPwd(ctx context.Context, req *system.UserResetPwdReq) (res *system.UserResetPwdRes, err error) { + err = service.User().ResetUserPwd(ctx, req) + return +} + +// SetStatus 修改用户状态 +func (c *userController) SetStatus(ctx context.Context, req *system.UserStatusReq) (res *system.UserStatusRes, err error) { + err = service.User().ChangeUserStatus(ctx, req) + return +} + +// Delete 删除用户 +func (c *userController) Delete(ctx context.Context, req *system.UserDeleteReq) (res *system.UserDeleteRes, err error) { + err = service.User().Delete(ctx, req.Ids) + return +} diff --git a/internal/controller/upload.go b/internal/controller/upload.go new file mode 100644 index 0000000..0b10240 --- /dev/null +++ b/internal/controller/upload.go @@ -0,0 +1,87 @@ +package controller + +import ( + "context" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "tyj_admin/api/v1/common" + "tyj_admin/internal/consts" + "tyj_admin/internal/service" +) + +var Upload = new(uploadController) + +type uploadController struct{} + +// 上传单图 +func (c *uploadController) SingleImg(ctx context.Context, req *common.UploadSingleImgReq) (res *common.UploadSingleRes, err error) { + r := g.RequestFromCtx(ctx) + file := r.GetUploadFile("file") + if file == nil { + err = gerror.New("上传文件必须") + return + } + v, _ := g.Cfg().Get(ctx, "upload.default") + response, err := service.Upload().UploadFile(ctx, file, consts.CheckFileTypeImg, v.Int()) + if err != nil { + return + } + res = &common.UploadSingleRes{ + UploadResponse: response, + } + // 上传第三方 + return +} + +// 上传多图 +func (c *uploadController) MultipleImg(ctx context.Context, req *common.UploadMultipleImgReq) (res *common.UploadMultipleRes, err error) { + r := g.RequestFromCtx(ctx) + files := r.GetUploadFiles("file") + if len(files) == 0 { + err = gerror.New("上传文件必须") + return + } + v, _ := g.Cfg().Get(ctx, "upload.default") + mf, err := service.Upload().UploadFiles(ctx, files, consts.CheckFileTypeImg, v.Int()) + if err != nil { + return + } + res = &mf + return +} + +// 上传单文件 +func (c *uploadController) SingleFile(ctx context.Context, req *common.UploadSingleFileReq) (res *common.UploadSingleRes, err error) { + r := g.RequestFromCtx(ctx) + file := r.GetUploadFile("file") + if file == nil { + err = gerror.New("上传文件必须") + return + } + v, _ := g.Cfg().Get(ctx, "upload.default") + response, err := service.Upload().UploadFile(ctx, file, consts.CheckFileTypeFile, v.Int()) + if err != nil { + return + } + res = &common.UploadSingleRes{ + UploadResponse: response, + } + return +} + +// 上传多文件 +func (c *uploadController) MultipleFile(ctx context.Context, req *common.UploadMultipleFileReq) (res *common.UploadMultipleRes, err error) { + r := g.RequestFromCtx(ctx) + files := r.GetUploadFiles("file") + if len(files) == 0 { + err = gerror.New("上传文件必须") + return + } + v, _ := g.Cfg().Get(ctx, "upload.default") + mf, err := service.Upload().UploadFiles(ctx, files, consts.CheckFileTypeFile, v.Int()) + if err != nil { + return + } + res = &mf + return +} diff --git a/internal/dao/casbin_rule.go b/internal/dao/casbin_rule.go new file mode 100644 index 0000000..22efd73 --- /dev/null +++ b/internal/dao/casbin_rule.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalCasbinRuleDao is internal type for wrapping internal DAO implements. +type internalCasbinRuleDao = *internal.CasbinRuleDao + +// casbinRuleDao is the data access object for table casbin_rule. +// You can define custom methods on it to extend its functionality as you wish. +type casbinRuleDao struct { + internalCasbinRuleDao +} + +var ( + // CasbinRule is globally public accessible object for table casbin_rule operations. + CasbinRule = casbinRuleDao{ + internal.NewCasbinRuleDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/internal/casbin_rule.go b/internal/dao/internal/casbin_rule.go new file mode 100644 index 0000000..1de410f --- /dev/null +++ b/internal/dao/internal/casbin_rule.go @@ -0,0 +1,85 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// CasbinRuleDao is the data access object for table casbin_rule. +type CasbinRuleDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns CasbinRuleColumns // columns contains all the column names of Table for convenient usage. +} + +// CasbinRuleColumns defines and stores column names for table casbin_rule. +type CasbinRuleColumns struct { + Ptype string // + V0 string // + V1 string // + V2 string // + V3 string // + V4 string // + V5 string // +} + +// casbinRuleColumns holds the columns for table casbin_rule. +var casbinRuleColumns = CasbinRuleColumns{ + Ptype: "ptype", + V0: "v0", + V1: "v1", + V2: "v2", + V3: "v3", + V4: "v4", + V5: "v5", +} + +// NewCasbinRuleDao creates and returns a new DAO object for table data access. +func NewCasbinRuleDao() *CasbinRuleDao { + return &CasbinRuleDao{ + group: "default", + table: "casbin_rule", + columns: casbinRuleColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *CasbinRuleDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *CasbinRuleDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *CasbinRuleDao) Columns() CasbinRuleColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *CasbinRuleDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *CasbinRuleDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *CasbinRuleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_auth_rule.go b/internal/dao/internal/sys_auth_rule.go new file mode 100644 index 0000000..ba9c811 --- /dev/null +++ b/internal/dao/internal/sys_auth_rule.go @@ -0,0 +1,115 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysAuthRuleDao is the data access object for table sys_auth_rule. +type SysAuthRuleDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysAuthRuleColumns // columns contains all the column names of Table for convenient usage. +} + +// SysAuthRuleColumns defines and stores column names for table sys_auth_rule. +type SysAuthRuleColumns struct { + Id string // + Pid string // 父ID + Name string // 规则名称 + Title string // 规则名称 + Icon string // 图标 + Condition string // 条件 + Remark string // 备注 + MenuType string // 类型 0目录 1菜单 2按钮 + Weigh string // 权重 + IsHide string // 显示状态 + Path string // 路由地址 + Component string // 组件路径 + IsLink string // 是否外链 1是 0否 + ModuleType string // 所属模块 + ModelId string // 模型ID + IsIframe string // 是否内嵌iframe + IsCached string // 是否缓存 + Redirect string // 路由重定向地址 + IsAffix string // 是否固定 + LinkUrl string // 链接地址 + CreatedAt string // 创建日期 + UpdatedAt string // 修改日期 +} + +// sysAuthRuleColumns holds the columns for table sys_auth_rule. +var sysAuthRuleColumns = SysAuthRuleColumns{ + Id: "id", + Pid: "pid", + Name: "name", + Title: "title", + Icon: "icon", + Condition: "condition", + Remark: "remark", + MenuType: "menu_type", + Weigh: "weigh", + IsHide: "is_hide", + Path: "path", + Component: "component", + IsLink: "is_link", + ModuleType: "module_type", + ModelId: "model_id", + IsIframe: "is_iframe", + IsCached: "is_cached", + Redirect: "redirect", + IsAffix: "is_affix", + LinkUrl: "link_url", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysAuthRuleDao creates and returns a new DAO object for table data access. +func NewSysAuthRuleDao() *SysAuthRuleDao { + return &SysAuthRuleDao{ + group: "default", + table: "sys_auth_rule", + columns: sysAuthRuleColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysAuthRuleDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysAuthRuleDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysAuthRuleDao) Columns() SysAuthRuleColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysAuthRuleDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysAuthRuleDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysAuthRuleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_config.go b/internal/dao/internal/sys_config.go new file mode 100644 index 0000000..4e64e31 --- /dev/null +++ b/internal/dao/internal/sys_config.go @@ -0,0 +1,91 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysConfigDao is the data access object for table sys_config. +type SysConfigDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysConfigColumns // columns contains all the column names of Table for convenient usage. +} + +// SysConfigColumns defines and stores column names for table sys_config. +type SysConfigColumns struct { + ConfigId string // 参数主键 + ConfigName string // 参数名称 + ConfigKey string // 参数键名 + ConfigValue string // 参数键值 + ConfigType string // 系统内置(Y是 N否) + CreateBy string // 创建者 + UpdateBy string // 更新者 + Remark string // 备注 + CreatedAt string // 创建时间 + UpdatedAt string // 修改时间 +} + +// sysConfigColumns holds the columns for table sys_config. +var sysConfigColumns = SysConfigColumns{ + ConfigId: "config_id", + ConfigName: "config_name", + ConfigKey: "config_key", + ConfigValue: "config_value", + ConfigType: "config_type", + CreateBy: "create_by", + UpdateBy: "update_by", + Remark: "remark", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysConfigDao creates and returns a new DAO object for table data access. +func NewSysConfigDao() *SysConfigDao { + return &SysConfigDao{ + group: "default", + table: "sys_config", + columns: sysConfigColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysConfigDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysConfigDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysConfigDao) Columns() SysConfigColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysConfigDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysConfigDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysConfigDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_dept.go b/internal/dao/internal/sys_dept.go new file mode 100644 index 0000000..5d43885 --- /dev/null +++ b/internal/dao/internal/sys_dept.go @@ -0,0 +1,99 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysDeptDao is the data access object for table sys_dept. +type SysDeptDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysDeptColumns // columns contains all the column names of Table for convenient usage. +} + +// SysDeptColumns defines and stores column names for table sys_dept. +type SysDeptColumns struct { + DeptId string // 部门id + ParentId string // 父部门id + Ancestors string // 祖级列表 + DeptName string // 部门名称 + OrderNum string // 显示顺序 + Leader string // 负责人 + Phone string // 联系电话 + Email string // 邮箱 + Status string // 部门状态(0正常 1停用) + CreatedBy string // 创建人 + UpdatedBy string // 修改人 + CreatedAt string // 创建时间 + UpdatedAt string // 修改时间 + DeletedAt string // 删除时间 +} + +// sysDeptColumns holds the columns for table sys_dept. +var sysDeptColumns = SysDeptColumns{ + DeptId: "dept_id", + ParentId: "parent_id", + Ancestors: "ancestors", + DeptName: "dept_name", + OrderNum: "order_num", + Leader: "leader", + Phone: "phone", + Email: "email", + Status: "status", + CreatedBy: "created_by", + UpdatedBy: "updated_by", + CreatedAt: "created_at", + UpdatedAt: "updated_at", + DeletedAt: "deleted_at", +} + +// NewSysDeptDao creates and returns a new DAO object for table data access. +func NewSysDeptDao() *SysDeptDao { + return &SysDeptDao{ + group: "default", + table: "sys_dept", + columns: sysDeptColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysDeptDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysDeptDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysDeptDao) Columns() SysDeptColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysDeptDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysDeptDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_dict_data.go b/internal/dao/internal/sys_dict_data.go new file mode 100644 index 0000000..a853755 --- /dev/null +++ b/internal/dao/internal/sys_dict_data.go @@ -0,0 +1,99 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysDictDataDao is the data access object for table sys_dict_data. +type SysDictDataDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysDictDataColumns // columns contains all the column names of Table for convenient usage. +} + +// SysDictDataColumns defines and stores column names for table sys_dict_data. +type SysDictDataColumns struct { + DictCode string // 字典编码 + DictSort string // 字典排序 + DictLabel string // 字典标签 + DictValue string // 字典键值 + DictType string // 字典类型 + CssClass string // 样式属性(其他样式扩展) + ListClass string // 表格回显样式 + IsDefault string // 是否默认(1是 0否) + Status string // 状态(0正常 1停用) + CreateBy string // 创建者 + UpdateBy string // 更新者 + Remark string // 备注 + CreatedAt string // 创建时间 + UpdatedAt string // 修改时间 +} + +// sysDictDataColumns holds the columns for table sys_dict_data. +var sysDictDataColumns = SysDictDataColumns{ + DictCode: "dict_code", + DictSort: "dict_sort", + DictLabel: "dict_label", + DictValue: "dict_value", + DictType: "dict_type", + CssClass: "css_class", + ListClass: "list_class", + IsDefault: "is_default", + Status: "status", + CreateBy: "create_by", + UpdateBy: "update_by", + Remark: "remark", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysDictDataDao creates and returns a new DAO object for table data access. +func NewSysDictDataDao() *SysDictDataDao { + return &SysDictDataDao{ + group: "default", + table: "sys_dict_data", + columns: sysDictDataColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysDictDataDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysDictDataDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysDictDataDao) Columns() SysDictDataColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysDictDataDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysDictDataDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysDictDataDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_dict_type.go b/internal/dao/internal/sys_dict_type.go new file mode 100644 index 0000000..32a680f --- /dev/null +++ b/internal/dao/internal/sys_dict_type.go @@ -0,0 +1,89 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysDictTypeDao is the data access object for table sys_dict_type. +type SysDictTypeDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysDictTypeColumns // columns contains all the column names of Table for convenient usage. +} + +// SysDictTypeColumns defines and stores column names for table sys_dict_type. +type SysDictTypeColumns struct { + DictId string // 字典主键 + DictName string // 字典名称 + DictType string // 字典类型 + Status string // 状态(0正常 1停用) + CreateBy string // 创建者 + UpdateBy string // 更新者 + Remark string // 备注 + CreatedAt string // 创建日期 + UpdatedAt string // 修改日期 +} + +// sysDictTypeColumns holds the columns for table sys_dict_type. +var sysDictTypeColumns = SysDictTypeColumns{ + DictId: "dict_id", + DictName: "dict_name", + DictType: "dict_type", + Status: "status", + CreateBy: "create_by", + UpdateBy: "update_by", + Remark: "remark", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysDictTypeDao creates and returns a new DAO object for table data access. +func NewSysDictTypeDao() *SysDictTypeDao { + return &SysDictTypeDao{ + group: "default", + table: "sys_dict_type", + columns: sysDictTypeColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysDictTypeDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysDictTypeDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysDictTypeDao) Columns() SysDictTypeColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysDictTypeDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysDictTypeDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysDictTypeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_login_log.go b/internal/dao/internal/sys_login_log.go new file mode 100644 index 0000000..abc22b6 --- /dev/null +++ b/internal/dao/internal/sys_login_log.go @@ -0,0 +1,91 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysLoginLogDao is the data access object for table sys_login_log. +type SysLoginLogDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysLoginLogColumns // columns contains all the column names of Table for convenient usage. +} + +// SysLoginLogColumns defines and stores column names for table sys_login_log. +type SysLoginLogColumns struct { + InfoId string // 访问ID + LoginName string // 登录账号 + Ipaddr string // 登录IP地址 + LoginLocation string // 登录地点 + Browser string // 浏览器类型 + Os string // 操作系统 + Status string // 登录状态(0成功 1失败) + Msg string // 提示消息 + LoginTime string // 登录时间 + Module string // 登录模块 +} + +// sysLoginLogColumns holds the columns for table sys_login_log. +var sysLoginLogColumns = SysLoginLogColumns{ + InfoId: "info_id", + LoginName: "login_name", + Ipaddr: "ipaddr", + LoginLocation: "login_location", + Browser: "browser", + Os: "os", + Status: "status", + Msg: "msg", + LoginTime: "login_time", + Module: "module", +} + +// NewSysLoginLogDao creates and returns a new DAO object for table data access. +func NewSysLoginLogDao() *SysLoginLogDao { + return &SysLoginLogDao{ + group: "default", + table: "sys_login_log", + columns: sysLoginLogColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysLoginLogDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysLoginLogDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysLoginLogDao) Columns() SysLoginLogColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysLoginLogDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysLoginLogDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysLoginLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_oper_log.go b/internal/dao/internal/sys_oper_log.go new file mode 100644 index 0000000..7d790f3 --- /dev/null +++ b/internal/dao/internal/sys_oper_log.go @@ -0,0 +1,103 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysOperLogDao is the data access object for table sys_oper_log. +type SysOperLogDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysOperLogColumns // columns contains all the column names of Table for convenient usage. +} + +// SysOperLogColumns defines and stores column names for table sys_oper_log. +type SysOperLogColumns struct { + OperId string // 日志主键 + Title string // 模块标题 + BusinessType string // 业务类型(0其它 1新增 2修改 3删除) + Method string // 方法名称 + RequestMethod string // 请求方式 + OperatorType string // 操作类别(0其它 1后台用户 2手机端用户) + OperName string // 操作人员 + DeptName string // 部门名称 + OperUrl string // 请求URL + OperIp string // 主机地址 + OperLocation string // 操作地点 + OperParam string // 请求参数 + JsonResult string // 返回参数 + Status string // 操作状态(0正常 1异常) + ErrorMsg string // 错误消息 + OperTime string // 操作时间 +} + +// sysOperLogColumns holds the columns for table sys_oper_log. +var sysOperLogColumns = SysOperLogColumns{ + OperId: "oper_id", + Title: "title", + BusinessType: "business_type", + Method: "method", + RequestMethod: "request_method", + OperatorType: "operator_type", + OperName: "oper_name", + DeptName: "dept_name", + OperUrl: "oper_url", + OperIp: "oper_ip", + OperLocation: "oper_location", + OperParam: "oper_param", + JsonResult: "json_result", + Status: "status", + ErrorMsg: "error_msg", + OperTime: "oper_time", +} + +// NewSysOperLogDao creates and returns a new DAO object for table data access. +func NewSysOperLogDao() *SysOperLogDao { + return &SysOperLogDao{ + group: "default", + table: "sys_oper_log", + columns: sysOperLogColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysOperLogDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysOperLogDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysOperLogDao) Columns() SysOperLogColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysOperLogDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysOperLogDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysOperLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_post.go b/internal/dao/internal/sys_post.go new file mode 100644 index 0000000..c7ec214 --- /dev/null +++ b/internal/dao/internal/sys_post.go @@ -0,0 +1,93 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysPostDao is the data access object for table sys_post. +type SysPostDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysPostColumns // columns contains all the column names of Table for convenient usage. +} + +// SysPostColumns defines and stores column names for table sys_post. +type SysPostColumns struct { + PostId string // 岗位ID + PostCode string // 岗位编码 + PostName string // 岗位名称 + PostSort string // 显示顺序 + Status string // 状态(0正常 1停用) + Remark string // 备注 + CreatedBy string // 创建人 + UpdatedBy string // 修改人 + CreatedAt string // 创建时间 + UpdatedAt string // 修改时间 + DeletedAt string // 删除时间 +} + +// sysPostColumns holds the columns for table sys_post. +var sysPostColumns = SysPostColumns{ + PostId: "post_id", + PostCode: "post_code", + PostName: "post_name", + PostSort: "post_sort", + Status: "status", + Remark: "remark", + CreatedBy: "created_by", + UpdatedBy: "updated_by", + CreatedAt: "created_at", + UpdatedAt: "updated_at", + DeletedAt: "deleted_at", +} + +// NewSysPostDao creates and returns a new DAO object for table data access. +func NewSysPostDao() *SysPostDao { + return &SysPostDao{ + group: "default", + table: "sys_post", + columns: sysPostColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysPostDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysPostDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysPostDao) Columns() SysPostColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysPostDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysPostDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_role.go b/internal/dao/internal/sys_role.go new file mode 100644 index 0000000..e009ff7 --- /dev/null +++ b/internal/dao/internal/sys_role.go @@ -0,0 +1,87 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysRoleDao is the data access object for table sys_role. +type SysRoleDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysRoleColumns // columns contains all the column names of Table for convenient usage. +} + +// SysRoleColumns defines and stores column names for table sys_role. +type SysRoleColumns struct { + Id string // + Status string // 状态;0:禁用;1:正常 + ListOrder string // 排序 + Name string // 角色名称 + Remark string // 备注 + DataScope string // 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限) + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 +} + +// sysRoleColumns holds the columns for table sys_role. +var sysRoleColumns = SysRoleColumns{ + Id: "id", + Status: "status", + ListOrder: "list_order", + Name: "name", + Remark: "remark", + DataScope: "data_scope", + CreatedAt: "created_at", + UpdatedAt: "updated_at", +} + +// NewSysRoleDao creates and returns a new DAO object for table data access. +func NewSysRoleDao() *SysRoleDao { + return &SysRoleDao{ + group: "default", + table: "sys_role", + columns: sysRoleColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysRoleDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysRoleDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysRoleDao) Columns() SysRoleColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysRoleDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysRoleDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_role_dept.go b/internal/dao/internal/sys_role_dept.go new file mode 100644 index 0000000..a2a7e5c --- /dev/null +++ b/internal/dao/internal/sys_role_dept.go @@ -0,0 +1,75 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysRoleDeptDao is the data access object for table sys_role_dept. +type SysRoleDeptDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysRoleDeptColumns // columns contains all the column names of Table for convenient usage. +} + +// SysRoleDeptColumns defines and stores column names for table sys_role_dept. +type SysRoleDeptColumns struct { + RoleId string // 角色ID + DeptId string // 部门ID +} + +// sysRoleDeptColumns holds the columns for table sys_role_dept. +var sysRoleDeptColumns = SysRoleDeptColumns{ + RoleId: "role_id", + DeptId: "dept_id", +} + +// NewSysRoleDeptDao creates and returns a new DAO object for table data access. +func NewSysRoleDeptDao() *SysRoleDeptDao { + return &SysRoleDeptDao{ + group: "default", + table: "sys_role_dept", + columns: sysRoleDeptColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysRoleDeptDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysRoleDeptDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysRoleDeptDao) Columns() SysRoleDeptColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysRoleDeptDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysRoleDeptDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysRoleDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_user.go b/internal/dao/internal/sys_user.go new file mode 100644 index 0000000..e85461c --- /dev/null +++ b/internal/dao/internal/sys_user.go @@ -0,0 +1,113 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysUserDao is the data access object for table sys_user. +type SysUserDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysUserColumns // columns contains all the column names of Table for convenient usage. +} + +// SysUserColumns defines and stores column names for table sys_user. +type SysUserColumns struct { + Id string // + UserName string // 用户名 + Mobile string // 中国手机不带国家代码,国际手机号格式为:国家代码-手机号 + UserNickname string // 用户昵称 + Birthday string // 生日 + UserPassword string // 登录密码;cmf_password加密 + UserSalt string // 加密盐 + UserStatus string // 用户状态;0:禁用,1:正常,2:未验证 + UserEmail string // 用户登录邮箱 + Sex string // 性别;0:保密,1:男,2:女 + Avatar string // 用户头像 + DeptId string // 部门id + Remark string // 备注 + IsAdmin string // 是否后台管理员 1 是 0 否 + Address string // 联系地址 + Describe string // 描述信息 + LastLoginIp string // 最后登录ip + LastLoginTime string // 最后登录时间 + CreatedAt string // 创建时间 + UpdatedAt string // 更新时间 + DeletedAt string // 删除时间 +} + +// sysUserColumns holds the columns for table sys_user. +var sysUserColumns = SysUserColumns{ + Id: "id", + UserName: "user_name", + Mobile: "mobile", + UserNickname: "user_nickname", + Birthday: "birthday", + UserPassword: "user_password", + UserSalt: "user_salt", + UserStatus: "user_status", + UserEmail: "user_email", + Sex: "sex", + Avatar: "avatar", + DeptId: "dept_id", + Remark: "remark", + IsAdmin: "is_admin", + Address: "address", + Describe: "describe", + LastLoginIp: "last_login_ip", + LastLoginTime: "last_login_time", + CreatedAt: "created_at", + UpdatedAt: "updated_at", + DeletedAt: "deleted_at", +} + +// NewSysUserDao creates and returns a new DAO object for table data access. +func NewSysUserDao() *SysUserDao { + return &SysUserDao{ + group: "default", + table: "sys_user", + columns: sysUserColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysUserDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysUserDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysUserDao) Columns() SysUserColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysUserDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysUserDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysUserDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_user_online.go b/internal/dao/internal/sys_user_online.go new file mode 100644 index 0000000..290beb2 --- /dev/null +++ b/internal/dao/internal/sys_user_online.go @@ -0,0 +1,87 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysUserOnlineDao is the data access object for table sys_user_online. +type SysUserOnlineDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysUserOnlineColumns // columns contains all the column names of Table for convenient usage. +} + +// SysUserOnlineColumns defines and stores column names for table sys_user_online. +type SysUserOnlineColumns struct { + Id string // + Uuid string // 用户标识 + Token string // 用户token + CreateTime string // 登录时间 + UserName string // 用户名 + Ip string // 登录ip + Explorer string // 浏览器 + Os string // 操作系统 +} + +// sysUserOnlineColumns holds the columns for table sys_user_online. +var sysUserOnlineColumns = SysUserOnlineColumns{ + Id: "id", + Uuid: "uuid", + Token: "token", + CreateTime: "create_time", + UserName: "user_name", + Ip: "ip", + Explorer: "explorer", + Os: "os", +} + +// NewSysUserOnlineDao creates and returns a new DAO object for table data access. +func NewSysUserOnlineDao() *SysUserOnlineDao { + return &SysUserOnlineDao{ + group: "default", + table: "sys_user_online", + columns: sysUserOnlineColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysUserOnlineDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysUserOnlineDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysUserOnlineDao) Columns() SysUserOnlineColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysUserOnlineDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysUserOnlineDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysUserOnlineDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/internal/sys_user_post.go b/internal/dao/internal/sys_user_post.go new file mode 100644 index 0000000..40b57ac --- /dev/null +++ b/internal/dao/internal/sys_user_post.go @@ -0,0 +1,75 @@ +// ========================================================================== +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ========================================================================== + +package internal + +import ( + "context" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" +) + +// SysUserPostDao is the data access object for table sys_user_post. +type SysUserPostDao struct { + table string // table is the underlying table name of the DAO. + group string // group is the database configuration group name of current DAO. + columns SysUserPostColumns // columns contains all the column names of Table for convenient usage. +} + +// SysUserPostColumns defines and stores column names for table sys_user_post. +type SysUserPostColumns struct { + UserId string // 用户ID + PostId string // 岗位ID +} + +// sysUserPostColumns holds the columns for table sys_user_post. +var sysUserPostColumns = SysUserPostColumns{ + UserId: "user_id", + PostId: "post_id", +} + +// NewSysUserPostDao creates and returns a new DAO object for table data access. +func NewSysUserPostDao() *SysUserPostDao { + return &SysUserPostDao{ + group: "default", + table: "sys_user_post", + columns: sysUserPostColumns, + } +} + +// DB retrieves and returns the underlying raw database management object of current DAO. +func (dao *SysUserPostDao) DB() gdb.DB { + return g.DB(dao.group) +} + +// Table returns the table name of current dao. +func (dao *SysUserPostDao) Table() string { + return dao.table +} + +// Columns returns all column names of current dao. +func (dao *SysUserPostDao) Columns() SysUserPostColumns { + return dao.columns +} + +// Group returns the configuration group name of database of current dao. +func (dao *SysUserPostDao) Group() string { + return dao.group +} + +// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation. +func (dao *SysUserPostDao) Ctx(ctx context.Context) *gdb.Model { + return dao.DB().Model(dao.table).Safe().Ctx(ctx) +} + +// Transaction wraps the transaction logic using function f. +// It rollbacks the transaction and returns the error from function f if it returns non-nil error. +// It commits the transaction and returns nil if function f returns nil. +// +// Note that, you should not Commit or Rollback the transaction in function f +// as it is automatically handled by this function. +func (dao *SysUserPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) { + return dao.Ctx(ctx).Transaction(ctx, f) +} diff --git a/internal/dao/sys_auth_rule.go b/internal/dao/sys_auth_rule.go new file mode 100644 index 0000000..de20cbf --- /dev/null +++ b/internal/dao/sys_auth_rule.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysAuthRuleDao is internal type for wrapping internal DAO implements. +type internalSysAuthRuleDao = *internal.SysAuthRuleDao + +// sysAuthRuleDao is the data access object for table sys_auth_rule. +// You can define custom methods on it to extend its functionality as you wish. +type sysAuthRuleDao struct { + internalSysAuthRuleDao +} + +var ( + // SysAuthRule is globally public accessible object for table sys_auth_rule operations. + SysAuthRule = sysAuthRuleDao{ + internal.NewSysAuthRuleDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_config.go b/internal/dao/sys_config.go new file mode 100644 index 0000000..4b1af76 --- /dev/null +++ b/internal/dao/sys_config.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysConfigDao is internal type for wrapping internal DAO implements. +type internalSysConfigDao = *internal.SysConfigDao + +// sysConfigDao is the data access object for table sys_config. +// You can define custom methods on it to extend its functionality as you wish. +type sysConfigDao struct { + internalSysConfigDao +} + +var ( + // SysConfig is globally public accessible object for table sys_config operations. + SysConfig = sysConfigDao{ + internal.NewSysConfigDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_dept.go b/internal/dao/sys_dept.go new file mode 100644 index 0000000..df642af --- /dev/null +++ b/internal/dao/sys_dept.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysDeptDao is internal type for wrapping internal DAO implements. +type internalSysDeptDao = *internal.SysDeptDao + +// sysDeptDao is the data access object for table sys_dept. +// You can define custom methods on it to extend its functionality as you wish. +type sysDeptDao struct { + internalSysDeptDao +} + +var ( + // SysDept is globally public accessible object for table sys_dept operations. + SysDept = sysDeptDao{ + internal.NewSysDeptDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_dict_data.go b/internal/dao/sys_dict_data.go new file mode 100644 index 0000000..94cb9e4 --- /dev/null +++ b/internal/dao/sys_dict_data.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysDictDataDao is internal type for wrapping internal DAO implements. +type internalSysDictDataDao = *internal.SysDictDataDao + +// sysDictDataDao is the data access object for table sys_dict_data. +// You can define custom methods on it to extend its functionality as you wish. +type sysDictDataDao struct { + internalSysDictDataDao +} + +var ( + // SysDictData is globally public accessible object for table sys_dict_data operations. + SysDictData = sysDictDataDao{ + internal.NewSysDictDataDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_dict_type.go b/internal/dao/sys_dict_type.go new file mode 100644 index 0000000..5212da9 --- /dev/null +++ b/internal/dao/sys_dict_type.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysDictTypeDao is internal type for wrapping internal DAO implements. +type internalSysDictTypeDao = *internal.SysDictTypeDao + +// sysDictTypeDao is the data access object for table sys_dict_type. +// You can define custom methods on it to extend its functionality as you wish. +type sysDictTypeDao struct { + internalSysDictTypeDao +} + +var ( + // SysDictType is globally public accessible object for table sys_dict_type operations. + SysDictType = sysDictTypeDao{ + internal.NewSysDictTypeDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_login_log.go b/internal/dao/sys_login_log.go new file mode 100644 index 0000000..0eabe29 --- /dev/null +++ b/internal/dao/sys_login_log.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysLoginLogDao is internal type for wrapping internal DAO implements. +type internalSysLoginLogDao = *internal.SysLoginLogDao + +// sysLoginLogDao is the data access object for table sys_login_log. +// You can define custom methods on it to extend its functionality as you wish. +type sysLoginLogDao struct { + internalSysLoginLogDao +} + +var ( + // SysLoginLog is globally public accessible object for table sys_login_log operations. + SysLoginLog = sysLoginLogDao{ + internal.NewSysLoginLogDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_oper_log.go b/internal/dao/sys_oper_log.go new file mode 100644 index 0000000..300d0a2 --- /dev/null +++ b/internal/dao/sys_oper_log.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysOperLogDao is internal type for wrapping internal DAO implements. +type internalSysOperLogDao = *internal.SysOperLogDao + +// sysOperLogDao is the data access object for table sys_oper_log. +// You can define custom methods on it to extend its functionality as you wish. +type sysOperLogDao struct { + internalSysOperLogDao +} + +var ( + // SysOperLog is globally public accessible object for table sys_oper_log operations. + SysOperLog = sysOperLogDao{ + internal.NewSysOperLogDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_post.go b/internal/dao/sys_post.go new file mode 100644 index 0000000..2d16dec --- /dev/null +++ b/internal/dao/sys_post.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysPostDao is internal type for wrapping internal DAO implements. +type internalSysPostDao = *internal.SysPostDao + +// sysPostDao is the data access object for table sys_post. +// You can define custom methods on it to extend its functionality as you wish. +type sysPostDao struct { + internalSysPostDao +} + +var ( + // SysPost is globally public accessible object for table sys_post operations. + SysPost = sysPostDao{ + internal.NewSysPostDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_role.go b/internal/dao/sys_role.go new file mode 100644 index 0000000..1789d26 --- /dev/null +++ b/internal/dao/sys_role.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysRoleDao is internal type for wrapping internal DAO implements. +type internalSysRoleDao = *internal.SysRoleDao + +// sysRoleDao is the data access object for table sys_role. +// You can define custom methods on it to extend its functionality as you wish. +type sysRoleDao struct { + internalSysRoleDao +} + +var ( + // SysRole is globally public accessible object for table sys_role operations. + SysRole = sysRoleDao{ + internal.NewSysRoleDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_role_dept.go b/internal/dao/sys_role_dept.go new file mode 100644 index 0000000..3b5dde0 --- /dev/null +++ b/internal/dao/sys_role_dept.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysRoleDeptDao is internal type for wrapping internal DAO implements. +type internalSysRoleDeptDao = *internal.SysRoleDeptDao + +// sysRoleDeptDao is the data access object for table sys_role_dept. +// You can define custom methods on it to extend its functionality as you wish. +type sysRoleDeptDao struct { + internalSysRoleDeptDao +} + +var ( + // SysRoleDept is globally public accessible object for table sys_role_dept operations. + SysRoleDept = sysRoleDeptDao{ + internal.NewSysRoleDeptDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_user.go b/internal/dao/sys_user.go new file mode 100644 index 0000000..c1f2566 --- /dev/null +++ b/internal/dao/sys_user.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysUserDao is internal type for wrapping internal DAO implements. +type internalSysUserDao = *internal.SysUserDao + +// sysUserDao is the data access object for table sys_user. +// You can define custom methods on it to extend its functionality as you wish. +type sysUserDao struct { + internalSysUserDao +} + +var ( + // SysUser is globally public accessible object for table sys_user operations. + SysUser = sysUserDao{ + internal.NewSysUserDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_user_online.go b/internal/dao/sys_user_online.go new file mode 100644 index 0000000..e7504e1 --- /dev/null +++ b/internal/dao/sys_user_online.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysUserOnlineDao is internal type for wrapping internal DAO implements. +type internalSysUserOnlineDao = *internal.SysUserOnlineDao + +// sysUserOnlineDao is the data access object for table sys_user_online. +// You can define custom methods on it to extend its functionality as you wish. +type sysUserOnlineDao struct { + internalSysUserOnlineDao +} + +var ( + // SysUserOnline is globally public accessible object for table sys_user_online operations. + SysUserOnline = sysUserOnlineDao{ + internal.NewSysUserOnlineDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/dao/sys_user_post.go b/internal/dao/sys_user_post.go new file mode 100644 index 0000000..7339a77 --- /dev/null +++ b/internal/dao/sys_user_post.go @@ -0,0 +1,27 @@ +// ================================================================================= +// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish. +// ================================================================================= + +package dao + +import ( + "tyj_admin/internal/dao/internal" +) + +// internalSysUserPostDao is internal type for wrapping internal DAO implements. +type internalSysUserPostDao = *internal.SysUserPostDao + +// sysUserPostDao is the data access object for table sys_user_post. +// You can define custom methods on it to extend its functionality as you wish. +type sysUserPostDao struct { + internalSysUserPostDao +} + +var ( + // SysUserPost is globally public accessible object for table sys_user_post operations. + SysUserPost = sysUserPostDao{ + internal.NewSysUserPostDao(), + } +) + +// Fill with you ideas below. diff --git a/internal/model/context.go b/internal/model/context.go new file mode 100644 index 0000000..6007206 --- /dev/null +++ b/internal/model/context.go @@ -0,0 +1,16 @@ +/* +* @desc:context-model +* @company:云南奇讯科技有限公司 +* @Author: yixiaohu +* @Date: 2022/3/16 14:45 + */ + +package model + +type Context struct { + User *ContextUser // User in context. +} + +type ContextUser struct { + *LoginUserRes +} diff --git a/internal/model/do/casbin_rule.go b/internal/model/do/casbin_rule.go new file mode 100644 index 0000000..3e9ec42 --- /dev/null +++ b/internal/model/do/casbin_rule.go @@ -0,0 +1,21 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// CasbinRule is the golang structure of table casbin_rule for DAO operations like Where/Data. +type CasbinRule struct { + g.Meta `orm:"table:casbin_rule, do:true"` + Ptype interface{} // + V0 interface{} // + V1 interface{} // + V2 interface{} // + V3 interface{} // + V4 interface{} // + V5 interface{} // +} diff --git a/internal/model/do/sys_auth_rule.go b/internal/model/do/sys_auth_rule.go new file mode 100644 index 0000000..3efd7af --- /dev/null +++ b/internal/model/do/sys_auth_rule.go @@ -0,0 +1,37 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysAuthRule is the golang structure of table sys_auth_rule for DAO operations like Where/Data. +type SysAuthRule struct { + g.Meta `orm:"table:sys_auth_rule, do:true"` + Id interface{} // + Pid interface{} // 父ID + Name interface{} // 规则名称 + Title interface{} // 规则名称 + Icon interface{} // 图标 + Condition interface{} // 条件 + Remark interface{} // 备注 + MenuType interface{} // 类型 0目录 1菜单 2按钮 + Weigh interface{} // 权重 + IsHide interface{} // 显示状态 + Path interface{} // 路由地址 + Component interface{} // 组件路径 + IsLink interface{} // 是否外链 1是 0否 + ModuleType interface{} // 所属模块 + ModelId interface{} // 模型ID + IsIframe interface{} // 是否内嵌iframe + IsCached interface{} // 是否缓存 + Redirect interface{} // 路由重定向地址 + IsAffix interface{} // 是否固定 + LinkUrl interface{} // 链接地址 + CreatedAt *gtime.Time // 创建日期 + UpdatedAt *gtime.Time // 修改日期 +} diff --git a/internal/model/do/sys_config.go b/internal/model/do/sys_config.go new file mode 100644 index 0000000..caa8e08 --- /dev/null +++ b/internal/model/do/sys_config.go @@ -0,0 +1,25 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysConfig is the golang structure of table sys_config for DAO operations like Where/Data. +type SysConfig struct { + g.Meta `orm:"table:sys_config, do:true"` + ConfigId interface{} // 参数主键 + ConfigName interface{} // 参数名称 + ConfigKey interface{} // 参数键名 + ConfigValue interface{} // 参数键值 + ConfigType interface{} // 系统内置(Y是 N否) + CreateBy interface{} // 创建者 + UpdateBy interface{} // 更新者 + Remark interface{} // 备注 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 修改时间 +} diff --git a/internal/model/do/sys_dept.go b/internal/model/do/sys_dept.go new file mode 100644 index 0000000..6139fbc --- /dev/null +++ b/internal/model/do/sys_dept.go @@ -0,0 +1,29 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDept is the golang structure of table sys_dept for DAO operations like Where/Data. +type SysDept struct { + g.Meta `orm:"table:sys_dept, do:true"` + DeptId interface{} // 部门id + ParentId interface{} // 父部门id + Ancestors interface{} // 祖级列表 + DeptName interface{} // 部门名称 + OrderNum interface{} // 显示顺序 + Leader interface{} // 负责人 + Phone interface{} // 联系电话 + Email interface{} // 邮箱 + Status interface{} // 部门状态(0正常 1停用) + CreatedBy interface{} // 创建人 + UpdatedBy interface{} // 修改人 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 修改时间 + DeletedAt *gtime.Time // 删除时间 +} diff --git a/internal/model/do/sys_dict_data.go b/internal/model/do/sys_dict_data.go new file mode 100644 index 0000000..8f81b0b --- /dev/null +++ b/internal/model/do/sys_dict_data.go @@ -0,0 +1,29 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictData is the golang structure of table sys_dict_data for DAO operations like Where/Data. +type SysDictData struct { + g.Meta `orm:"table:sys_dict_data, do:true"` + DictCode interface{} // 字典编码 + DictSort interface{} // 字典排序 + DictLabel interface{} // 字典标签 + DictValue interface{} // 字典键值 + DictType interface{} // 字典类型 + CssClass interface{} // 样式属性(其他样式扩展) + ListClass interface{} // 表格回显样式 + IsDefault interface{} // 是否默认(1是 0否) + Status interface{} // 状态(0正常 1停用) + CreateBy interface{} // 创建者 + UpdateBy interface{} // 更新者 + Remark interface{} // 备注 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 修改时间 +} diff --git a/internal/model/do/sys_dict_type.go b/internal/model/do/sys_dict_type.go new file mode 100644 index 0000000..7522b84 --- /dev/null +++ b/internal/model/do/sys_dict_type.go @@ -0,0 +1,24 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictType is the golang structure of table sys_dict_type for DAO operations like Where/Data. +type SysDictType struct { + g.Meta `orm:"table:sys_dict_type, do:true"` + DictId interface{} // 字典主键 + DictName interface{} // 字典名称 + DictType interface{} // 字典类型 + Status interface{} // 状态(0正常 1停用) + CreateBy interface{} // 创建者 + UpdateBy interface{} // 更新者 + Remark interface{} // 备注 + CreatedAt *gtime.Time // 创建日期 + UpdatedAt *gtime.Time // 修改日期 +} diff --git a/internal/model/do/sys_login_log.go b/internal/model/do/sys_login_log.go new file mode 100644 index 0000000..8fd6538 --- /dev/null +++ b/internal/model/do/sys_login_log.go @@ -0,0 +1,25 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysLoginLog is the golang structure of table sys_login_log for DAO operations like Where/Data. +type SysLoginLog struct { + g.Meta `orm:"table:sys_login_log, do:true"` + InfoId interface{} // 访问ID + LoginName interface{} // 登录账号 + Ipaddr interface{} // 登录IP地址 + LoginLocation interface{} // 登录地点 + Browser interface{} // 浏览器类型 + Os interface{} // 操作系统 + Status interface{} // 登录状态(0成功 1失败) + Msg interface{} // 提示消息 + LoginTime *gtime.Time // 登录时间 + Module interface{} // 登录模块 +} diff --git a/internal/model/do/sys_oper_log.go b/internal/model/do/sys_oper_log.go new file mode 100644 index 0000000..d8180e6 --- /dev/null +++ b/internal/model/do/sys_oper_log.go @@ -0,0 +1,31 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysOperLog is the golang structure of table sys_oper_log for DAO operations like Where/Data. +type SysOperLog struct { + g.Meta `orm:"table:sys_oper_log, do:true"` + OperId interface{} // 日志主键 + Title interface{} // 模块标题 + BusinessType interface{} // 业务类型(0其它 1新增 2修改 3删除) + Method interface{} // 方法名称 + RequestMethod interface{} // 请求方式 + OperatorType interface{} // 操作类别(0其它 1后台用户 2手机端用户) + OperName interface{} // 操作人员 + DeptName interface{} // 部门名称 + OperUrl interface{} // 请求URL + OperIp interface{} // 主机地址 + OperLocation interface{} // 操作地点 + OperParam interface{} // 请求参数 + JsonResult interface{} // 返回参数 + Status interface{} // 操作状态(0正常 1异常) + ErrorMsg interface{} // 错误消息 + OperTime *gtime.Time // 操作时间 +} diff --git a/internal/model/do/sys_post.go b/internal/model/do/sys_post.go new file mode 100644 index 0000000..a8e067d --- /dev/null +++ b/internal/model/do/sys_post.go @@ -0,0 +1,26 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysPost is the golang structure of table sys_post for DAO operations like Where/Data. +type SysPost struct { + g.Meta `orm:"table:sys_post, do:true"` + PostId interface{} // 岗位ID + PostCode interface{} // 岗位编码 + PostName interface{} // 岗位名称 + PostSort interface{} // 显示顺序 + Status interface{} // 状态(0正常 1停用) + Remark interface{} // 备注 + CreatedBy interface{} // 创建人 + UpdatedBy interface{} // 修改人 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 修改时间 + DeletedAt *gtime.Time // 删除时间 +} diff --git a/internal/model/do/sys_role.go b/internal/model/do/sys_role.go new file mode 100644 index 0000000..47e9599 --- /dev/null +++ b/internal/model/do/sys_role.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysRole is the golang structure of table sys_role for DAO operations like Where/Data. +type SysRole struct { + g.Meta `orm:"table:sys_role, do:true"` + Id interface{} // + Status interface{} // 状态;0:禁用;1:正常 + ListOrder interface{} // 排序 + Name interface{} // 角色名称 + Remark interface{} // 备注 + DataScope interface{} // 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限) + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 +} diff --git a/internal/model/do/sys_role_dept.go b/internal/model/do/sys_role_dept.go new file mode 100644 index 0000000..df1a1ad --- /dev/null +++ b/internal/model/do/sys_role_dept.go @@ -0,0 +1,16 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// SysRoleDept is the golang structure of table sys_role_dept for DAO operations like Where/Data. +type SysRoleDept struct { + g.Meta `orm:"table:sys_role_dept, do:true"` + RoleId interface{} // 角色ID + DeptId interface{} // 部门ID +} diff --git a/internal/model/do/sys_user.go b/internal/model/do/sys_user.go new file mode 100644 index 0000000..d4934ee --- /dev/null +++ b/internal/model/do/sys_user.go @@ -0,0 +1,36 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysUser is the golang structure of table sys_user for DAO operations like Where/Data. +type SysUser struct { + g.Meta `orm:"table:sys_user, do:true"` + Id interface{} // + UserName interface{} // 用户名 + Mobile interface{} // 中国手机不带国家代码,国际手机号格式为:国家代码-手机号 + UserNickname interface{} // 用户昵称 + Birthday interface{} // 生日 + UserPassword interface{} // 登录密码;cmf_password加密 + UserSalt interface{} // 加密盐 + UserStatus interface{} // 用户状态;0:禁用,1:正常,2:未验证 + UserEmail interface{} // 用户登录邮箱 + Sex interface{} // 性别;0:保密,1:男,2:女 + Avatar interface{} // 用户头像 + DeptId interface{} // 部门id + Remark interface{} // 备注 + IsAdmin interface{} // 是否后台管理员 1 是 0 否 + Address interface{} // 联系地址 + Describe interface{} // 描述信息 + LastLoginIp interface{} // 最后登录ip + LastLoginTime *gtime.Time // 最后登录时间 + CreatedAt *gtime.Time // 创建时间 + UpdatedAt *gtime.Time // 更新时间 + DeletedAt *gtime.Time // 删除时间 +} diff --git a/internal/model/do/sys_user_online.go b/internal/model/do/sys_user_online.go new file mode 100644 index 0000000..f47ec4b --- /dev/null +++ b/internal/model/do/sys_user_online.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +// SysUserOnline is the golang structure of table sys_user_online for DAO operations like Where/Data. +type SysUserOnline struct { + g.Meta `orm:"table:sys_user_online, do:true"` + Id interface{} // + Uuid interface{} // 用户标识 + Token interface{} // 用户token + CreateTime *gtime.Time // 登录时间 + UserName interface{} // 用户名 + Ip interface{} // 登录ip + Explorer interface{} // 浏览器 + Os interface{} // 操作系统 +} diff --git a/internal/model/do/sys_user_post.go b/internal/model/do/sys_user_post.go new file mode 100644 index 0000000..a06c02d --- /dev/null +++ b/internal/model/do/sys_user_post.go @@ -0,0 +1,16 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package do + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +// SysUserPost is the golang structure of table sys_user_post for DAO operations like Where/Data. +type SysUserPost struct { + g.Meta `orm:"table:sys_user_post, do:true"` + UserId interface{} // 用户ID + PostId interface{} // 岗位ID +} diff --git a/internal/model/entity/casbin_rule.go b/internal/model/entity/casbin_rule.go new file mode 100644 index 0000000..99ad458 --- /dev/null +++ b/internal/model/entity/casbin_rule.go @@ -0,0 +1,16 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// CasbinRule is the golang structure for table casbin_rule. +type CasbinRule struct { + Ptype string `json:"ptype" description:""` + V0 string `json:"v0" description:""` + V1 string `json:"v1" description:""` + V2 string `json:"v2" description:""` + V3 string `json:"v3" description:""` + V4 string `json:"v4" description:""` + V5 string `json:"v5" description:""` +} diff --git a/internal/model/entity/sys_auth_rule.go b/internal/model/entity/sys_auth_rule.go new file mode 100644 index 0000000..b4d8197 --- /dev/null +++ b/internal/model/entity/sys_auth_rule.go @@ -0,0 +1,35 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysAuthRule is the golang structure for table sys_auth_rule. +type SysAuthRule struct { + Id uint `json:"id" description:""` + Pid uint `json:"pid" description:"父ID"` + Name string `json:"name" description:"规则名称"` + Title string `json:"title" description:"规则名称"` + Icon string `json:"icon" description:"图标"` + Condition string `json:"condition" description:"条件"` + Remark string `json:"remark" description:"备注"` + MenuType uint `json:"menuType" description:"类型 0目录 1菜单 2按钮"` + Weigh int `json:"weigh" description:"权重"` + IsHide uint `json:"isHide" description:"显示状态"` + Path string `json:"path" description:"路由地址"` + Component string `json:"component" description:"组件路径"` + IsLink uint `json:"isLink" description:"是否外链 1是 0否"` + ModuleType string `json:"moduleType" description:"所属模块"` + ModelId uint `json:"modelId" description:"模型ID"` + IsIframe uint `json:"isIframe" description:"是否内嵌iframe"` + IsCached uint `json:"isCached" description:"是否缓存"` + Redirect string `json:"redirect" description:"路由重定向地址"` + IsAffix uint `json:"isAffix" description:"是否固定"` + LinkUrl string `json:"linkUrl" description:"链接地址"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建日期"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"修改日期"` +} diff --git a/internal/model/entity/sys_config.go b/internal/model/entity/sys_config.go new file mode 100644 index 0000000..fd49bcb --- /dev/null +++ b/internal/model/entity/sys_config.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysConfig is the golang structure for table sys_config. +type SysConfig struct { + ConfigId uint `json:"configId" description:"参数主键"` + ConfigName string `json:"configName" description:"参数名称"` + ConfigKey string `json:"configKey" description:"参数键名"` + ConfigValue string `json:"configValue" description:"参数键值"` + ConfigType int `json:"configType" description:"系统内置(Y是 N否)"` + CreateBy uint `json:"createBy" description:"创建者"` + UpdateBy uint `json:"updateBy" description:"更新者"` + Remark string `json:"remark" description:"备注"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"` +} diff --git a/internal/model/entity/sys_dept.go b/internal/model/entity/sys_dept.go new file mode 100644 index 0000000..acbc258 --- /dev/null +++ b/internal/model/entity/sys_dept.go @@ -0,0 +1,27 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDept is the golang structure for table sys_dept. +type SysDept struct { + DeptId int64 `json:"deptId" description:"部门id"` + ParentId int64 `json:"parentId" description:"父部门id"` + Ancestors string `json:"ancestors" description:"祖级列表"` + DeptName string `json:"deptName" description:"部门名称"` + OrderNum int `json:"orderNum" description:"显示顺序"` + Leader string `json:"leader" description:"负责人"` + Phone string `json:"phone" description:"联系电话"` + Email string `json:"email" description:"邮箱"` + Status uint `json:"status" description:"部门状态(0正常 1停用)"` + CreatedBy uint64 `json:"createdBy" description:"创建人"` + UpdatedBy int64 `json:"updatedBy" description:"修改人"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"` + DeletedAt *gtime.Time `json:"deletedAt" description:"删除时间"` +} diff --git a/internal/model/entity/sys_dict_data.go b/internal/model/entity/sys_dict_data.go new file mode 100644 index 0000000..e5363fc --- /dev/null +++ b/internal/model/entity/sys_dict_data.go @@ -0,0 +1,27 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictData is the golang structure for table sys_dict_data. +type SysDictData struct { + DictCode int64 `json:"dictCode" description:"字典编码"` + DictSort int `json:"dictSort" description:"字典排序"` + DictLabel string `json:"dictLabel" description:"字典标签"` + DictValue string `json:"dictValue" description:"字典键值"` + DictType string `json:"dictType" description:"字典类型"` + CssClass string `json:"cssClass" description:"样式属性(其他样式扩展)"` + ListClass string `json:"listClass" description:"表格回显样式"` + IsDefault int `json:"isDefault" description:"是否默认(1是 0否)"` + Status int `json:"status" description:"状态(0正常 1停用)"` + CreateBy uint64 `json:"createBy" description:"创建者"` + UpdateBy uint64 `json:"updateBy" description:"更新者"` + Remark string `json:"remark" description:"备注"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"` +} diff --git a/internal/model/entity/sys_dict_type.go b/internal/model/entity/sys_dict_type.go new file mode 100644 index 0000000..1556460 --- /dev/null +++ b/internal/model/entity/sys_dict_type.go @@ -0,0 +1,22 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysDictType is the golang structure for table sys_dict_type. +type SysDictType struct { + DictId uint64 `json:"dictId" description:"字典主键"` + DictName string `json:"dictName" description:"字典名称"` + DictType string `json:"dictType" description:"字典类型"` + Status uint `json:"status" description:"状态(0正常 1停用)"` + CreateBy uint `json:"createBy" description:"创建者"` + UpdateBy uint `json:"updateBy" description:"更新者"` + Remark string `json:"remark" description:"备注"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建日期"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"修改日期"` +} diff --git a/internal/model/entity/sys_login_log.go b/internal/model/entity/sys_login_log.go new file mode 100644 index 0000000..3a7b961 --- /dev/null +++ b/internal/model/entity/sys_login_log.go @@ -0,0 +1,23 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysLoginLog is the golang structure for table sys_login_log. +type SysLoginLog struct { + InfoId int64 `json:"infoId" description:"访问ID"` + LoginName string `json:"loginName" description:"登录账号"` + Ipaddr string `json:"ipaddr" description:"登录IP地址"` + LoginLocation string `json:"loginLocation" description:"登录地点"` + Browser string `json:"browser" description:"浏览器类型"` + Os string `json:"os" description:"操作系统"` + Status int `json:"status" description:"登录状态(0成功 1失败)"` + Msg string `json:"msg" description:"提示消息"` + LoginTime *gtime.Time `json:"loginTime" description:"登录时间"` + Module string `json:"module" description:"登录模块"` +} diff --git a/internal/model/entity/sys_oper_log.go b/internal/model/entity/sys_oper_log.go new file mode 100644 index 0000000..c68385d --- /dev/null +++ b/internal/model/entity/sys_oper_log.go @@ -0,0 +1,29 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysOperLog is the golang structure for table sys_oper_log. +type SysOperLog struct { + OperId uint64 `json:"operId" description:"日志主键"` + Title string `json:"title" description:"模块标题"` + BusinessType int `json:"businessType" description:"业务类型(0其它 1新增 2修改 3删除)"` + Method string `json:"method" description:"方法名称"` + RequestMethod string `json:"requestMethod" description:"请求方式"` + OperatorType int `json:"operatorType" description:"操作类别(0其它 1后台用户 2手机端用户)"` + OperName string `json:"operName" description:"操作人员"` + DeptName string `json:"deptName" description:"部门名称"` + OperUrl string `json:"operUrl" description:"请求URL"` + OperIp string `json:"operIp" description:"主机地址"` + OperLocation string `json:"operLocation" description:"操作地点"` + OperParam string `json:"operParam" description:"请求参数"` + JsonResult string `json:"jsonResult" description:"返回参数"` + Status int `json:"status" description:"操作状态(0正常 1异常)"` + ErrorMsg string `json:"errorMsg" description:"错误消息"` + OperTime *gtime.Time `json:"operTime" description:"操作时间"` +} diff --git a/internal/model/entity/sys_post.go b/internal/model/entity/sys_post.go new file mode 100644 index 0000000..8301eb8 --- /dev/null +++ b/internal/model/entity/sys_post.go @@ -0,0 +1,24 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysPost is the golang structure for table sys_post. +type SysPost struct { + PostId uint64 `json:"postId" description:"岗位ID"` + PostCode string `json:"postCode" description:"岗位编码"` + PostName string `json:"postName" description:"岗位名称"` + PostSort int `json:"postSort" description:"显示顺序"` + Status uint `json:"status" description:"状态(0正常 1停用)"` + Remark string `json:"remark" description:"备注"` + CreatedBy uint64 `json:"createdBy" description:"创建人"` + UpdatedBy uint64 `json:"updatedBy" description:"修改人"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"` + DeletedAt *gtime.Time `json:"deletedAt" description:"删除时间"` +} diff --git a/internal/model/entity/sys_role.go b/internal/model/entity/sys_role.go new file mode 100644 index 0000000..c98e802 --- /dev/null +++ b/internal/model/entity/sys_role.go @@ -0,0 +1,21 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysRole is the golang structure for table sys_role. +type SysRole struct { + Id uint `json:"id" description:""` + Status uint `json:"status" description:"状态;0:禁用;1:正常"` + ListOrder uint `json:"listOrder" description:"排序"` + Name string `json:"name" description:"角色名称"` + Remark string `json:"remark" description:"备注"` + DataScope uint `json:"dataScope" description:"数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"` +} diff --git a/internal/model/entity/sys_role_dept.go b/internal/model/entity/sys_role_dept.go new file mode 100644 index 0000000..c795ca0 --- /dev/null +++ b/internal/model/entity/sys_role_dept.go @@ -0,0 +1,11 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// SysRoleDept is the golang structure for table sys_role_dept. +type SysRoleDept struct { + RoleId int64 `json:"roleId" description:"角色ID"` + DeptId int64 `json:"deptId" description:"部门ID"` +} diff --git a/internal/model/entity/sys_user.go b/internal/model/entity/sys_user.go new file mode 100644 index 0000000..bd87afd --- /dev/null +++ b/internal/model/entity/sys_user.go @@ -0,0 +1,34 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysUser is the golang structure for table sys_user. +type SysUser struct { + Id uint64 `json:"id" description:""` + UserName string `json:"userName" description:"用户名"` + Mobile string `json:"mobile" description:"中国手机不带国家代码,国际手机号格式为:国家代码-手机号"` + UserNickname string `json:"userNickname" description:"用户昵称"` + Birthday int `json:"birthday" description:"生日"` + UserPassword string `json:"userPassword" description:"登录密码;cmf_password加密"` + UserSalt string `json:"userSalt" description:"加密盐"` + UserStatus uint `json:"userStatus" description:"用户状态;0:禁用,1:正常,2:未验证"` + UserEmail string `json:"userEmail" description:"用户登录邮箱"` + Sex int `json:"sex" description:"性别;0:保密,1:男,2:女"` + Avatar string `json:"avatar" description:"用户头像"` + DeptId uint64 `json:"deptId" description:"部门id"` + Remark string `json:"remark" description:"备注"` + IsAdmin int `json:"isAdmin" description:"是否后台管理员 1 是 0 否"` + Address string `json:"address" description:"联系地址"` + Describe string `json:"describe" description:"描述信息"` + LastLoginIp string `json:"lastLoginIp" description:"最后登录ip"` + LastLoginTime *gtime.Time `json:"lastLoginTime" description:"最后登录时间"` + CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"` + UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"` + DeletedAt *gtime.Time `json:"deletedAt" description:"删除时间"` +} diff --git a/internal/model/entity/sys_user_online.go b/internal/model/entity/sys_user_online.go new file mode 100644 index 0000000..a286995 --- /dev/null +++ b/internal/model/entity/sys_user_online.go @@ -0,0 +1,21 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +import ( + "github.com/gogf/gf/v2/os/gtime" +) + +// SysUserOnline is the golang structure for table sys_user_online. +type SysUserOnline struct { + Id uint64 `json:"id" description:""` + Uuid string `json:"uuid" description:"用户标识"` + Token string `json:"token" description:"用户token"` + CreateTime *gtime.Time `json:"createTime" description:"登录时间"` + UserName string `json:"userName" description:"用户名"` + Ip string `json:"ip" description:"登录ip"` + Explorer string `json:"explorer" description:"浏览器"` + Os string `json:"os" description:"操作系统"` +} diff --git a/internal/model/entity/sys_user_post.go b/internal/model/entity/sys_user_post.go new file mode 100644 index 0000000..8de724c --- /dev/null +++ b/internal/model/entity/sys_user_post.go @@ -0,0 +1,11 @@ +// ================================================================================= +// Code generated by GoFrame CLI tool. DO NOT EDIT. +// ================================================================================= + +package entity + +// SysUserPost is the golang structure for table sys_user_post. +type SysUserPost struct { + UserId int64 `json:"userId" description:"用户ID"` + PostId int64 `json:"postId" description:"岗位ID"` +} diff --git a/internal/model/sys_auth_rule.go b/internal/model/sys_auth_rule.go new file mode 100644 index 0000000..f797156 --- /dev/null +++ b/internal/model/sys_auth_rule.go @@ -0,0 +1,59 @@ +/* +* @desc:菜单model +* +* +* @Date: 2022/3/11 14:53 + */ + +package model + +type SysAuthRuleInfoRes struct { + Id uint `orm:"id,primary" json:"id"` // + Pid uint `orm:"pid" json:"pid"` // 父ID + Name string `orm:"name,unique" json:"name"` // 规则名称 + Title string `orm:"title" json:"title"` // 规则名称 + Icon string `orm:"icon" json:"icon"` // 图标 + Condition string `orm:"condition" json:"condition"` // 条件 + Remark string `orm:"remark" json:"remark"` // 备注 + MenuType uint `orm:"menu_type" json:"menuType"` // 类型 0目录 1菜单 2按钮 + Weigh int `orm:"weigh" json:"weigh"` // 权重 + IsHide uint `orm:"is_hide" json:"isHide"` // 显示状态 + IsCached uint `orm:"is_cached" json:"isCached"` // 是否缓存 + IsAffix uint `orm:"is_affix" json:"isAffix"` //是否固定 + Path string `orm:"path" json:"path"` // 路由地址 + Redirect string `orm:"redirect" json:"redirect"` // 跳转路由 + Component string `orm:"component" json:"component"` // 组件路径 + IsIframe uint `orm:"is_iframe" json:"isIframe"` // 是否iframe + IsLink uint `orm:"is_link" json:"isLink"` // 是否外链 1是 0否 + LinkUrl string `orm:"link_url" json:"linkUrl"` //链接地址 +} + +// SysAuthRuleTreeRes 菜单树形结构 +type SysAuthRuleTreeRes struct { + *SysAuthRuleInfoRes + Children []*SysAuthRuleTreeRes `json:"children"` +} + +type UserMenu struct { + Id uint `json:"id"` + Pid uint `json:"pid"` + Name string `json:"name"` + Component string `json:"component"` + Path string `json:"path"` + *MenuMeta `json:"meta"` +} + +type UserMenus struct { + *UserMenu `json:""` + Children []*UserMenus `json:"children"` +} + +type MenuMeta struct { + Icon string `json:"icon"` + Title string `json:"title"` + IsLink string `json:"isLink"` + IsHide bool `json:"isHide"` + IsKeepAlive bool `json:"isKeepAlive"` + IsAffix bool `json:"isAffix"` + IsIframe bool `json:"isIframe"` +} diff --git a/internal/model/sys_config.go b/internal/model/sys_config.go new file mode 100644 index 0000000..bc132aa --- /dev/null +++ b/internal/model/sys_config.go @@ -0,0 +1,8 @@ +/* +* @desc:xxxx功能描述 +* +* +* @Date: 2022/3/18 11:56 + */ + +package model diff --git a/internal/model/sys_dept.go b/internal/model/sys_dept.go new file mode 100644 index 0000000..c349d48 --- /dev/null +++ b/internal/model/sys_dept.go @@ -0,0 +1,15 @@ +/* +* @desc:部门model +* +* +* @Date: 2022/4/11 9:07 + */ + +package model + +import "tyj_admin/internal/model/entity" + +type SysDeptTreeRes struct { + *entity.SysDept + Children []*SysDeptTreeRes `json:"children"` +} diff --git a/internal/model/sys_dict_data.go b/internal/model/sys_dict_data.go new file mode 100644 index 0000000..3b124d0 --- /dev/null +++ b/internal/model/sys_dict_data.go @@ -0,0 +1,21 @@ +/* +* @desc:字典数据 +* +* +* @Date: 2022/3/18 11:56 + */ + +package model + +type DictTypeRes struct { + DictName string `json:"name"` + Remark string `json:"remark"` +} + +// DictDataRes 字典数据 +type DictDataRes struct { + DictValue string `json:"key"` + DictLabel string `json:"value"` + IsDefault int `json:"isDefault"` + Remark string `json:"remark"` +} diff --git a/internal/model/sys_dict_type.go b/internal/model/sys_dict_type.go new file mode 100644 index 0000000..d487d50 --- /dev/null +++ b/internal/model/sys_dict_type.go @@ -0,0 +1,19 @@ +/* +* @desc:字典类型 +* +* +* @Date: 2022/3/18 11:56 + */ + +package model + +import "github.com/gogf/gf/v2/os/gtime" + +type SysDictTypeInfoRes struct { + DictId uint64 `orm:"dict_id,primary" json:"dictId"` // 字典主键 + DictName string `orm:"dict_name" json:"dictName"` // 字典名称 + DictType string `orm:"dict_type,unique" json:"dictType"` // 字典类型 + Status uint `orm:"status" json:"status"` // 状态(0正常 1停用) + Remark string `orm:"remark" json:"remark"` // 备注 + CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建日期 +} diff --git a/internal/model/sys_init.go b/internal/model/sys_init.go new file mode 100644 index 0000000..91cb6ff --- /dev/null +++ b/internal/model/sys_init.go @@ -0,0 +1,39 @@ +package model + +// 程序初始化yaml配置文件 +type DbInitConfig struct { + Database Database `json:"database" yaml:"database"` + Redis Redis `json:"redis" yaml:"redis"` +} + +type Database struct { + Default DbDefault `json:"default" yaml:"default"` +} + +type DbDefault struct { + Host string `json:"host" yaml:"host"` + Port int `json:"port" yaml:"port"` + User string `json:"user" yaml:"user"` + Pass string `json:"pass" yaml:"pass"` + Name string `json:"name" yaml:"name"` + Type string `json:"type" yaml:"type"` + Role string `json:"role" yaml:"role"` + Debug bool `json:"debug" yaml:"debug"` + Charset string `json:"charset" yaml:"charset"` + DryRun bool `json:"dryRun" yaml:"dryRun"` + MaxIdle int `json:"maxIdle" yaml:"maxIdle"` + MaxOpen int `json:"maxOpen" yaml:"maxOpen"` + MaxLifetime int `json:"maxLifetime" yaml:"maxLifetime"` +} + +type Redis struct { + Default RedisDefault `json:"default" yaml:"default"` +} + +type RedisDefault struct { + Address string `json:"address" yaml:"address"` + Db int `json:"db" yaml:"db"` + Pass string `json:"pass" yaml:"pass"` + IdleTimeout int `json:"idleTimeout" yaml:"idleTimeout"` + MaxActive int `json:"maxActive" yaml:"maxActive"` +} diff --git a/internal/model/sys_role.go b/internal/model/sys_role.go new file mode 100644 index 0000000..d494d83 --- /dev/null +++ b/internal/model/sys_role.go @@ -0,0 +1,8 @@ +/* +* @desc:角色 +* +* +* @Date: 2022/3/30 9:11 + */ + +package model diff --git a/internal/model/sys_user.go b/internal/model/sys_user.go new file mode 100644 index 0000000..b59ee20 --- /dev/null +++ b/internal/model/sys_user.go @@ -0,0 +1,41 @@ +/* +* @desc:用户模型对象 +* +* +* @Date: 2022/3/7 11:47 + */ + +package model + +import "tyj_admin/internal/model/entity" + +// LoginUserRes 登录返回 +type LoginUserRes struct { + Id uint64 `orm:"id,primary" json:"id"` // + UserName string `orm:"user_name,unique" json:"userName"` // 用户名 + UserNickname string `orm:"user_nickname" json:"userNickname"` // 用户昵称 + UserPassword string `orm:"user_password" json:"userPassword"` // 登录密码;cmf_password加密 + UserSalt string `orm:"user_salt" json:"userSalt"` // 加密盐 + UserStatus uint `orm:"user_status" json:"userStatus"` // 用户状态;0:禁用,1:正常,2:未验证 + IsAdmin int `orm:"is_admin" json:"isAdmin"` // 是否后台管理员 1 是 0 否 + Avatar string `orm:"avatar" json:"avatar"` //头像 + DeptId uint64 `orm:"dept_id" json:"deptId"` //部门id +} + +// SysUserRoleDeptRes 带有部门、角色、岗位信息的用户数据 +type SysUserRoleDeptRes struct { + *entity.SysUser + Dept *entity.SysDept `json:"dept"` + RoleInfo []*SysUserRoleInfoRes `json:"roleInfo"` + Post []*SysUserPostInfoRes `json:"post"` +} + +type SysUserRoleInfoRes struct { + RoleId uint `json:"roleId"` + Name string `json:"name"` +} + +type SysUserPostInfoRes struct { + PostId int64 `json:"postId"` + PostName string `json:"postName"` +} diff --git a/internal/model/sys_user_login.go b/internal/model/sys_user_login.go new file mode 100644 index 0000000..b794b48 --- /dev/null +++ b/internal/model/sys_user_login.go @@ -0,0 +1,18 @@ +/* +* @desc:登录日志 +* +* +* @Date: 2022/3/8 11:43 + */ + +package model + +// LoginLogParams 登录日志写入参数 +type LoginLogParams struct { + Status int + Username string + Ip string + UserAgent string + Msg string + Module string +} diff --git a/internal/model/token.go b/internal/model/token.go new file mode 100644 index 0000000..cb16f1a --- /dev/null +++ b/internal/model/token.go @@ -0,0 +1,32 @@ +/* +* @desc:token options +* +* +* @Date: 2022/3/8 16:02 + */ + +package model + +import ( + "github.com/gogf/gf/v2/frame/g" +) + +type TokenOptions struct { + // server name + ServerName string `json:"serverName"` + // 缓存key (每创建一个实例CacheKey必须不相同) + CacheKey string `json:"cacheKey"` + // 超时时间 默认10天(秒) + Timeout int64 `json:"timeout"` + // 缓存刷新时间 默认5天(秒) + // 处理携带token的请求时当前时间大于超时时间并小于缓存刷新时间时token将自动刷新即重置token存活时间 + // MaxRefresh值为0时,token将不会自动刷新 + MaxRefresh int64 `json:"maxRefresh"` + // 是否允许多点登录 + MultiLogin bool `json:"multiLogin"` + // Token加密key 32位 + EncryptKey []byte `json:"encryptKey"` + // 拦截排除地址 + ExcludePaths g.SliceStr `json:"excludePaths"` + CacheModel string `json:"cacheModel"` +} diff --git a/internal/packed/packed.go b/internal/packed/packed.go new file mode 100644 index 0000000..e20ab1e --- /dev/null +++ b/internal/packed/packed.go @@ -0,0 +1 @@ +package packed diff --git a/internal/router/router.go b/internal/router/router.go new file mode 100644 index 0000000..8f0a162 --- /dev/null +++ b/internal/router/router.go @@ -0,0 +1,86 @@ +/* +* @desc:路由绑定 +* +* +* @Date: 2022/2/18 16:23 + */ + +package router + +import ( + "github.com/gogf/gf/v2/net/ghttp" + + "tyj_admin/internal/controller" + "tyj_admin/internal/service" +) + +func BindController(group *ghttp.RouterGroup) { + group.Group("/api/v1", func(group *ghttp.RouterGroup) { + group.Middleware(ghttp.MiddlewareHandlerResponse) + // 绑定后台路由 + SystemBindController(group) + // 绑定测试路由 + DemoBindController(group) + // 绑定公共路由 + CommonBindController(group) + }) + +} + +func CommonBindController(group *ghttp.RouterGroup) { + group.Group("/pub", func(group *ghttp.RouterGroup) { + group.Middleware(service.Middleware().MiddlewareCORS) + group.Group("/captcha", func(group *ghttp.RouterGroup) { + group.Bind( + controller.Captcha, + ) + }) + + // 文件上传 + group.Group("/upload", func(group *ghttp.RouterGroup) { + group.Bind( + controller.Upload, + ) + }) + }) +} + +func DemoBindController(group *ghttp.RouterGroup) { + group.Group("/demo", func(group *ghttp.RouterGroup) { + group.Middleware(service.Middleware().MiddlewareCORS) + group.Bind( + controller.Demo, + ) + }) + +} + +func SystemBindController(group *ghttp.RouterGroup) { + group.Group("/system", func(group *ghttp.RouterGroup) { + group.Middleware(service.Middleware().MiddlewareCORS) + // 系统初始化 + group.Bind( + controller.DbInit, + ) + group.Bind( + //登录 + controller.Login, + ) + //登录验证拦截 + service.SysGfToken().Middleware(group) + //context拦截器 + group.Middleware(service.Middleware().Ctx, service.Middleware().Auth) + group.Bind( + controller.User, + controller.Menu, + controller.Role, + controller.Dept, + controller.Post, + controller.DictType, + controller.DictData, + controller.Config, + controller.Monitor, + controller.LoginLog, + ) + }) +} diff --git a/internal/service/cache.go b/internal/service/cache.go new file mode 100644 index 0000000..9f0a236 --- /dev/null +++ b/internal/service/cache.go @@ -0,0 +1,55 @@ +/* +* @desc:缓存处理 +* +* +* @Date: 2022/3/9 11:15 + */ + +package service + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + "github.com/tiger1103/gfast-cache/cache" + "sync" + "tyj_admin/internal/consts" +) + +type ICache interface { + cache.IGCache +} + +type cacheImpl struct { + *cache.GfCache + prefix string +} + +var ( + c = cacheImpl{} + cacheContainer *cache.GfCache + lock = &sync.Mutex{} +) + +func Cache() ICache { + var ( + ch = c + ctx = gctx.New() + ) + prefix := g.Cfg().MustGet(ctx, "system.cache.prefix").String() + model := g.Cfg().MustGet(ctx, "system.cache.model").String() + if cacheContainer == nil { + lock.Lock() + if cacheContainer == nil { + if model == consts.CacheModelRedis { + // redis + cacheContainer = cache.NewRedis(prefix) + } else { + // memory + cacheContainer = cache.New(prefix) + } + } + lock.Unlock() + } + ch.GfCache = cacheContainer + return &ch +} diff --git a/internal/service/captcha.go b/internal/service/captcha.go new file mode 100644 index 0000000..d40f530 --- /dev/null +++ b/internal/service/captcha.go @@ -0,0 +1,51 @@ +package service + +import ( + "context" + "github.com/gogf/gf/v2/text/gstr" + "github.com/mojocn/base64Captcha" +) + +type ICaptcha interface { + GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string, err error) + VerifyString(id, answer string) bool +} + +type captchaImpl struct { + driver *base64Captcha.DriverString + store base64Captcha.Store +} + +var ( + captcha = captchaImpl{ + driver: &base64Captcha.DriverString{ + Height: 80, + Width: 240, + NoiseCount: 50, + ShowLineOptions: 20, + Length: 4, + Source: "abcdefghjkmnpqrstuvwxyz23456789", + Fonts: []string{"chromohv.ttf"}, + }, + store: base64Captcha.DefaultMemStore, + } +) + +func Captcha() ICaptcha { + return &captcha +} + +// GetVerifyImgString 获取字母数字混合验证码 +func (s *captchaImpl) GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string, err error) { + driver := s.driver.ConvertFonts() + c := base64Captcha.NewCaptcha(driver, s.store) + idKeyC, base64stringC, err = c.Generate() + return +} + +// VerifyString 验证输入的验证码是否正确 +func (s *captchaImpl) VerifyString(id, answer string) bool { + c := base64Captcha.NewCaptcha(s.driver, s.store) + answer = gstr.ToLower(answer) + return c.Verify(id, answer, true) +} diff --git a/internal/service/casbin.go b/internal/service/casbin.go new file mode 100644 index 0000000..1f9afa0 --- /dev/null +++ b/internal/service/casbin.go @@ -0,0 +1,238 @@ +package service + +import ( + "context" + "github.com/casbin/casbin/v2" + "github.com/casbin/casbin/v2/model" + "github.com/casbin/casbin/v2/persist" + "github.com/gogf/gf/v2/frame/g" + "sync" + "tyj_admin/internal/dao" + "tyj_admin/internal/model/entity" +) + +type cabinImpl struct{} + +type adapterCasbin struct { + Enforcer *casbin.SyncedEnforcer + EnforcerErr error + ctx context.Context +} + +var ( + cb = cabinImpl{} + once sync.Once + ac *adapterCasbin +) + +// CasbinEnforcer 获取adapter单例对象 +func CasbinEnforcer(ctx context.Context) (enforcer *casbin.SyncedEnforcer, err error) { + once.Do(func() { + ac = cb.newAdapter(ctx) + }) + enforcer = ac.Enforcer + err = ac.EnforcerErr + return +} + +// 初始化adapter操作 +func (s *cabinImpl) newAdapter(ctx context.Context) (a *adapterCasbin) { + a = new(adapterCasbin) + a.initPolicy(ctx) + a.ctx = ctx + return +} + +func (a *adapterCasbin) initPolicy(ctx context.Context) { + // Because the DB is empty at first, + // so we need to load the policy from the file adapter (.CSV) first. + e, err := casbin.NewSyncedEnforcer(g.Cfg().MustGet(ctx, "casbin.modelFile").String(), a) + + if err != nil { + a.EnforcerErr = err + return + } + + // This is a trick to save the current policy to the DB. + // We can't call e.SavePolicy() because the adapter in the enforcer is still the file adapter. + // The current policy means the policy in the Casbin enforcer (aka in memory). + //err = a.SavePolicy(e.GetModel()) + //if err != nil { + // return err + //} + //set adapter + //e.SetAdapter(a) + // Clear the current policy. + e.ClearPolicy() + a.Enforcer = e + // Load the policy from DB. + err = a.LoadPolicy(e.GetModel()) + if err != nil { + a.EnforcerErr = err + return + } +} + +// SavePolicy saves policy to database. +func (a *adapterCasbin) SavePolicy(model model.Model) (err error) { + err = a.dropTable() + if err != nil { + return + } + err = a.createTable() + if err != nil { + return + } + for ptype, ast := range model["p"] { + for _, rule := range ast.Policy { + line := savePolicyLine(ptype, rule) + _, err := dao.CasbinRule.Ctx(a.ctx).Data(line).Insert() + if err != nil { + return err + } + } + } + + for ptype, ast := range model["g"] { + for _, rule := range ast.Policy { + line := savePolicyLine(ptype, rule) + _, err := dao.CasbinRule.Ctx(a.ctx).Data(line).Insert() + if err != nil { + return err + } + } + } + return +} + +func (a *adapterCasbin) dropTable() (err error) { + return +} + +func (a *adapterCasbin) createTable() (err error) { + return +} + +// LoadPolicy loads policy from database. +func (a *adapterCasbin) LoadPolicy(model model.Model) error { + var lines []*entity.CasbinRule + if err := dao.CasbinRule.Ctx(a.ctx).Scan(&lines); err != nil { + return err + } + for _, line := range lines { + loadPolicyLine(line, model) + } + return nil +} + +// AddPolicy adds a policy rule to the storage. +func (a *adapterCasbin) AddPolicy(sec string, ptype string, rule []string) error { + line := savePolicyLine(ptype, rule) + _, err := dao.CasbinRule.Ctx(a.ctx).Data(line).Insert() + return err +} + +// RemovePolicy removes a policy rule from the storage. +func (a *adapterCasbin) RemovePolicy(sec string, ptype string, rule []string) error { + line := savePolicyLine(ptype, rule) + err := rawDelete(a, line) + return err +} + +// RemoveFilteredPolicy removes policy rules that match the filter from the storage. +func (a *adapterCasbin) RemoveFilteredPolicy(sec string, ptype string, + fieldIndex int, fieldValues ...string) error { + line := &entity.CasbinRule{} + line.Ptype = ptype + if fieldIndex <= 0 && 0 < fieldIndex+len(fieldValues) { + line.V0 = fieldValues[0-fieldIndex] + } + if fieldIndex <= 1 && 1 < fieldIndex+len(fieldValues) { + line.V1 = fieldValues[1-fieldIndex] + } + if fieldIndex <= 2 && 2 < fieldIndex+len(fieldValues) { + line.V2 = fieldValues[2-fieldIndex] + } + if fieldIndex <= 3 && 3 < fieldIndex+len(fieldValues) { + line.V3 = fieldValues[3-fieldIndex] + } + if fieldIndex <= 4 && 4 < fieldIndex+len(fieldValues) { + line.V4 = fieldValues[4-fieldIndex] + } + if fieldIndex <= 5 && 5 < fieldIndex+len(fieldValues) { + line.V5 = fieldValues[5-fieldIndex] + } + err := rawDelete(a, line) + return err +} + +func loadPolicyLine(line *entity.CasbinRule, model model.Model) { + lineText := line.Ptype + if line.V0 != "" { + lineText += ", " + line.V0 + } + if line.V1 != "" { + lineText += ", " + line.V1 + } + if line.V2 != "" { + lineText += ", " + line.V2 + } + if line.V3 != "" { + lineText += ", " + line.V3 + } + if line.V4 != "" { + lineText += ", " + line.V4 + } + if line.V5 != "" { + lineText += ", " + line.V5 + } + persist.LoadPolicyLine(lineText, model) +} + +func savePolicyLine(ptype string, rule []string) *entity.CasbinRule { + line := &entity.CasbinRule{} + line.Ptype = ptype + if len(rule) > 0 { + line.V0 = rule[0] + } + if len(rule) > 1 { + line.V1 = rule[1] + } + if len(rule) > 2 { + line.V2 = rule[2] + } + if len(rule) > 3 { + line.V3 = rule[3] + } + if len(rule) > 4 { + line.V4 = rule[4] + } + if len(rule) > 5 { + line.V5 = rule[5] + } + return line +} + +func rawDelete(a *adapterCasbin, line *entity.CasbinRule) error { + db := dao.CasbinRule.Ctx(a.ctx).Where("ptype = ?", line.Ptype) + if line.V0 != "" { + db = db.Where("v0 = ?", line.V0) + } + if line.V1 != "" { + db = db.Where("v1 = ?", line.V1) + } + if line.V2 != "" { + db = db.Where("v2 = ?", line.V2) + } + if line.V3 != "" { + db = db.Where("v3 = ?", line.V3) + } + if line.V4 != "" { + db = db.Where("v4 = ?", line.V4) + } + if line.V5 != "" { + db = db.Where("v5 = ?", line.V5) + } + _, err := db.Delete() + return err +} diff --git a/internal/service/context.go b/internal/service/context.go new file mode 100644 index 0000000..443dd89 --- /dev/null +++ b/internal/service/context.go @@ -0,0 +1,72 @@ +/* +* @desc:context-service +* @company:云南奇讯科技有限公司 +* @Author: yixiaohu +* @Date: 2022/3/16 14:46 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/net/ghttp" + "tyj_admin/internal/consts" + "tyj_admin/internal/model" +) + +type IContext interface { + Init(r *ghttp.Request, customCtx *model.Context) + Get(ctx context.Context) *model.Context + SetUser(ctx context.Context, ctxUser *model.ContextUser) + GetLoginUser(ctx context.Context) *model.ContextUser + GetUserId(ctx context.Context) uint64 +} + +// Context 上下文管理服务 +var contextService = contextServiceImpl{} + +type contextServiceImpl struct{} + +func Context() IContext { + return &contextService +} + +// Init 初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改。 +func (s *contextServiceImpl) Init(r *ghttp.Request, customCtx *model.Context) { + r.SetCtxVar(consts.CtxKey, customCtx) +} + +// Get 获得上下文变量,如果没有设置,那么返回nil +func (s *contextServiceImpl) Get(ctx context.Context) *model.Context { + value := ctx.Value(consts.CtxKey) + if value == nil { + return nil + } + if localCtx, ok := value.(*model.Context); ok { + return localCtx + } + return nil +} + +// SetUser 将上下文信息设置到上下文请求中,注意是完整覆盖 +func (s *contextServiceImpl) SetUser(ctx context.Context, ctxUser *model.ContextUser) { + s.Get(ctx).User = ctxUser +} + +// GetLoginUser 获取当前登陆用户信息 +func (s *contextServiceImpl) GetLoginUser(ctx context.Context) *model.ContextUser { + context := s.Get(ctx) + if context == nil { + return nil + } + return context.User +} + +// GetUserId 获取当前登录用户id +func (s *contextServiceImpl) GetUserId(ctx context.Context) uint64 { + user := s.GetLoginUser(ctx) + if user != nil { + return user.Id + } + return 0 +} diff --git a/internal/service/middleware.go b/internal/service/middleware.go new file mode 100644 index 0000000..2339b4f --- /dev/null +++ b/internal/service/middleware.go @@ -0,0 +1,137 @@ +/* +* @desc:中间件处理 +* +* +* @Date: 2022/3/17 9:11 + */ + +package service + +import ( + "fmt" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/internal/model" + "tyj_admin/library/libResponse" +) + +type IMiddleware interface { + MiddlewareCORS(r *ghttp.Request) + Ctx(r *ghttp.Request) + Auth(r *ghttp.Request) +} + +type middlewareImpl struct{} + +var middleService = middlewareImpl{} + +func Middleware() IMiddleware { + return &middleService +} + +func (s *middlewareImpl) MiddlewareCORS(r *ghttp.Request) { + corsOptions := r.Response.DefaultCORSOptions() + // you can set options + //corsOptions.AllowDomain = []string{"goframe.org", "baidu.com"} + r.Response.CORS(corsOptions) + r.Middleware.Next() +} + +// Ctx 自定义上下文对象 +func (s *middlewareImpl) Ctx(r *ghttp.Request) { + ctx := r.GetCtx() + // 初始化登录用户信息 + data, err := SysGfToken().ParseToken(r) + if err != nil { + // 执行下一步请求逻辑 + r.Middleware.Next() + } + if data != nil { + context := new(model.Context) + err = gconv.Struct(data.Data, &context.User) + if err != nil { + g.Log().Error(ctx, err) + // 执行下一步请求逻辑 + r.Middleware.Next() + } + Context().Init(r, context) + } + // 执行下一步请求逻辑 + r.Middleware.Next() +} + +// Auth 权限判断处理中间件 +func (s *middlewareImpl) Auth(r *ghttp.Request) { + ctx := r.GetCtx() + //获取登陆用户id + adminId := Context().GetUserId(ctx) + accessParams := r.Get("accessParams").Strings() + accessParamsStr := "" + if len(accessParams) > 0 && accessParams[0] != "undefined" { + accessParamsStr = "?" + gstr.Join(accessParams, "&") + } + url := gstr.TrimLeft(r.Request.URL.Path, "/") + accessParamsStr + /*if r.Method != "GET" && adminId != 1 && url!="api/v1/system/login" { + libResponse.FailJson(true, r, "对不起!演示系统,不能删改数据!") + }*/ + //获取无需验证权限的用户id + tagSuperAdmin := false + User().NotCheckAuthAdminIds(ctx).Iterator(func(v interface{}) bool { + if gconv.Uint64(v) == adminId { + tagSuperAdmin = true + return false + } + return true + }) + if tagSuperAdmin { + r.Middleware.Next() + //不要再往后面执行 + return + } + //获取地址对应的菜单id + menuList, err := Rule().GetMenuList(ctx) + if err != nil { + g.Log().Error(ctx, err) + libResponse.FailJson(true, r, "请求数据失败") + } + var menu *model.SysAuthRuleInfoRes + for _, m := range menuList { + ms := gstr.SubStr(m.Name, 0, gstr.Pos(m.Name, "?")) + if m.Name == url || ms == url { + menu = m + break + } + } + //只验证存在数据库中的规则 + if menu != nil { + //若存在不需要验证的条件则跳过 + if gstr.Equal(menu.Condition, "nocheck") { + r.Middleware.Next() + return + } + menuId := menu.Id + //菜单没存数据库不验证权限 + if menuId != 0 { + //判断权限操作 + enforcer, err := CasbinEnforcer(ctx) + if err != nil { + g.Log().Error(ctx, err) + libResponse.FailJson(true, r, "获取权限失败") + } + hasAccess := false + hasAccess, err = enforcer.Enforce(fmt.Sprintf("%s%d", userService.CasBinUserPrefix, adminId), gconv.String(menuId), "All") + if err != nil { + g.Log().Error(ctx, err) + libResponse.FailJson(true, r, "判断权限失败") + } + if !hasAccess { + libResponse.FailJson(true, r, "没有访问权限") + } + } + } else if menu == nil && accessParamsStr != "" { + libResponse.FailJson(true, r, "没有访问权限") + } + r.Middleware.Next() +} diff --git a/internal/service/sys_auth_rule.go b/internal/service/sys_auth_rule.go new file mode 100644 index 0000000..c3a18c6 --- /dev/null +++ b/internal/service/sys_auth_rule.go @@ -0,0 +1,325 @@ +/* +* @desc:菜单处理 +* +* +* @Date: 2022/3/11 15:07 + */ + +package service + +import ( + "context" + "fmt" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model" + "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" + "tyj_admin/library/liberr" +) + +type IRule interface { + GetIsMenuList(ctx context.Context) ([]*model.SysAuthRuleInfoRes, error) + GetMenuList(ctx context.Context) (list []*model.SysAuthRuleInfoRes, err error) + GetIsButtonList(ctx context.Context) ([]*model.SysAuthRuleInfoRes, error) + Add(ctx context.Context, req *system.RuleAddReq) (err error) + Get(ctx context.Context, id uint) (rule *entity.SysAuthRule, err error) + GetMenuRoles(ctx context.Context, id uint) (roleIds []uint, err error) + Update(ctx context.Context, req *system.RuleUpdateReq) (err error) + GetMenuListSearch(ctx context.Context, req *system.RuleSearchReq) (res []*model.SysAuthRuleInfoRes, err error) + GetMenuListTree(pid uint, list []*model.SysAuthRuleInfoRes) []*model.SysAuthRuleTreeRes + DeleteMenuByIds(ctx context.Context, ids []int) (err error) +} + +type ruleImpl struct { +} + +var ruleService = ruleImpl{} + +func Rule() IRule { + return &ruleService +} + +func (s *ruleImpl) GetMenuListSearch(ctx context.Context, req *system.RuleSearchReq) (res []*model.SysAuthRuleInfoRes, err error) { + err = g.Try(ctx, func(ctx context.Context) { + m := dao.SysAuthRule.Ctx(ctx) + if req.Title != "" { + m = m.Where("title like ?", "%"+req.Title+"%") + } + if req.Component != "" { + m = m.Where("component like ?", "%"+req.Component+"%") + } + err = m.Fields(model.SysAuthRuleInfoRes{}).Order("weigh desc,id asc").Scan(&res) + liberr.ErrIsNil(ctx, err, "获取菜单失败") + }) + return +} + +// GetIsMenuList 获取isMenu=0|1 +func (s *ruleImpl) GetIsMenuList(ctx context.Context) ([]*model.SysAuthRuleInfoRes, error) { + list, err := s.GetMenuList(ctx) + if err != nil { + return nil, err + } + var gList = make([]*model.SysAuthRuleInfoRes, 0, len(list)) + for _, v := range list { + if v.MenuType == 0 || v.MenuType == 1 { + gList = append(gList, v) + } + } + return gList, nil +} + +// GetMenuList 获取所有菜单 +func (s *ruleImpl) GetMenuList(ctx context.Context) (list []*model.SysAuthRuleInfoRes, err error) { + cache := Cache() + //从缓存获取 + iList := cache.GetOrSetFuncLock(ctx, consts.CacheSysAuthMenu, s.getMenuListFromDb, 0, consts.CacheSysAuthTag) + if iList != nil { + err = gconv.Struct(iList, &list) + liberr.ErrIsNil(ctx, err) + } + return +} + +// 从数据库获取所有菜单 +func (s *ruleImpl) getMenuListFromDb(ctx context.Context) (value interface{}, err error) { + err = g.Try(ctx, func(ctx context.Context) { + var v []*model.SysAuthRuleInfoRes + //从数据库获取 + err = dao.SysAuthRule.Ctx(ctx). + Fields(model.SysAuthRuleInfoRes{}).Order("weigh desc,id asc").Scan(&v) + liberr.ErrIsNil(ctx, err, "获取菜单数据失败") + value = v + }) + return +} + +// GetIsButtonList 获取所有按钮isMenu=2 菜单列表 +func (s *ruleImpl) GetIsButtonList(ctx context.Context) ([]*model.SysAuthRuleInfoRes, error) { + list, err := s.GetMenuList(ctx) + if err != nil { + return nil, err + } + var gList = make([]*model.SysAuthRuleInfoRes, 0, len(list)) + for _, v := range list { + if v.MenuType == 2 { + gList = append(gList, v) + } + } + return gList, nil +} + +// Add 添加菜单 +func (s *ruleImpl) Add(ctx context.Context, req *system.RuleAddReq) (err error) { + if s.menuNameExists(ctx, req.Name, 0) { + err = gerror.New("接口规则已经存在") + return + } + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + //菜单数据 + data := do.SysAuthRule{ + Pid: req.Pid, + Name: req.Name, + Title: req.Title, + Icon: req.Icon, + Condition: req.Condition, + Remark: req.Remark, + MenuType: req.MenuType, + Weigh: req.Weigh, + IsHide: req.IsHide, + Path: req.Path, + Component: req.Component, + IsLink: req.IsLink, + IsIframe: req.IsIframe, + IsCached: req.IsCached, + Redirect: req.Redirect, + IsAffix: req.IsAffix, + LinkUrl: req.LinkUrl, + } + ruleId, e := dao.SysAuthRule.Ctx(ctx).TX(tx).InsertAndGetId(data) + liberr.ErrIsNil(ctx, e, "添加菜单失败") + e = s.BindRoleRule(ctx, ruleId, req.Roles) + liberr.ErrIsNil(ctx, e, "添加菜单失败") + }) + return err + }) + if err == nil { + // 删除相关缓存 + Cache().Remove(ctx, consts.CacheSysAuthMenu) + } + return +} + +// 检查菜单规则是否存在 +func (s *ruleImpl) menuNameExists(ctx context.Context, name string, id uint) bool { + m := dao.SysAuthRule.Ctx(ctx).Where("name=?", name) + if id != 0 { + m = m.Where("id!=?", id) + } + c, err := m.Fields(dao.SysAuthRule.Columns().Id).Limit(1).One() + if err != nil { + g.Log().Error(ctx, err) + return false + } + return !c.IsEmpty() +} + +// BindRoleRule 绑定角色权限 +func (s *ruleImpl) BindRoleRule(ctx context.Context, ruleId interface{}, roleIds []uint) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + for _, roleId := range roleIds { + _, err = enforcer.AddPolicy(fmt.Sprintf("%d", roleId), fmt.Sprintf("%d", ruleId), "All") + liberr.ErrIsNil(ctx, err) + } + }) + return +} + +func (s *ruleImpl) Get(ctx context.Context, id uint) (rule *entity.SysAuthRule, err error) { + err = g.Try(ctx, func(ctx context.Context) { + err = dao.SysAuthRule.Ctx(ctx).WherePri(id).Scan(&rule) + liberr.ErrIsNil(ctx, err, "获取菜单失败") + }) + return +} + +func (s *ruleImpl) GetMenuRoles(ctx context.Context, id uint) (roleIds []uint, err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + policies := enforcer.GetFilteredNamedPolicy("p", 1, gconv.String(id)) + for _, policy := range policies { + roleIds = append(roleIds, gconv.Uint(policy[0])) + } + }) + return +} + +func (s *ruleImpl) Update(ctx context.Context, req *system.RuleUpdateReq) (err error) { + if s.menuNameExists(ctx, req.Name, req.Id) { + err = gerror.New("接口规则已经存在") + return + } + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + //菜单数据 + data := do.SysAuthRule{ + Pid: req.Pid, + Name: req.Name, + Title: req.Title, + Icon: req.Icon, + Condition: req.Condition, + Remark: req.Remark, + MenuType: req.MenuType, + Weigh: req.Weigh, + IsHide: req.IsHide, + Path: req.Path, + Component: req.Component, + IsLink: req.IsLink, + IsIframe: req.IsIframe, + IsCached: req.IsCached, + Redirect: req.Redirect, + IsAffix: req.IsAffix, + LinkUrl: req.LinkUrl, + } + _, e := dao.SysAuthRule.Ctx(ctx).TX(tx).WherePri(req.Id).Update(data) + liberr.ErrIsNil(ctx, e, "添加菜单失败") + e = s.UpdateRoleRule(ctx, req.Id, req.Roles) + liberr.ErrIsNil(ctx, e, "添加菜单失败") + }) + return err + }) + if err == nil { + // 删除相关缓存 + Cache().Remove(ctx, consts.CacheSysAuthMenu) + } + return +} + +func (s *ruleImpl) UpdateRoleRule(ctx context.Context, ruleId uint, roleIds []uint) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + //删除旧权限 + _, e = enforcer.RemoveFilteredPolicy(1, gconv.String(ruleId)) + liberr.ErrIsNil(ctx, e) + // 添加新权限 + roleIdsStrArr := gconv.Strings(roleIds) + for _, v := range roleIdsStrArr { + _, e = enforcer.AddPolicy(v, gconv.String(ruleId), "All") + liberr.ErrIsNil(ctx, e) + } + }) + return +} + +func (s *ruleImpl) GetMenuListTree(pid uint, list []*model.SysAuthRuleInfoRes) []*model.SysAuthRuleTreeRes { + tree := make([]*model.SysAuthRuleTreeRes, 0, len(list)) + for _, menu := range list { + if menu.Pid == pid { + t := &model.SysAuthRuleTreeRes{ + SysAuthRuleInfoRes: menu, + } + child := s.GetMenuListTree(menu.Id, list) + if child != nil { + t.Children = child + } + tree = append(tree, t) + } + } + return tree +} + +// DeleteMenuByIds 删除菜单 +func (s *ruleImpl) DeleteMenuByIds(ctx context.Context, ids []int) (err error) { + var list []*model.SysAuthRuleInfoRes + list, err = s.GetMenuList(ctx) + if err != nil { + return + } + childrenIds := make([]int, 0, len(list)) + for _, id := range ids { + rules := s.FindSonByParentId(list, gconv.Uint(id)) + for _, child := range rules { + childrenIds = append(childrenIds, gconv.Int(child.Id)) + } + } + ids = append(ids, childrenIds...) + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + return g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysAuthRule.Ctx(ctx).Where("id in (?)", ids).Delete() + liberr.ErrIsNil(ctx, err, "删除失败") + //删除权限 + enforcer, err := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, err) + for _, v := range ids { + _, err = enforcer.RemoveFilteredPolicy(1, gconv.String(v)) + liberr.ErrIsNil(ctx, err) + } + // 删除相关缓存 + Cache().Remove(ctx, consts.CacheSysAuthMenu) + }) + }) + return +} + +func (s *ruleImpl) FindSonByParentId(list []*model.SysAuthRuleInfoRes, pid uint) []*model.SysAuthRuleInfoRes { + children := make([]*model.SysAuthRuleInfoRes, 0, len(list)) + for _, v := range list { + if v.Pid == pid { + children = append(children, v) + fChildren := s.FindSonByParentId(list, v.Id) + children = append(children, fChildren...) + } + } + return children +} diff --git a/internal/service/sys_config.go b/internal/service/sys_config.go new file mode 100644 index 0000000..bf8a61b --- /dev/null +++ b/internal/service/sys_config.go @@ -0,0 +1,184 @@ +/* +* @desc:系统参数配置 +* +* +* @Date: 2022/3/18 11:55 + */ + +package service + +import ( + "context" + "errors" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" + "tyj_admin/library/liberr" +) + +type IConfig interface { + List(ctx context.Context, req *system.ConfigSearchReq) (res *system.ConfigSearchRes, err error) + Add(ctx context.Context, req *system.ConfigAddReq, userId uint64) (err error) + Get(ctx context.Context, id int) (res *system.ConfigGetRes, err error) + Edit(ctx context.Context, req *system.ConfigEditReq, userId uint64) (err error) + Delete(ctx context.Context, ids []int) (err error) + GetConfigByKey(ctx context.Context, key string) (config *entity.SysConfig, err error) + GetByKey(ctx context.Context, key string) (config *entity.SysConfig, err error) +} + +type configTmpl struct { +} + +var configService = configTmpl{} + +func Config() IConfig { + return &configService +} + +// List 系统参数列表 +func (s *configTmpl) List(ctx context.Context, req *system.ConfigSearchReq) (res *system.ConfigSearchRes, err error) { + res = new(system.ConfigSearchRes) + err = g.Try(ctx, func(ctx context.Context) { + m := dao.SysConfig.Ctx(ctx) + if req != nil { + if req.ConfigName != "" { + m = m.Where("config_name like ?", "%"+req.ConfigName+"%") + } + if req.ConfigType != "" { + m = m.Where("config_type = ", gconv.Int(req.ConfigType)) + } + if req.ConfigKey != "" { + m = m.Where("config_key like ?", "%"+req.ConfigKey+"%") + } + if len(req.DateRange) > 0 { + m = m.Where("created_at >= ? AND created_at<=?", req.DateRange[0], req.DateRange[1]) + } + } + res.Total, err = m.Count() + liberr.ErrIsNil(ctx, err, "获取数据失败") + if req.PageNum == 0 { + req.PageNum = 1 + } + res.CurrentPage = req.PageNum + if req.PageSize == 0 { + req.PageSize = consts.PageSize + } + err = m.Page(req.PageNum, req.PageSize).Order("config_id asc").Scan(&res.List) + liberr.ErrIsNil(ctx, err, "获取数据失败") + }) + return +} + +func (s *configTmpl) Add(ctx context.Context, req *system.ConfigAddReq, userId uint64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + err = s.CheckConfigKeyUnique(ctx, req.ConfigKey) + liberr.ErrIsNil(ctx, err) + _, err = dao.SysConfig.Ctx(ctx).Insert(do.SysConfig{ + ConfigName: req.ConfigName, + ConfigKey: req.ConfigKey, + ConfigValue: req.ConfigValue, + ConfigType: req.ConfigType, + CreateBy: userId, + Remark: req.Remark, + }) + liberr.ErrIsNil(ctx, err, "添加系统参数失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysConfigTag) + }) + return +} + +// CheckConfigKeyUnique 验证参数键名是否存在 +func (s *configTmpl) CheckConfigKeyUnique(ctx context.Context, configKey string, configId ...int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + data := (*entity.SysConfig)(nil) + m := dao.SysConfig.Ctx(ctx).Fields(dao.SysConfig.Columns().ConfigId).Where(dao.SysConfig.Columns().ConfigKey, configKey) + if len(configId) > 0 { + m = m.Where(dao.SysConfig.Columns().ConfigId+" != ?", configId[0]) + } + err = m.Scan(&data) + liberr.ErrIsNil(ctx, err, "校验失败") + if data != nil { + liberr.ErrIsNil(ctx, errors.New("参数键名重复")) + } + }) + return +} + +// Get 获取系统参数 +func (s *configTmpl) Get(ctx context.Context, id int) (res *system.ConfigGetRes, err error) { + res = new(system.ConfigGetRes) + err = g.Try(ctx, func(ctx context.Context) { + err = dao.SysConfig.Ctx(ctx).WherePri(id).Scan(&res.Data) + liberr.ErrIsNil(ctx, err, "获取系统参数失败") + }) + return +} + +// Edit 修改系统参数 +func (s *configTmpl) Edit(ctx context.Context, req *system.ConfigEditReq, userId uint64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + err = s.CheckConfigKeyUnique(ctx, req.ConfigKey, req.ConfigId) + liberr.ErrIsNil(ctx, err) + _, err = dao.SysConfig.Ctx(ctx).WherePri(req.ConfigId).Update(do.SysConfig{ + ConfigName: req.ConfigName, + ConfigKey: req.ConfigKey, + ConfigValue: req.ConfigValue, + ConfigType: req.ConfigType, + UpdateBy: userId, + Remark: req.Remark, + }) + liberr.ErrIsNil(ctx, err, "修改系统参数失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysConfigTag) + }) + return +} + +// Delete 删除系统参数 +func (s *configTmpl) Delete(ctx context.Context, ids []int) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysConfig.Ctx(ctx).Delete(dao.SysConfig.Columns().ConfigId+" in (?)", ids) + liberr.ErrIsNil(ctx, err, "删除失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysConfigTag) + }) + return +} + +// GetConfigByKey 通过key获取参数(从缓存获取) +func (s *configTmpl) GetConfigByKey(ctx context.Context, key string) (config *entity.SysConfig, err error) { + if key == "" { + err = gerror.New("参数key不能为空") + return + } + cache := Cache() + cf := cache.Get(ctx, consts.CacheSysConfigTag+key) + if cf != nil && !cf.IsEmpty() { + err = gconv.Struct(cf, &config) + return + } + config, err = s.GetByKey(ctx, key) + if err != nil { + return + } + if config != nil { + cache.Set(ctx, consts.CacheSysConfigTag+key, config, 0, consts.CacheSysConfigTag) + } + return +} + +// GetByKey 通过key获取参数(从数据库获取) +func (s *configTmpl) GetByKey(ctx context.Context, key string) (config *entity.SysConfig, err error) { + err = dao.SysConfig.Ctx(ctx).Where("config_key", key).Scan(&config) + if err != nil { + g.Log().Error(ctx, err) + err = gerror.New("获取配置失败") + } + return +} diff --git a/internal/service/sys_dept.go b/internal/service/sys_dept.go new file mode 100644 index 0000000..c20e0aa --- /dev/null +++ b/internal/service/sys_dept.go @@ -0,0 +1,169 @@ +/* +* @desc:部门管理 +* +* +* @Date: 2022/4/6 15:19 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model" + "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" + "tyj_admin/library/liberr" +) + +type IDept interface { + GetList(ctx context.Context, req *system.DeptSearchReq) (list []*entity.SysDept, err error) + Add(ctx context.Context, req *system.DeptAddReq) (err error) + Edit(ctx context.Context, req *system.DeptEditReq) (err error) + GetFromCache(ctx context.Context) (list []*entity.SysDept, err error) + Delete(ctx context.Context, id int64) (err error) + GetListTree(pid int64, list []*entity.SysDept) (deptTree []*model.SysDeptTreeRes) + FindSonByParentId(deptList []*entity.SysDept, deptId int64) []*entity.SysDept +} + +var deptService = deptImpl{} + +func Dept() IDept { + return &deptService +} + +type deptImpl struct { +} + +func (s *deptImpl) GetList(ctx context.Context, req *system.DeptSearchReq) (list []*entity.SysDept, err error) { + list, err = s.GetFromCache(ctx) + if err != nil { + return + } + rList := make([]*entity.SysDept, 0, len(list)) + if req.DeptName != "" || req.Status != "" { + for _, v := range list { + if req.DeptName != "" && !gstr.ContainsI(v.DeptName, req.DeptName) { + continue + } + if req.Status != "" && v.Status != gconv.Uint(req.Status) { + continue + } + rList = append(rList, v) + } + list = rList + } + return +} + +func (s *deptImpl) GetFromCache(ctx context.Context) (list []*entity.SysDept, err error) { + err = g.Try(ctx, func(ctx context.Context) { + cache := Cache() + //从缓存获取 + iList := cache.GetOrSetFuncLock(ctx, consts.CacheSysDept, func(ctx context.Context) (value interface{}, err error) { + err = dao.SysDept.Ctx(ctx).Scan(&list) + liberr.ErrIsNil(ctx, err, "获取部门列表失败") + value = list + return + }, 0, consts.CacheSysAuthTag) + if iList != nil { + err = gconv.Struct(iList, &list) + liberr.ErrIsNil(ctx, err) + } + }) + return +} + +// Add 添加部门 +func (s *deptImpl) Add(ctx context.Context, req *system.DeptAddReq) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysDept.Ctx(ctx).Insert(do.SysDept{ + ParentId: req.ParentID, + DeptName: req.DeptName, + OrderNum: req.OrderNum, + Leader: req.Leader, + Phone: req.Phone, + Email: req.Email, + Status: req.Status, + CreatedBy: Context().GetUserId(ctx), + }) + liberr.ErrIsNil(ctx, err, "添加部门失败") + // 删除缓存 + Cache().Remove(ctx, consts.CacheSysDept) + }) + return +} + +// Edit 部门修改 +func (s *deptImpl) Edit(ctx context.Context, req *system.DeptEditReq) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysDept.Ctx(ctx).WherePri(req.DeptId).Update(do.SysDept{ + ParentId: req.ParentID, + DeptName: req.DeptName, + OrderNum: req.OrderNum, + Leader: req.Leader, + Phone: req.Phone, + Email: req.Email, + Status: req.Status, + UpdatedBy: Context().GetUserId(ctx), + }) + liberr.ErrIsNil(ctx, err, "修改部门失败") + // 删除缓存 + Cache().Remove(ctx, consts.CacheSysDept) + }) + return +} + +func (s *deptImpl) Delete(ctx context.Context, id int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + var list []*entity.SysDept + err = dao.SysDept.Ctx(ctx).Scan(&list) + liberr.ErrIsNil(ctx, err, "不存在部门信息") + children := s.FindSonByParentId(list, id) + ids := make([]int64, 0, len(list)) + for _, v := range children { + ids = append(ids, v.DeptId) + } + ids = append(ids, id) + _, err = dao.SysDept.Ctx(ctx).Where(dao.SysDept.Columns().DeptId+" in (?)", ids).Delete() + liberr.ErrIsNil(ctx, err, "删除部门失败") + // 删除缓存 + Cache().Remove(ctx, consts.CacheSysDept) + }) + return +} + +func (s *deptImpl) FindSonByParentId(deptList []*entity.SysDept, deptId int64) []*entity.SysDept { + children := make([]*entity.SysDept, 0, len(deptList)) + for _, v := range deptList { + if v.ParentId == deptId { + children = append(children, v) + fChildren := s.FindSonByParentId(deptList, v.DeptId) + children = append(children, fChildren...) + } + } + return children +} + +// GetListTree 部门树形菜单 +func (s *deptImpl) GetListTree(pid int64, list []*entity.SysDept) (deptTree []*model.SysDeptTreeRes) { + deptTree = make([]*model.SysDeptTreeRes, 0, len(list)) + for _, v := range list { + if v.ParentId == pid { + t := &model.SysDeptTreeRes{ + SysDept: v, + } + child := s.GetListTree(v.DeptId, list) + if len(child) > 0 { + t.Children = child + } + deptTree = append(deptTree, t) + } + } + return +} diff --git a/internal/service/sys_dict_data.go b/internal/service/sys_dict_data.go new file mode 100644 index 0000000..cc4424b --- /dev/null +++ b/internal/service/sys_dict_data.go @@ -0,0 +1,178 @@ +/* +* @desc:字典数据 +* +* +* @Date: 2022/3/18 11:55 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model" + "tyj_admin/internal/model/do" + "tyj_admin/library/liberr" +) + +type IDictData interface { + GetDictWithDataByType(ctx context.Context, req *system.GetDictReq) (dict *system.GetDictRes, err error) + List(ctx context.Context, req *system.DictDataSearchReq) (res *system.DictDataSearchRes, err error) + Add(ctx context.Context, req *system.DictDataAddReq, userId uint64) (err error) + Get(ctx context.Context, dictCode uint) (res *system.DictDataGetRes, err error) + Edit(ctx context.Context, req *system.DictDataEditReq, userId uint64) (err error) + Delete(ctx context.Context, ids []int) (err error) +} + +type dictDataImpl struct { +} + +var dictData = dictDataImpl{} + +func DictData() IDictData { + return &dictData +} + +// GetDictWithDataByType 通过字典键类型获取选项 +func (s dictDataImpl) GetDictWithDataByType(ctx context.Context, req *system.GetDictReq) (dict *system.GetDictRes, + err error) { + cache := Cache() + cacheKey := consts.CacheSysDict + "_" + req.DictType + //从缓存获取 + iDict := cache.GetOrSetFuncLock(ctx, cacheKey, func(ctx context.Context) (value interface{}, err error) { + err = g.Try(ctx, func(ctx context.Context) { + //从数据库获取 + dict = &system.GetDictRes{} + //获取类型数据 + err = dao.SysDictType.Ctx(ctx).Where(dao.SysDictType.Columns().DictType, req.DictType). + Where(dao.SysDictType.Columns().Status, 1).Fields(model.DictTypeRes{}).Scan(&dict.Info) + liberr.ErrIsNil(ctx, err, "获取字典类型失败") + err = dao.SysDictData.Ctx(ctx).Fields(model.DictDataRes{}). + Where(dao.SysDictData.Columns().DictType, req.DictType). + Order(dao.SysDictData.Columns().DictSort + " asc," + + dao.SysDictData.Columns().DictCode + " asc"). + Scan(&dict.Values) + liberr.ErrIsNil(ctx, err, "获取字典数据失败") + }) + value = dict + return + }, 0, consts.CacheSysDictTag) + if iDict != nil { + err = gconv.Struct(iDict, &dict) + if err != nil { + return + } + } + //设置给定的默认值 + for _, v := range dict.Values { + if req.DefaultValue != "" { + if gstr.Equal(req.DefaultValue, v.DictValue) { + v.IsDefault = 1 + } else { + v.IsDefault = 0 + } + } + } + return +} + +// List 获取字典数据 +func (s dictDataImpl) List(ctx context.Context, req *system.DictDataSearchReq) (res *system.DictDataSearchRes, err error) { + res = new(system.DictDataSearchRes) + err = g.Try(ctx, func(ctx context.Context) { + m := dao.SysDictData.Ctx(ctx) + if req != nil { + if req.DictLabel != "" { + m = m.Where(dao.SysDictData.Columns().DictLabel+" like ?", "%"+req.DictLabel+"%") + } + if req.Status != "" { + m = m.Where(dao.SysDictData.Columns().Status+" = ", gconv.Int(req.Status)) + } + if req.DictType != "" { + m = m.Where(dao.SysDictData.Columns().DictType+" = ?", req.DictType) + } + res.Total, err = m.Count() + liberr.ErrIsNil(ctx, err, "获取字典数据失败") + if req.PageNum == 0 { + req.PageNum = 1 + } + res.CurrentPage = req.PageNum + } + if req.PageSize == 0 { + req.PageSize = consts.PageSize + } + err = m.Page(req.PageNum, req.PageSize).Order(dao.SysDictData.Columns().DictSort + " asc," + + dao.SysDictData.Columns().DictCode + " asc").Scan(&res.List) + liberr.ErrIsNil(ctx, err, "获取字典数据失败") + }) + return +} + +func (s *dictDataImpl) Add(ctx context.Context, req *system.DictDataAddReq, userId uint64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysDictData.Ctx(ctx).Insert(do.SysDictData{ + DictSort: req.DictSort, + DictLabel: req.DictLabel, + DictValue: req.DictValue, + DictType: req.DictType, + CssClass: req.CssClass, + ListClass: req.ListClass, + IsDefault: req.IsDefault, + Status: req.Status, + CreateBy: userId, + Remark: req.Remark, + }) + liberr.ErrIsNil(ctx, err, "添加字典数据失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysDictTag) + }) + return +} + +// Get 获取字典数据 +func (s *dictDataImpl) Get(ctx context.Context, dictCode uint) (res *system.DictDataGetRes, err error) { + res = new(system.DictDataGetRes) + err = g.Try(ctx, func(ctx context.Context) { + err = dao.SysDictData.Ctx(ctx).WherePri(dictCode).Scan(&res.Dict) + liberr.ErrIsNil(ctx, err, "获取字典数据失败") + }) + return +} + +// Edit 修改字典数据 +func (s *dictDataImpl) Edit(ctx context.Context, req *system.DictDataEditReq, userId uint64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysDictData.Ctx(ctx).WherePri(req.DictCode).Update(do.SysDictData{ + DictSort: req.DictSort, + DictLabel: req.DictLabel, + DictValue: req.DictValue, + DictType: req.DictType, + CssClass: req.CssClass, + ListClass: req.ListClass, + IsDefault: req.IsDefault, + Status: req.Status, + UpdateBy: userId, + Remark: req.Remark, + }) + liberr.ErrIsNil(ctx, err, "修改字典数据失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysDictTag) + }) + return +} + +// Delete 删除字典数据 +func (s *dictDataImpl) Delete(ctx context.Context, ids []int) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysDictData.Ctx(ctx).Where(dao.SysDictData.Columns().DictCode+" in(?)", ids).Delete() + liberr.ErrIsNil(ctx, err, "删除字典数据失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysDictTag) + }) + return +} diff --git a/internal/service/sys_dict_type.go b/internal/service/sys_dict_type.go new file mode 100644 index 0000000..c1adcbb --- /dev/null +++ b/internal/service/sys_dict_type.go @@ -0,0 +1,172 @@ +/* +* @desc:字典类型 +* +* +* @Date: 2022/3/18 11:55 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/container/garray" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model" + "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" + "tyj_admin/library/liberr" +) + +type IDictType interface { + List(ctx context.Context, req *system.DictTypeSearchReq) (res *system.DictTypeSearchRes, err error) + Add(ctx context.Context, req *system.DictTypeAddReq, userId uint64) (err error) + Get(ctx context.Context, req *system.DictTypeGetReq) (dictType *entity.SysDictType, err error) + Edit(ctx context.Context, req *system.DictTypeEditReq, userId uint64) (err error) + Delete(ctx context.Context, dictIds []int) (err error) +} + +type dictTypeImpl struct { +} + +var dictTypeService = dictTypeImpl{} + +func DictType() IDictType { + return &dictTypeService +} + +// List 字典类型列表 +func (s *dictTypeImpl) List(ctx context.Context, req *system.DictTypeSearchReq) (res *system.DictTypeSearchRes, err error) { + res = new(system.DictTypeSearchRes) + err = g.Try(ctx, func(ctx context.Context) { + m := dao.SysDictType.Ctx(ctx) + if req.DictName != "" { + m = m.Where(dao.SysDictType.Columns().DictName+" like ?", "%"+req.DictName+"%") + } + if req.DictType != "" { + m = m.Where(dao.SysDictType.Columns().DictType+" like ?", "%"+req.DictType+"%") + } + if req.Status != "" { + m = m.Where(dao.SysDictType.Columns().Status+" = ", gconv.Int(req.Status)) + } + res.Total, err = m.Count() + liberr.ErrIsNil(ctx, err, "获取字典类型失败") + if req.PageNum == 0 { + req.PageNum = 1 + } + res.CurrentPage = req.PageNum + if req.PageSize == 0 { + req.PageSize = consts.PageSize + } + err = m.Fields(model.SysDictTypeInfoRes{}).Page(req.PageNum, req.PageSize). + Order(dao.SysDictType.Columns().DictId + " asc").Scan(&res.DictTypeList) + liberr.ErrIsNil(ctx, err, "获取字典类型失败") + }) + return +} + +// Add 添加字典类型 +func (s *dictTypeImpl) Add(ctx context.Context, req *system.DictTypeAddReq, userId uint64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + err = s.ExistsDictType(ctx, req.DictType) + liberr.ErrIsNil(ctx, err) + _, err = dao.SysDictType.Ctx(ctx).Insert(do.SysDictType{ + DictName: req.DictName, + DictType: req.DictType, + Status: req.Status, + CreateBy: userId, + Remark: req.Remark, + }) + liberr.ErrIsNil(ctx, err, "添加字典类型失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysDictTag) + }) + return +} + +// Edit 修改字典类型 +func (s *dictTypeImpl) Edit(ctx context.Context, req *system.DictTypeEditReq, userId uint64) (err error) { + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + err = s.ExistsDictType(ctx, req.DictType, req.DictId) + liberr.ErrIsNil(ctx, err) + dictType := (*entity.SysDictType)(nil) + e := dao.SysDictType.Ctx(ctx).Fields(dao.SysDictType.Columns().DictType).WherePri(req.DictId).Scan(&dictType) + liberr.ErrIsNil(ctx, e, "获取字典类型失败") + liberr.ValueIsNil(dictType, "字典类型不存在") + //修改字典类型 + _, e = dao.SysDictType.Ctx(ctx).TX(tx).WherePri(req.DictId).Update(do.SysDictType{ + DictName: req.DictName, + DictType: req.DictType, + Status: req.Status, + UpdateBy: userId, + Remark: req.Remark, + }) + liberr.ErrIsNil(ctx, e, "修改字典类型失败") + //修改字典数据 + _, e = dao.SysDictData.Ctx(ctx).TX(tx).Data(do.SysDictData{DictType: req.DictType}). + Where(dao.SysDictData.Columns().DictType, dictType.DictType).Update() + liberr.ErrIsNil(ctx, e, "修改字典数据失败") + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysDictTag) + }) + return err + }) + return +} + +func (s *dictTypeImpl) Get(ctx context.Context, req *system.DictTypeGetReq) (dictType *entity.SysDictType, err error) { + err = g.Try(ctx, func(ctx context.Context) { + err = dao.SysDictType.Ctx(ctx).Where(dao.SysDictType.Columns().DictId, req.DictId).Scan(&dictType) + liberr.ErrIsNil(ctx, err, "获取字典类型失败") + }) + return +} + +// ExistsDictType 检查类型是否已经存在 +func (s *dictTypeImpl) ExistsDictType(ctx context.Context, dictType string, dictId ...int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + m := dao.SysDictType.Ctx(ctx).Fields(dao.SysDictType.Columns().DictId). + Where(dao.SysDictType.Columns().DictType, dictType) + if len(dictId) > 0 { + m = m.Where(dao.SysDictType.Columns().DictId+" !=? ", dictId[0]) + } + res, e := m.One() + liberr.ErrIsNil(ctx, e, "sql err") + if !res.IsEmpty() { + liberr.ErrIsNil(ctx, gerror.New("字典类型已存在")) + } + }) + return +} + +// Delete 删除字典类型 +func (s *dictTypeImpl) Delete(ctx context.Context, dictIds []int) (err error) { + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + discs := ([]*entity.SysDictType)(nil) + err = dao.SysDictType.Ctx(ctx).Fields(dao.SysDictType.Columns().DictType). + Where(dao.SysDictType.Columns().DictId+" in (?) ", dictIds).Scan(&discs) + liberr.ErrIsNil(ctx, err, "删除失败") + types := garray.NewStrArray() + for _, dt := range discs { + types.Append(dt.DictType) + } + if types.Len() > 0 { + _, err = dao.SysDictType.Ctx(ctx).TX(tx).Delete(dao.SysDictType.Columns().DictId+" in (?) ", dictIds) + liberr.ErrIsNil(ctx, err, "删除类型失败") + _, err = dao.SysDictData.Ctx(ctx).TX(tx).Delete(dao.SysDictData.Columns().DictType+" in (?) ", types.Slice()) + liberr.ErrIsNil(ctx, err, "删除字典数据失败") + } + //清除缓存 + Cache().RemoveByTag(ctx, consts.CacheSysDictTag) + }) + return err + }) + return +} diff --git a/internal/service/sys_init.go b/internal/service/sys_init.go new file mode 100644 index 0000000..94386bc --- /dev/null +++ b/internal/service/sys_init.go @@ -0,0 +1,239 @@ +package service + +import ( + "bufio" + "bytes" + "context" + "fmt" + "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/database/gredis" + "github.com/gogf/gf/v2/frame/g" + "gopkg.in/yaml.v3" + "io" + "os" + "strings" + "time" + "tyj_admin/api/v1/system" + "tyj_admin/library/libUtils" +) + +type ISysInit interface { + // 生成配置文件 + CreateConfigFile(ctx context.Context, req *system.DbInitCreateDbReq) (err error) + // 生成数据库 + CreateDataBase(ctx context.Context, dbName string) (err error) + // 加载配置文件 + LoadConfigFile() (err error) + + // 是否已生成配置文件 + IsCreateConfigFile() bool + + //创建数据库 + CreateDataBaseByName(ctx context.Context, req *system.DbInitCreateDbReq) (err error) +} + +func SysInit() ISysInit { + return &sysInit{} +} + +type sysInit struct{} + +var SysInitConfig map[string]*gvar.Var + +func init() { + ctx := context.TODO() + c, err := g.Cfg("initialize").Get(ctx, "initialize") + if err != nil { + g.Log().Panic(ctx, err) + } + SysInitConfig = make(map[string]*gvar.Var) + SysInitConfig = c.MapStrVar() +} + +// 创建数据库 +func (s *sysInit) CreateDataBaseByName(ctx context.Context, req *system.DbInitCreateDbReq) (err error) { + db, err := gdb.New(gdb.ConfigNode{ + Type: "mysql", + Host: req.DbHost, + Port: fmt.Sprintf("%d", req.DbPort), + User: req.DbUser, + Pass: req.DbPass, + }) + if err != nil { + return + } + defer db.Close(ctx) + + _, err = db.Exec(ctx, fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci", req.DbName)) + if err != nil { + return + } + + return +} + +// 是否已经生成配置文件 +func (s *sysInit) IsCreateConfigFile() bool { + return libUtils.FileIsExisted(SysInitConfig["configPath"].String()) +} + +// 加载配置文件 +func (s *sysInit) LoadConfigFile() (err error) { + var ( + ctx = context.TODO() + ) + fileName, _ := libUtils.ParseFilePath(SysInitConfig["configPath"].String()) + // 加载数据库配置 + c1, err := g.Cfg(fileName).Get(ctx, "database.default") + if err != nil { + return + } + dbConfig := c1.MapStrVar() + gdb.SetConfig(gdb.Config{ + "default": gdb.ConfigGroup{ + gdb.ConfigNode{ + Host: dbConfig["host"].String(), + Port: dbConfig["port"].String(), + User: dbConfig["user"].String(), + Pass: dbConfig["pass"].String(), + Name: dbConfig["name"].String(), + Type: dbConfig["type"].String(), + Role: dbConfig["role"].String(), + Debug: dbConfig["debug"].Bool(), + Charset: dbConfig["charset"].String(), + DryRun: dbConfig["dryRun"].Bool(), + MaxIdleConnCount: dbConfig["maxIdle"].Int(), + MaxOpenConnCount: dbConfig["maxOpen"].Int(), + MaxConnLifeTime: dbConfig["maxLifetime"].Duration() * time.Second, + }, + }, + }) + + // 加载redis配置 + c2, err := g.Cfg(fileName).Get(ctx, "redis.default") + if err != nil { + return + } + redisConfig := c2.Map() + err = gredis.SetConfigByMap(redisConfig) + if err != nil { + return + } + return +} + +// 创建配置文件 +func (s *sysInit) CreateConfigFile(ctx context.Context, req *system.DbInitCreateDbReq) (err error) { + yamlConfig := req.ToDbInitConfig() + b, err := yaml.Marshal(yamlConfig) + if err != nil { + return + } + err = libUtils.WriteToFile(SysInitConfig["configPath"].String(), string(b)) + return +} + +// 读取sql文件 +func (s *sysInit) ReadSqlFile(path string) (sqlArr []string, err error) { + + inputFile, inputError := os.Open(path) + if inputError != nil { + return nil, inputError + } + defer inputFile.Close() + inputReader := bufio.NewReader(inputFile) + var ( + flag bool = true + buffer bytes.Buffer + ) + + for { + inputString, readerError := inputReader.ReadString('\n') + inputString = strings.TrimSpace(inputString) + if strings.HasPrefix(inputString, "--") { + flag = false + } + if strings.HasPrefix(inputString, "/*") { + flag = false + } + + if flag && inputString != "" { + if strings.HasSuffix(inputString, ";") { + if buffer.Len() == 0 { + sqlArr = append(sqlArr, inputString) + } else { + buffer.WriteString(inputString) + sqlArr = append(sqlArr, buffer.String()) + buffer.Reset() + } + } else { + buffer.WriteString(inputString + " ") + } + } + + if !flag && strings.HasPrefix(inputString, "*/") { + flag = true + } + + if !flag && strings.HasPrefix(inputString, "--") { + flag = true + } + + if readerError == io.EOF { + break + } + } + return +} + +// 创建数据库表 +func (s *sysInit) CreateDataBase(ctx context.Context, dbName string) (err error) { + sqlArr, err := s.ReadSqlFile(SysInitConfig["sqlFilePath"].String()) + if err != nil { + return + } + + if len(sqlArr) == 0 { + return + } + // newSqlArr := SqlArr(sqlArr).Split(10) + db := g.DB() + for _, item := range sqlArr { + _, err = db.Exec(ctx, item) + if err != nil { + return + } + } + + return +} + +type SqlArr []string + +func (arr SqlArr) Split(num int) (result SqlArr) { + if len(arr) == 0 { + return + } + var ( + buffer bytes.Buffer + i int + ) + + for _, item := range arr { + buffer.WriteString(item) + i++ + if i == num { + result = append(result, buffer.String()) + buffer.Reset() + i = 0 + } + } + + if buffer.Len() > 0 { + result = append(result, buffer.String()) + } + + return + +} diff --git a/internal/service/sys_login_log.go b/internal/service/sys_login_log.go new file mode 100644 index 0000000..7c80829 --- /dev/null +++ b/internal/service/sys_login_log.go @@ -0,0 +1,109 @@ +/* +* @desc:登录日志处理 +* +* +* @Date: 2022/3/8 11:42 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/grpool" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model" + "tyj_admin/library/liberr" +) + +type ISysLoginLog interface { + Invoke(ctx context.Context, data *model.LoginLogParams) + List(ctx context.Context, req *system.LoginLogSearchReq) (res *system.LoginLogSearchRes, err error) + DeleteLoginLogByIds(ctx context.Context, ids []int) (err error) + ClearLoginLog(ctx context.Context) (err error) +} + +type sysLoginLogImpl struct { + Pool *grpool.Pool +} + +var ( + sysLoginLogService = sysLoginLogImpl{ + Pool: grpool.New(100), + } +) + +func SysLoginLog() ISysLoginLog { + return &sysLoginLogService +} + +func (s *sysLoginLogImpl) Invoke(ctx context.Context, data *model.LoginLogParams) { + s.Pool.Add( + ctx, + func(ctx context.Context) { + //写入日志数据 + User().LoginLog(ctx, data) + }, + ) +} + +func (s *sysLoginLogImpl) List(ctx context.Context, req *system.LoginLogSearchReq) (res *system.LoginLogSearchRes, err error) { + res = new(system.LoginLogSearchRes) + if req.PageNum == 0 { + req.PageNum = 1 + } + res.CurrentPage = req.PageNum + if req.PageSize == 0 { + req.PageSize = consts.PageSize + } + m := dao.SysLoginLog.Ctx(ctx) + order := "info_id DESC" + if req.LoginName != "" { + m = m.Where("login_name like ?", "%"+req.LoginName+"%") + } + if req.Status != "" { + m = m.Where("status", gconv.Int(req.Status)) + } + if req.Ipaddr != "" { + m = m.Where("ipaddr like ?", "%"+req.Ipaddr+"%") + } + if req.LoginLocation != "" { + m = m.Where("login_location like ?", "%"+req.LoginLocation+"%") + } + if len(req.DateRange) != 0 { + m = m.Where("login_time >=? AND login_time <=?", req.DateRange[0], req.DateRange[1]) + } + if req.SortName != "" { + if req.SortOrder != "" { + order = req.SortName + " " + req.SortOrder + } else { + order = req.SortName + " DESC" + } + } + err = g.Try(ctx, func(ctx context.Context) { + res.Total, err = m.Count() + liberr.ErrIsNil(ctx, err, "获取日志失败") + err = m.Page(req.PageNum, req.PageSize).Order(order).Scan(&res.List) + liberr.ErrIsNil(ctx, err, "获取日志数据失败") + }) + return +} + +func (s *sysLoginLogImpl) DeleteLoginLogByIds(ctx context.Context, ids []int) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysLoginLog.Ctx(ctx).Delete("info_id in (?)", ids) + liberr.ErrIsNil(ctx, err, "删除失败") + }) + return +} + +func (s *sysLoginLogImpl) ClearLoginLog(ctx context.Context) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = g.DB().Ctx(ctx).Exec(ctx, "truncate "+dao.SysLoginLog.Table()) + liberr.ErrIsNil(ctx, err, "清除失败") + }) + return +} diff --git a/internal/service/sys_post.go b/internal/service/sys_post.go new file mode 100644 index 0000000..7e02210 --- /dev/null +++ b/internal/service/sys_post.go @@ -0,0 +1,116 @@ +/* +* @desc:岗位处理 +* +* +* @Date: 2022/4/7 23:18 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" + "tyj_admin/library/liberr" +) + +type IPost interface { + List(ctx context.Context, req *system.PostSearchReq) (res *system.PostSearchRes, err error) + Add(ctx context.Context, req *system.PostAddReq) (err error) + Edit(ctx context.Context, req *system.PostEditReq) (err error) + Delete(ctx context.Context, ids []int) (err error) + GetUsedPost(ctx context.Context) (list []*entity.SysPost, err error) +} + +type postImpl struct { +} + +var postService = postImpl{} + +func Post() IPost { + return &postService +} + +// List 岗位列表 +func (s *postImpl) List(ctx context.Context, req *system.PostSearchReq) (res *system.PostSearchRes, err error) { + res = new(system.PostSearchRes) + err = g.Try(ctx, func(ctx context.Context) { + m := dao.SysPost.Ctx(ctx) + if req != nil { + if req.PostCode != "" { + m = m.Where("post_code like ?", "%"+req.PostCode+"%") + } + if req.PostName != "" { + m = m.Where("post_name like ?", "%"+req.PostName+"%") + } + if req.Status != "" { + m = m.Where("status", gconv.Uint(req.Status)) + } + } + res.Total, err = m.Count() + liberr.ErrIsNil(ctx, err, "获取岗位失败") + if req.PageNum == 0 { + req.PageNum = 1 + } + if req.PageSize == 0 { + req.PageSize = consts.PageSize + } + res.CurrentPage = req.PageNum + err = m.Page(req.PageNum, req.PageSize).Order("post_sort asc,post_id asc").Scan(&res.PostList) + liberr.ErrIsNil(ctx, err, "获取岗位失败") + }) + return +} + +func (s *postImpl) Add(ctx context.Context, req *system.PostAddReq) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysPost.Ctx(ctx).Insert(do.SysPost{ + PostCode: req.PostCode, + PostName: req.PostName, + PostSort: req.PostSort, + Status: req.Status, + Remark: req.Remark, + CreatedBy: Context().GetUserId(ctx), + }) + liberr.ErrIsNil(ctx, err, "添加岗位失败") + }) + return +} + +func (s *postImpl) Edit(ctx context.Context, req *system.PostEditReq) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysPost.Ctx(ctx).WherePri(req.PostId).Update(do.SysPost{ + PostCode: req.PostCode, + PostName: req.PostName, + PostSort: req.PostSort, + Status: req.Status, + Remark: req.Remark, + UpdatedBy: Context().GetUserId(ctx), + }) + liberr.ErrIsNil(ctx, err, "修改岗位失败") + }) + return +} + +func (s *postImpl) Delete(ctx context.Context, ids []int) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysPost.Ctx(ctx).Where(dao.SysPost.Columns().PostId+" in(?)", ids).Delete() + liberr.ErrIsNil(ctx, err, "删除失败") + }) + return +} + +// GetUsedPost 获取正常状态的岗位 +func (s *postImpl) GetUsedPost(ctx context.Context) (list []*entity.SysPost, err error) { + err = g.Try(ctx, func(ctx context.Context) { + err = dao.SysPost.Ctx(ctx).Where(dao.SysPost.Columns().Status, 1). + Order(dao.SysPost.Columns().PostSort + " ASC, " + dao.SysPost.Columns().PostId + " ASC ").Scan(&list) + liberr.ErrIsNil(ctx, err, "获取岗位数据失败") + }) + return +} diff --git a/internal/service/sys_role.go b/internal/service/sys_role.go new file mode 100644 index 0000000..425f833 --- /dev/null +++ b/internal/service/sys_role.go @@ -0,0 +1,197 @@ +/* +* @desc:角色处理 +* +* +* @Date: 2022/3/9 10:31 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" + "tyj_admin/library/liberr" +) + +type IRole interface { + GetRoleList(ctx context.Context) (list []*entity.SysRole, err error) + GetRoleListSearch(ctx context.Context, req *system.RoleListReq) (res *system.RoleListRes, err error) + AddRole(ctx context.Context, req *system.RoleAddReq) (err error) + Get(ctx context.Context, id uint) (res *entity.SysRole, err error) + GetFilteredNamedPolicy(ctx context.Context, id uint) (gpSlice []int, err error) + EditRole(ctx context.Context, req *system.RoleEditReq) error + DeleteByIds(ctx context.Context, ids []int64) (err error) +} + +type roleImpl struct { +} + +var roleService = roleImpl{} + +func Role() IRole { + return &roleService +} + +func (s *roleImpl) GetRoleListSearch(ctx context.Context, req *system.RoleListReq) (res *system.RoleListRes, err error) { + res = new(system.RoleListRes) + g.Try(ctx, func(ctx context.Context) { + model := dao.SysRole.Ctx(ctx) + if req.RoleName != "" { + model = model.Where("name like ?", "%"+req.RoleName+"%") + } + if req.Status != "" { + model = model.Where("status", gconv.Int(req.Status)) + } + res.Total, err = model.Count() + liberr.ErrIsNil(ctx, err, "获取角色数据失败") + if req.PageNum == 0 { + req.PageNum = 1 + } + res.CurrentPage = req.PageNum + if req.PageSize == 0 { + req.PageSize = consts.PageSize + } + err = model.Page(res.CurrentPage, req.PageSize).Order("id asc").Scan(&res.List) + liberr.ErrIsNil(ctx, err, "获取数据失败") + }) + return +} + +// GetRoleList 获取角色列表 +func (s *roleImpl) GetRoleList(ctx context.Context) (list []*entity.SysRole, err error) { + cache := Cache() + //从缓存获取 + iList := cache.GetOrSetFuncLock(ctx, consts.CacheSysRole, s.getRoleListFromDb, 0, consts.CacheSysAuthTag) + if iList != nil { + err = gconv.Struct(iList, &list) + } + return +} + +// 从数据库获取所有角色 +func (s *roleImpl) getRoleListFromDb(ctx context.Context) (value interface{}, err error) { + err = g.Try(ctx, func(ctx context.Context) { + var v []*entity.SysRole + //从数据库获取 + err = dao.SysRole.Ctx(ctx). + Order(dao.SysRole.Columns().ListOrder + " asc," + dao.SysRole.Columns().Id + " asc"). + Scan(&v) + liberr.ErrIsNil(ctx, err, "获取角色数据失败") + value = v + }) + return +} + +// AddRoleRule 添加角色权限 +func (s *roleImpl) AddRoleRule(ctx context.Context, ruleIds []uint, roleId int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + ruleIdsStr := gconv.Strings(ruleIds) + for _, v := range ruleIdsStr { + _, err = enforcer.AddPolicy(gconv.String(roleId), v, "All") + liberr.ErrIsNil(ctx, err) + } + }) + return +} + +// DelRoleRule 删除角色权限 +func (s *roleImpl) DelRoleRule(ctx context.Context, roleId int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + _, err = enforcer.RemoveFilteredPolicy(0, gconv.String(roleId)) + liberr.ErrIsNil(ctx, e) + }) + return +} + +func (s *roleImpl) AddRole(ctx context.Context, req *system.RoleAddReq) (err error) { + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + roleId, e := dao.SysRole.Ctx(ctx).TX(tx).InsertAndGetId(req) + liberr.ErrIsNil(ctx, e, "添加角色失败") + //添加角色权限 + e = s.AddRoleRule(ctx, req.MenuIds, roleId) + liberr.ErrIsNil(ctx, e) + //清除缓存 + Cache().Remove(ctx, consts.CacheSysRole) + }) + return err + }) + return +} + +func (s *roleImpl) Get(ctx context.Context, id uint) (res *entity.SysRole, err error) { + err = g.Try(ctx, func(ctx context.Context) { + err = dao.SysRole.Ctx(ctx).WherePri(id).Scan(&res) + liberr.ErrIsNil(ctx, err, "获取角色信息失败") + }) + return +} + +// GetFilteredNamedPolicy 获取角色关联的菜单规则 +func (s *roleImpl) GetFilteredNamedPolicy(ctx context.Context, id uint) (gpSlice []int, err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + gp := enforcer.GetFilteredNamedPolicy("p", 0, gconv.String(id)) + gpSlice = make([]int, len(gp)) + for k, v := range gp { + gpSlice[k] = gconv.Int(v[1]) + } + }) + return +} + +// EditRole 修改角色 +func (s *roleImpl) EditRole(ctx context.Context, req *system.RoleEditReq) (err error) { + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + _, e := dao.SysRole.Ctx(ctx).TX(tx).WherePri(req.Id).Data(&do.SysRole{ + Status: req.Status, + ListOrder: req.ListOrder, + Name: req.Name, + Remark: req.Remark, + }).Update() + liberr.ErrIsNil(ctx, e, "修改角色失败") + //删除角色权限 + e = s.DelRoleRule(ctx, req.Id) + liberr.ErrIsNil(ctx, e) + //添加角色权限 + e = s.AddRoleRule(ctx, req.MenuIds, req.Id) + liberr.ErrIsNil(ctx, e) + //清除缓存 + Cache().Remove(ctx, consts.CacheSysRole) + }) + return err + }) + return +} + +// DeleteByIds 删除角色 +func (s *roleImpl) DeleteByIds(ctx context.Context, ids []int64) (err error) { + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysRole.Ctx(ctx).TX(tx).Where(dao.SysRole.Columns().Id+" in(?)", ids).Delete() + liberr.ErrIsNil(ctx, err, "删除角色失败") + //删除角色权限 + for _, v := range ids { + err = s.DelRoleRule(ctx, v) + liberr.ErrIsNil(ctx, err) + } + //清除缓存 + Cache().Remove(ctx, consts.CacheSysRole) + }) + return err + }) + return +} diff --git a/internal/service/sys_user.go b/internal/service/sys_user.go new file mode 100644 index 0000000..4501183 --- /dev/null +++ b/internal/service/sys_user.go @@ -0,0 +1,626 @@ +/* +* @desc:用户处理 +* +* +* @Date: 2022/3/7 9:50 + */ + +package service + +import ( + "context" + "fmt" + "github.com/gogf/gf/v2/container/gset" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "github.com/gogf/gf/v2/util/grand" + "github.com/mssola/user_agent" + "tyj_admin/api/v1/system" + "tyj_admin/internal/consts" + "tyj_admin/internal/dao" + model2 "tyj_admin/internal/model" + "tyj_admin/internal/model/do" + "tyj_admin/internal/model/entity" + "tyj_admin/library/libUtils" + "tyj_admin/library/liberr" +) + +type IUser interface { + GetAdminUserByUsernamePassword(ctx context.Context, req *system.UserLoginReq) (user *model2.LoginUserRes, err error) + LoginLog(ctx context.Context, params *model2.LoginLogParams) + UpdateLoginInfo(ctx context.Context, id uint64, ip string) (err error) + NotCheckAuthAdminIds(ctx context.Context) *gset.Set + GetAdminRules(ctx context.Context, userId uint64) (menuList []*model2.UserMenus, permissions []string, err error) + List(ctx context.Context, req *system.UserSearchReq) (total int, userList []*entity.SysUser, err error) + GetUsersRoleDept(ctx context.Context, userList []*entity.SysUser) (users []*model2.SysUserRoleDeptRes, err error) + Add(ctx context.Context, req *system.UserAddReq) (err error) + GetEditUser(ctx context.Context, id uint64) (res *system.UserGetEditRes, err error) + Edit(ctx context.Context, req *system.UserEditReq) (err error) + ResetUserPwd(ctx context.Context, req *system.UserResetPwdReq) (err error) + ChangeUserStatus(ctx context.Context, req *system.UserStatusReq) (err error) + Delete(ctx context.Context, ids []int) (err error) +} + +type userImpl struct { + CasBinUserPrefix string //CasBin 用户id前缀 +} + +var ( + notCheckAuthAdminIds *gset.Set //无需验证权限的用户id + userService = userImpl{ + CasBinUserPrefix: "u_", + } +) + +func User() IUser { + return &userService +} + +func (s *userImpl) NotCheckAuthAdminIds(ctx context.Context) *gset.Set { + ids := g.Cfg().MustGet(ctx, "system.notCheckAuthAdminIds") + if !g.IsNil(ids) { + notCheckAuthAdminIds = gset.NewFrom(ids) + } + return notCheckAuthAdminIds +} + +func (s *userImpl) GetAdminUserByUsernamePassword(ctx context.Context, req *system.UserLoginReq) (user *model2.LoginUserRes, err error) { + err = g.Try(ctx, func(ctx context.Context) { + user, err = s.GetUserByUsername(ctx, req.Username) + liberr.ErrIsNil(ctx, err) + liberr.ValueIsNil(user, "账号密码错误") + //验证密码 + if libUtils.EncryptPassword(req.Password, user.UserSalt) != user.UserPassword { + liberr.ErrIsNil(ctx, gerror.New("账号密码错误")) + } + //账号状态 + if user.UserStatus == 0 { + liberr.ErrIsNil(ctx, gerror.New("账号已被冻结")) + } + }) + return +} + +// GetUserByUsername 通过用户名获取用户信息 +func (s *userImpl) GetUserByUsername(ctx context.Context, userName string) (user *model2.LoginUserRes, err error) { + err = g.Try(ctx, func(ctx context.Context) { + user = &model2.LoginUserRes{} + err = dao.SysUser.Ctx(ctx).Fields(user).Where(dao.SysUser.Columns().UserName, userName).Scan(user) + liberr.ErrIsNil(ctx, err, "账号密码错误") + }) + return +} + +// LoginLog 记录登录日志 +func (s *userImpl) LoginLog(ctx context.Context, params *model2.LoginLogParams) { + ua := user_agent.New(params.UserAgent) + browser, _ := ua.Browser() + loginData := &do.SysLoginLog{ + LoginName: params.Username, + Ipaddr: params.Ip, + LoginLocation: libUtils.GetCityByIp(params.Ip), + Browser: browser, + Os: ua.OS(), + Status: params.Status, + Msg: params.Msg, + LoginTime: gtime.Now(), + Module: params.Module, + } + _, err := dao.SysLoginLog.Ctx(ctx).Insert(loginData) + if err != nil { + g.Log().Error(ctx, err) + } +} + +func (s *userImpl) UpdateLoginInfo(ctx context.Context, id uint64, ip string) (err error) { + g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysUser.Ctx(ctx).WherePri(id).Update(g.Map{ + dao.SysUser.Columns().LastLoginIp: ip, + dao.SysUser.Columns().LastLoginTime: gtime.Now(), + }) + liberr.ErrIsNil(ctx, err, "更新用户登录信息失败") + }) + return +} + +// GetAdminRules 获取用户菜单数据 +func (s *userImpl) GetAdminRules(ctx context.Context, userId uint64) (menuList []*model2.UserMenus, permissions []string, err error) { + err = g.Try(ctx, func(ctx context.Context) { + //是否超管 + isSuperAdmin := false + //获取无需验证权限的用户id + s.NotCheckAuthAdminIds(ctx).Iterator(func(v interface{}) bool { + if gconv.Uint64(v) == userId { + isSuperAdmin = true + return false + } + return true + }) + //获取用户菜单数据 + allRoles, err := Role().GetRoleList(ctx) + liberr.ErrIsNil(ctx, err) + roles, err := s.GetAdminRole(ctx, userId, allRoles) + liberr.ErrIsNil(ctx, err) + name := make([]string, len(roles)) + roleIds := make([]uint, len(roles)) + for k, v := range roles { + name[k] = v.Name + roleIds[k] = v.Id + } + //获取菜单信息 + if isSuperAdmin { + //超管获取所有菜单 + permissions = []string{"*/*/*"} + menuList, err = s.GetAllMenus(ctx) + liberr.ErrIsNil(ctx, err) + } else { + menuList, err = s.GetAdminMenusByRoleIds(ctx, roleIds) + liberr.ErrIsNil(ctx, err) + permissions, err = s.GetPermissions(ctx, roleIds) + liberr.ErrIsNil(ctx, err) + } + }) + return +} + +// GetAdminRole 获取用户角色 +func (s *userImpl) GetAdminRole(ctx context.Context, userId uint64, allRoleList []*entity.SysRole) (roles []*entity.SysRole, err error) { + var roleIds []uint + roleIds, err = s.GetAdminRoleIds(ctx, userId) + if err != nil { + return + } + roles = make([]*entity.SysRole, 0, len(allRoleList)) + for _, v := range allRoleList { + for _, id := range roleIds { + if id == v.Id { + roles = append(roles, v) + } + } + if len(roles) == len(roleIds) { + break + } + } + return +} + +// GetAdminRoleIds 获取用户角色ids +func (s *userImpl) GetAdminRoleIds(ctx context.Context, userId uint64) (roleIds []uint, err error) { + enforcer, e := CasbinEnforcer(ctx) + if e != nil { + err = e + return + } + //查询关联角色规则 + groupPolicy := enforcer.GetFilteredGroupingPolicy(0, fmt.Sprintf("%s%d", s.CasBinUserPrefix, userId)) + if len(groupPolicy) > 0 { + roleIds = make([]uint, len(groupPolicy)) + //得到角色id的切片 + for k, v := range groupPolicy { + roleIds[k] = gconv.Uint(v[1]) + } + } + return +} + +func (s *userImpl) GetAllMenus(ctx context.Context) (menus []*model2.UserMenus, err error) { + //获取所有开启的菜单 + var allMenus []*model2.SysAuthRuleInfoRes + allMenus, err = Rule().GetIsMenuList(ctx) + if err != nil { + return + } + menus = make([]*model2.UserMenus, len(allMenus)) + for k, v := range allMenus { + var menu *model2.UserMenu + menu = s.setMenuData(menu, v) + menus[k] = &model2.UserMenus{UserMenu: menu} + } + menus = s.GetMenusTree(menus, 0) + return +} + +func (s *userImpl) GetAdminMenusByRoleIds(ctx context.Context, roleIds []uint) (menus []*model2.UserMenus, err error) { + //获取角色对应的菜单id + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + menuIds := map[int64]int64{} + for _, roleId := range roleIds { + //查询当前权限 + gp := enforcer.GetFilteredPolicy(0, gconv.String(roleId)) + for _, p := range gp { + mid := gconv.Int64(p[1]) + menuIds[mid] = mid + } + } + //获取所有开启的菜单 + allMenus, err := Rule().GetIsMenuList(ctx) + liberr.ErrIsNil(ctx, err) + menus = make([]*model2.UserMenus, 0, len(allMenus)) + for _, v := range allMenus { + if _, ok := menuIds[gconv.Int64(v.Id)]; gstr.Equal(v.Condition, "nocheck") || ok { + var roleMenu *model2.UserMenu + roleMenu = s.setMenuData(roleMenu, v) + menus = append(menus, &model2.UserMenus{UserMenu: roleMenu}) + } + } + menus = s.GetMenusTree(menus, 0) + }) + return +} + +func (s *userImpl) GetMenusTree(menus []*model2.UserMenus, pid uint) []*model2.UserMenus { + returnList := make([]*model2.UserMenus, 0, len(menus)) + for _, menu := range menus { + if menu.Pid == pid { + menu.Children = s.GetMenusTree(menus, menu.Id) + returnList = append(returnList, menu) + } + } + return returnList +} + +func (s *userImpl) setMenuData(menu *model2.UserMenu, entity *model2.SysAuthRuleInfoRes) *model2.UserMenu { + menu = &model2.UserMenu{ + Id: entity.Id, + Pid: entity.Pid, + Name: gstr.CaseCamelLower(gstr.Replace(entity.Name, "/", "_")), + Component: entity.Component, + Path: entity.Path, + MenuMeta: &model2.MenuMeta{ + Icon: entity.Icon, + Title: entity.Title, + IsLink: "", + IsHide: entity.IsHide == 1, + IsKeepAlive: entity.IsCached == 1, + IsAffix: entity.IsAffix == 1, + IsIframe: entity.IsIframe == 1, + }, + } + if menu.MenuMeta.IsIframe || entity.IsLink == 1 { + menu.MenuMeta.IsLink = entity.LinkUrl + } + return menu +} + +func (s *userImpl) GetPermissions(ctx context.Context, roleIds []uint) (userButtons []string, err error) { + err = g.Try(ctx, func(ctx context.Context) { + //获取角色对应的菜单id + enforcer, err := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, err) + menuIds := map[int64]int64{} + for _, roleId := range roleIds { + //查询当前权限 + gp := enforcer.GetFilteredPolicy(0, gconv.String(roleId)) + for _, p := range gp { + mid := gconv.Int64(p[1]) + menuIds[mid] = mid + } + } + //获取所有开启的按钮 + allButtons, err := Rule().GetIsButtonList(ctx) + liberr.ErrIsNil(ctx, err) + userButtons = make([]string, 0, len(allButtons)) + for _, button := range allButtons { + if _, ok := menuIds[gconv.Int64(button.Id)]; gstr.Equal(button.Condition, "nocheck") || ok { + userButtons = append(userButtons, button.Name) + } + } + }) + return +} + +// List 用户列表 +func (s *userImpl) List(ctx context.Context, req *system.UserSearchReq) (total int, userList []*entity.SysUser, err error) { + err = g.Try(ctx, func(ctx context.Context) { + m := dao.SysUser.Ctx(ctx) + if req.KeyWords != "" { + keyWords := "%" + req.KeyWords + "%" + m = m.Where("user_name like ? or user_nickname like ?", keyWords, keyWords) + } + if req.DeptId != "" { + deptIds, e := s.getSearchDeptIds(ctx, gconv.Int64(req.DeptId)) + liberr.ErrIsNil(ctx, e) + m = m.Where("dept_id in (?)", deptIds) + } + if req.Status != "" { + m = m.Where("user_status", gconv.Int(req.Status)) + } + if req.Mobile != "" { + m = m.Where("mobile like ?", "%"+req.Mobile+"%") + } + if len(req.DateRange) > 0 { + m = m.Where("created_at >=? AND created_at <=?", req.DateRange[0], req.DateRange[1]) + } + if req.PageSize == 0 { + req.PageSize = consts.PageSize + } + if req.PageNum == 0 { + req.PageNum = 1 + } + total, err = m.Count() + liberr.ErrIsNil(ctx, err, "获取用户数据失败") + err = m.FieldsEx(dao.SysUser.Columns().UserPassword, dao.SysUser.Columns().UserSalt). + Page(req.PageNum, req.PageSize).Order("id asc").Scan(&userList) + liberr.ErrIsNil(ctx, err, "获取用户列表失败") + }) + return +} + +// GetUsersRoleDept 获取多个用户角色 部门信息 +func (s *userImpl) GetUsersRoleDept(ctx context.Context, userList []*entity.SysUser) (users []*model2.SysUserRoleDeptRes, err error) { + err = g.Try(ctx, func(ctx context.Context) { + allRoles, e := Role().GetRoleList(ctx) + liberr.ErrIsNil(ctx, e) + depts, e := Dept().GetFromCache(ctx) + liberr.ErrIsNil(ctx, e) + users = make([]*model2.SysUserRoleDeptRes, len(userList)) + for k, u := range userList { + var dept *entity.SysDept + users[k] = &model2.SysUserRoleDeptRes{ + SysUser: u, + } + for _, d := range depts { + if u.DeptId == uint64(d.DeptId) { + dept = d + } + } + users[k].Dept = dept + roles, e := s.GetAdminRole(ctx, u.Id, allRoles) + liberr.ErrIsNil(ctx, e) + for _, r := range roles { + users[k].RoleInfo = append(users[k].RoleInfo, &model2.SysUserRoleInfoRes{RoleId: r.Id, Name: r.Name}) + } + } + }) + return +} + +func (s *userImpl) getSearchDeptIds(ctx context.Context, deptId int64) (deptIds []int64, err error) { + err = g.Try(ctx, func(ctx context.Context) { + deptAll, e := Dept().GetFromCache(ctx) + liberr.ErrIsNil(ctx, e) + deptWithChildren := Dept().FindSonByParentId(deptAll, gconv.Int64(deptId)) + deptIds = make([]int64, len(deptWithChildren)) + for k, v := range deptWithChildren { + deptIds[k] = v.DeptId + } + deptIds = append(deptIds, deptId) + }) + return +} + +func (s *userImpl) Add(ctx context.Context, req *system.UserAddReq) (err error) { + err = s.userNameOrMobileExists(ctx, req.UserName, req.Mobile) + if err != nil { + return + } + req.UserSalt = grand.S(10) + req.Password = libUtils.EncryptPassword(req.Password, req.UserSalt) + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + userId, e := dao.SysUser.Ctx(ctx).TX(tx).InsertAndGetId(do.SysUser{ + UserName: req.UserName, + Mobile: req.Mobile, + UserNickname: req.NickName, + UserPassword: req.Password, + UserSalt: req.UserSalt, + UserStatus: req.Status, + UserEmail: req.Email, + Sex: req.Sex, + DeptId: req.DeptId, + Remark: req.Remark, + IsAdmin: req.IsAdmin, + }) + liberr.ErrIsNil(ctx, e, "添加用户失败") + e = s.addUserRole(ctx, req.RoleIds, userId) + liberr.ErrIsNil(ctx, e, "设置用户权限失败") + e = s.AddUserPost(ctx, tx, req.PostIds, userId) + liberr.ErrIsNil(ctx, e) + }) + return err + }) + return +} + +func (s *userImpl) Edit(ctx context.Context, req *system.UserEditReq) (err error) { + err = s.userNameOrMobileExists(ctx, "", req.Mobile, req.UserId) + if err != nil { + return + } + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysUser.Ctx(ctx).TX(tx).WherePri(req.UserId).Update(do.SysUser{ + Mobile: req.Mobile, + UserNickname: req.NickName, + UserStatus: req.Status, + UserEmail: req.Email, + Sex: req.Sex, + DeptId: req.DeptId, + Remark: req.Remark, + IsAdmin: req.IsAdmin, + }) + liberr.ErrIsNil(ctx, err, "修改用户信息失败") + //设置用户所属角色信息 + err = s.EditUserRole(ctx, req.RoleIds, req.UserId) + liberr.ErrIsNil(ctx, err, "设置用户权限失败") + err = s.AddUserPost(ctx, tx, req.PostIds, req.UserId) + liberr.ErrIsNil(ctx, err) + }) + return err + }) + return +} + +// AddUserPost 添加用户岗位信息 +func (s *userImpl) AddUserPost(ctx context.Context, tx *gdb.TX, postIds []int64, userId int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + //删除旧岗位信息 + _, err = dao.SysUserPost.Ctx(ctx).TX(tx).Where(dao.SysUserPost.Columns().UserId, userId).Delete() + liberr.ErrIsNil(ctx, err, "设置用户岗位失败") + if len(postIds) == 0 { + return + } + //添加用户岗位信息 + data := g.List{} + for _, v := range postIds { + data = append(data, g.Map{ + dao.SysUserPost.Columns().UserId: userId, + dao.SysUserPost.Columns().PostId: v, + }) + } + _, err = dao.SysUserPost.Ctx(ctx).TX(tx).Data(data).Insert() + liberr.ErrIsNil(ctx, err, "设置用户岗位失败") + }) + return +} + +// AddUserRole 添加用户角色信息 +func (s *userImpl) addUserRole(ctx context.Context, roleIds []int64, userId int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + for _, v := range roleIds { + _, e = enforcer.AddGroupingPolicy(fmt.Sprintf("%s%d", s.CasBinUserPrefix, userId), gconv.String(v)) + liberr.ErrIsNil(ctx, e) + } + }) + return +} + +// EditUserRole 修改用户角色信息 +func (s *userImpl) EditUserRole(ctx context.Context, roleIds []int64, userId int64) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + + //删除用户旧角色信息 + enforcer.RemoveFilteredGroupingPolicy(0, fmt.Sprintf("%s%d", s.CasBinUserPrefix, userId)) + for _, v := range roleIds { + _, err = enforcer.AddGroupingPolicy(fmt.Sprintf("%s%d", s.CasBinUserPrefix, userId), gconv.String(v)) + liberr.ErrIsNil(ctx, err) + } + }) + return +} + +func (s *userImpl) userNameOrMobileExists(ctx context.Context, userName, mobile string, id ...int64) error { + user := (*entity.SysUser)(nil) + err := g.Try(ctx, func(ctx context.Context) { + m := dao.SysUser.Ctx(ctx) + if len(id) > 0 { + m = m.Where(dao.SysUser.Columns().Id+" != ", id) + } + m = m.Where(fmt.Sprintf("%s='%s' OR %s='%s'", + dao.SysUser.Columns().UserName, + userName, + dao.SysUser.Columns().Mobile, + mobile)) + err := m.Limit(1).Scan(&user) + liberr.ErrIsNil(ctx, err, "获取用户信息失败") + if user == nil { + return + } + if user.UserName == userName { + liberr.ErrIsNil(ctx, gerror.New("用户名已存在")) + } + if user.Mobile == mobile { + liberr.ErrIsNil(ctx, gerror.New("手机号已存在")) + } + }) + return err +} + +// GetEditUser 获取编辑用户信息 +func (s *userImpl) GetEditUser(ctx context.Context, id uint64) (res *system.UserGetEditRes, err error) { + res = new(system.UserGetEditRes) + err = g.Try(ctx, func(ctx context.Context) { + //获取用户信息 + res.User, err = s.GetUserInfoById(ctx, id) + liberr.ErrIsNil(ctx, err) + //获取已选择的角色信息 + res.CheckedRoleIds, err = s.GetAdminRoleIds(ctx, id) + liberr.ErrIsNil(ctx, err) + res.CheckedPosts, err = s.GetUserPostIds(ctx, id) + liberr.ErrIsNil(ctx, err) + }) + return +} + +// GetUserInfoById 通过Id获取用户信息 +func (s *userImpl) GetUserInfoById(ctx context.Context, id uint64, withPwd ...bool) (user *entity.SysUser, err error) { + err = g.Try(ctx, func(ctx context.Context) { + if len(withPwd) > 0 && withPwd[0] { + //用户用户信息 + err = dao.SysUser.Ctx(ctx).Where(dao.SysUser.Columns().Id, id).Scan(&user) + } else { + //用户用户信息 + err = dao.SysUser.Ctx(ctx).Where(dao.SysUser.Columns().Id, id). + FieldsEx(dao.SysUser.Columns().UserPassword, dao.SysUser.Columns().UserSalt).Scan(&user) + } + liberr.ErrIsNil(ctx, err, "获取用户数据失败") + }) + return +} + +// GetUserPostIds 获取用户岗位 +func (s *userImpl) GetUserPostIds(ctx context.Context, userId uint64) (postIds []int64, err error) { + err = g.Try(ctx, func(ctx context.Context) { + var list []*entity.SysUserPost + err = dao.SysUserPost.Ctx(ctx).Where(dao.SysUserPost.Columns().UserId, userId).Scan(&list) + liberr.ErrIsNil(ctx, err, "获取用户岗位信息失败") + postIds = make([]int64, 0) + for _, entity := range list { + postIds = append(postIds, entity.PostId) + } + }) + return +} + +// ResetUserPwd 重置用户密码 +func (s *userImpl) ResetUserPwd(ctx context.Context, req *system.UserResetPwdReq) (err error) { + salt := grand.S(10) + password := libUtils.EncryptPassword(req.Password, salt) + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysUser.Ctx(ctx).WherePri(req.Id).Update(g.Map{ + dao.SysUser.Columns().UserSalt: salt, + dao.SysUser.Columns().UserPassword: password, + }) + liberr.ErrIsNil(ctx, err, "重置用户密码失败") + }) + return +} + +func (s *userImpl) ChangeUserStatus(ctx context.Context, req *system.UserStatusReq) (err error) { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysUser.Ctx(ctx).WherePri(req.Id).Update(do.SysUser{UserStatus: req.UserStatus}) + liberr.ErrIsNil(ctx, err, "设置用户状态失败") + }) + return +} + +// Delete 删除用户 +func (s *userImpl) Delete(ctx context.Context, ids []int) (err error) { + err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error { + err = g.Try(ctx, func(ctx context.Context) { + _, err = dao.SysUser.Ctx(ctx).TX(tx).Where(dao.SysUser.Columns().Id+" in(?)", ids).Delete() + liberr.ErrIsNil(ctx, err, "删除用户失败") + //删除对应权限 + enforcer, e := CasbinEnforcer(ctx) + liberr.ErrIsNil(ctx, e) + for _, v := range ids { + enforcer.RemoveFilteredGroupingPolicy(0, fmt.Sprintf("%s%d", s.CasBinUserPrefix, v)) + } + //删除用户对应的岗位 + _, err = dao.SysUserPost.Ctx(ctx).TX(tx).Delete(dao.SysUserPost.Columns().UserId+" in (?)", ids) + liberr.ErrIsNil(ctx, err, "删除用户的岗位失败") + }) + return err + }) + return +} diff --git a/internal/service/token.go b/internal/service/token.go new file mode 100644 index 0000000..523b6ef --- /dev/null +++ b/internal/service/token.go @@ -0,0 +1,82 @@ +/* +* @desc:token功能 +* +* +* @Date: 2022/3/8 15:54 + */ + +package service + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gctx" + "github.com/tiger1103/gfast-token/gftoken" + "sync" + "tyj_admin/internal/consts" + "tyj_admin/internal/model" + "tyj_admin/library/liberr" +) + +type IGfToken interface { + GenerateToken(ctx context.Context, key string, data interface{}) (keys string, err error) + Middleware(group *ghttp.RouterGroup) error + ParseToken(r *ghttp.Request) (*gftoken.CustomClaims, error) + IsLogin(r *ghttp.Request) (b bool, failed *gftoken.AuthFailed) + GetRequestToken(r *ghttp.Request) (token string) + RemoveToken(ctx context.Context, token string) (err error) +} + +type gfTokenImpl struct { + *gftoken.GfToken +} + +var gT = gfTokenImpl{ + GfToken: gftoken.NewGfToken(), +} + +func GfToken(options *model.TokenOptions) IGfToken { + var fun gftoken.OptionFunc + if options.CacheModel == consts.CacheModelRedis { + fun = gftoken.WithGRedis() + } else { + fun = gftoken.WithGCache() + } + gT.GfToken = gftoken.NewGfToken( + gftoken.WithCacheKey(options.CacheKey), + gftoken.WithTimeout(options.Timeout), + gftoken.WithMaxRefresh(options.MaxRefresh), + gftoken.WithMultiLogin(options.MultiLogin), + gftoken.WithExcludePaths(options.ExcludePaths), + fun, + ) + return &gT +} + +// =======================system========================== +type gft struct { + options *model.TokenOptions + gT IGfToken + lock *sync.Mutex +} + +var gftService = &gft{ + options: nil, + gT: nil, + lock: &sync.Mutex{}, +} + +func SysGfToken() IGfToken { + if gftService.gT == nil { + gftService.lock.Lock() + defer gftService.lock.Unlock() + if gftService.gT == nil { + ctx := gctx.New() + err := g.Cfg().MustGet(ctx, "gfToken").Struct(&gftService.options) + liberr.ErrIsNil(ctx, err) + gftService.gT = GfToken(gftService.options) + } + } + return gftService.gT +} diff --git a/internal/service/upload.go b/internal/service/upload.go new file mode 100644 index 0000000..1059477 --- /dev/null +++ b/internal/service/upload.go @@ -0,0 +1,306 @@ +package service + +import ( + "context" + "errors" + "fmt" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gfile" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/text/gregex" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" + "github.com/gogf/gf/v2/util/grand" + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "time" + "tyj_admin/api/v1/common" + "tyj_admin/internal/consts" + "tyj_admin/internal/model/entity" +) + +type IUpload interface { + UploadFile(ctx context.Context, file *ghttp.UploadFile, checkFileType string, source int) (result common.UploadResponse, err error) + UploadFiles(ctx context.Context, files []*ghttp.UploadFile, checkFileType string, source int) (result common.UploadMultipleRes, err error) +} + +type uploadTmpl struct{} + +func Upload() IUpload { + return &uploadTmpl{} +} + +// 上传多文件 +func (s *uploadTmpl) UploadFiles(ctx context.Context, files []*ghttp.UploadFile, checkFileType string, source int) (result common.UploadMultipleRes, err error) { + for _, item := range files { + f, e := s.UploadFile(ctx, item, checkFileType, source) + if e != nil { + return + } + result = append(result, &f) + } + return +} + +// 上传单文件 +func (s *uploadTmpl) UploadFile(ctx context.Context, file *ghttp.UploadFile, checkFileType string, source int) (result common.UploadResponse, err error) { + + // 检查文件类型 + err = s.CheckType(ctx, checkFileType, file) + if err != nil { + return + } + + // 检查文件大小 + err = s.CheckSize(ctx, checkFileType, file) + if err != nil { + return + } + + // 非图片文件只能上传至本地 + if checkFileType == consts.CheckFileTypeFile { + source = consts.SourceLocal + } + + switch source { + // 上传至本地 + case consts.SourceLocal: + result, err = s.UploadLocal(ctx, file) + // 上传至腾讯云 + case consts.SourceTencent: + result, err = s.UploadTencent(ctx, file) + default: + err = errors.New("source参数错误!") + } + + if err != nil { + return + } + return +} + +// 上传至腾讯云 +func (s *uploadTmpl) UploadTencent(ctx context.Context, file *ghttp.UploadFile) (result common.UploadResponse, err error) { + v, err := g.Cfg().Get(ctx, "upload.tencentCOS") + if err != nil { + return + } + m := v.MapStrVar() + var ( + upPath = m["upPath"].String() + rawUrl = m["rawUrl"].String() + secretID = m["secretID"].String() + secretKey = m["secretKey"].String() + ) + name := gfile.Basename(file.Filename) + name = strings.ToLower(strconv.FormatInt(gtime.TimestampNano(), 36) + grand.S(6)) + name = name + gfile.Ext(file.Filename) + + path := upPath + name + + url, _ := url.Parse(rawUrl) + b := &cos.BaseURL{BucketURL: url} + client := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: secretID, + SecretKey: secretKey, + Transport: &debug.DebugRequestTransport{ + RequestHeader: false, + RequestBody: false, + ResponseHeader: false, + ResponseBody: false, + }, + }, + }) + opt := &cos.ObjectPutOptions{ + ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{ + ContentLength: int64(file.Size), + }, + } + var f io.ReadCloser + f, err = file.Open() + if err != nil { + return + } + defer f.Close() + _, err = client.Object.Put(context.Background(), path, f, opt) + result = common.UploadResponse{ + Size: file.Size, + Path: rawUrl + path, + FullPath: rawUrl + path, + Name: file.Filename, + Type: file.Header.Get("Content-type"), + } + return +} + +// 上传本地 +func (s *uploadTmpl) UploadLocal(ctx context.Context, file *ghttp.UploadFile) (result common.UploadResponse, err error) { + if file == nil { + err = errors.New("文件必须!") + return + } + r := g.RequestFromCtx(ctx) + urlPerfix := fmt.Sprintf("http://%s/", r.Host) + p := strings.Trim(consts.UploadPath, "/") + sp := s.getStaticPath(ctx) + if sp != "" { + sp = strings.Trim(sp, "/") + } + nowData := time.Now().Format("2006-01-02") + // 包含静态文件夹的路径 + fullDirPath := sp + "/" + p + "/" + nowData + fileName, err := file.Save(fullDirPath, true) + if err != nil { + return + } + // 不含静态文件夹的路径 + fullPath := p + "/" + nowData + "/" + fileName + + result = common.UploadResponse{ + Size: file.Size, + Path: fullPath, + FullPath: urlPerfix + fullPath, + Name: file.Filename, + Type: file.Header.Get("Content-type"), + } + return +} + +// 检查上传文件大小 +func (s *uploadTmpl) CheckSize(ctx context.Context, checkFileType string, file *ghttp.UploadFile) (err error) { + + var ( + configSize *entity.SysConfig + ) + + if checkFileType == consts.CheckFileTypeFile { + + //获取上传大小配置 + configSize, err = s.getUpConfig(ctx, consts.FileSizeKey) + if err != nil { + return + } + } else if checkFileType == consts.CheckFileTypeImg { + + //获取上传大小配置 + configSize, err = s.getUpConfig(ctx, consts.ImgSizeKey) + if err != nil { + return + } + } else { + return errors.New(fmt.Sprintf("文件检查类型错误:%s|%s", consts.CheckFileTypeFile, consts.CheckFileTypeImg)) + } + + var rightSize bool + rightSize, err = s.checkSize(configSize.ConfigValue, file.Size) + if err != nil { + return + } + if !rightSize { + err = gerror.New("上传文件超过最大尺寸:" + configSize.ConfigValue) + return + } + return +} + +// 检查上传文件类型 +func (s *uploadTmpl) CheckType(ctx context.Context, checkFileType string, file *ghttp.UploadFile) (err error) { + + var ( + configType *entity.SysConfig + ) + + if checkFileType == consts.CheckFileTypeFile { + //获取上传类型配置 + configType, err = s.getUpConfig(ctx, consts.FileTypeKey) + if err != nil { + return + } + + } else if checkFileType == consts.CheckFileTypeImg { + //获取上传类型配置 + configType, err = s.getUpConfig(ctx, consts.ImgTypeKey) + if err != nil { + return + } + } else { + return errors.New(fmt.Sprintf("文件检查类型错误:%s|%s", consts.CheckFileTypeFile, consts.CheckFileTypeImg)) + } + + rightType := s.checkFileType(file.Filename, configType.ConfigValue) + if !rightType { + err = gerror.New("上传文件类型错误,只能包含后缀为:" + configType.ConfigValue + "的文件。") + return + } + return +} + +// 获取上传配置 +func (s *uploadTmpl) getUpConfig(ctx context.Context, key string) (config *entity.SysConfig, err error) { + config, err = Config().GetConfigByKey(ctx, key) + if err != nil { + return + } + if config == nil { + err = gerror.New("上传文件类型未设置,请在后台配置") + return + } + return +} + +// 判断上传文件类型是否合法 +func (s *uploadTmpl) checkFileType(fileName, typeString string) bool { + suffix := gstr.SubStrRune(fileName, gstr.PosRRune(fileName, ".")+1, gstr.LenRune(fileName)-1) + imageType := gstr.Split(typeString, ",") + rightType := false + for _, v := range imageType { + if gstr.Equal(suffix, v) { + rightType = true + break + } + } + return rightType +} + +// 检查文件大小是否合法 +func (s *uploadTmpl) checkSize(configSize string, fileSize int64) (bool, error) { + match, err := gregex.MatchString(`^([0-9]+)(?i:([a-z]*))$`, configSize) + if err != nil { + return false, err + } + if len(match) == 0 { + err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB)") + return false, err + } + var cfSize int64 + switch gstr.ToUpper(match[2]) { + case "MB", "M": + cfSize = gconv.Int64(match[1]) * 1024 * 1024 + case "KB", "K": + cfSize = gconv.Int64(match[1]) * 1024 + case "": + cfSize = gconv.Int64(match[1]) + } + if cfSize == 0 { + err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB),最大单位为MB") + return false, err + } + return cfSize >= fileSize, nil +} + +// 静态文件夹目录 +func (s *uploadTmpl) getStaticPath(ctx context.Context) string { + value, _ := g.Cfg().Get(ctx, "server.serverRoot") + if !value.IsEmpty() { + return value.String() + } + return "" +} diff --git a/library/libResponse/response.go b/library/libResponse/response.go new file mode 100644 index 0000000..466e95b --- /dev/null +++ b/library/libResponse/response.go @@ -0,0 +1,107 @@ +package libResponse + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gview" + "github.com/gogf/gf/v2/text/gstr" + "github.com/gogf/gf/v2/util/gconv" +) + +const ( + SuccessCode int = 0 + ErrorCode int = -1 +) + +type Response struct { + // 代码 + Code int `json:"code" example:"200"` + // 数据集 + Data interface{} `json:"data"` + // 消息 + Msg string `json:"message"` +} + +var response = new(Response) + +func JsonExit(r *ghttp.Request, code int, msg string, data ...interface{}) { + response.JsonExit(r, code, msg, data...) +} + +func RJson(r *ghttp.Request, code int, msg string, data ...interface{}) { + response.RJson(r, code, msg, data...) +} + +func SusJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) { + response.SusJson(isExit, r, msg, data...) +} + +func FailJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) { + response.FailJson(isExit, r, msg, data...) +} + +func WriteTpl(r *ghttp.Request, tpl string, view *gview.View, params ...gview.Params) error { + return response.WriteTpl(r, tpl, view, params...) +} + +// 返回JSON数据并退出当前HTTP执行函数。 +func (res *Response) JsonExit(r *ghttp.Request, code int, msg string, data ...interface{}) { + res.RJson(r, code, msg, data...) + r.ExitAll() +} + +// 标准返回结果数据结构封装。 +// 返回固定数据结构的JSON: +// code: 状态码(200:成功,302跳转,和http请求状态码一至); +// msg: 请求结果信息; +// data: 请求结果,根据不同接口返回结果的数据结构不同; +func (res *Response) RJson(r *ghttp.Request, code int, msg string, data ...interface{}) { + responseData := interface{}(nil) + if len(data) > 0 { + responseData = data[0] + } + response = &Response{ + Code: code, + Msg: msg, + Data: responseData, + } + r.Response.WriteJson(response) +} + +//成功返回JSON +func (res *Response) SusJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) { + if isExit { + res.JsonExit(r, SuccessCode, msg, data...) + } + res.RJson(r, SuccessCode, msg, data...) +} + +//失败返回JSON +func (res *Response) FailJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) { + if isExit { + res.JsonExit(r, ErrorCode, msg, data...) + } + res.RJson(r, ErrorCode, msg, data...) +} + +// WriteTpl 模板输出 +func (res *Response) WriteTpl(r *ghttp.Request, tpl string, view *gview.View, params ...gview.Params) error { + //绑定模板中需要用到的方法 + view.BindFuncMap(g.Map{ + // 根据长度i来切割字符串 + "subStr": func(str interface{}, i int) (s string) { + s1 := gconv.String(str) + if gstr.LenRune(s1) > i { + s = gstr.SubStrRune(s1, 0, i) + "..." + return s + } + return s1 + }, + }) + r.Response.Write(view.Parse(r.GetCtx(), tpl, params...)) + return nil +} + +func (res *Response) Redirect(r *ghttp.Request, location string, code ...int) { + r.Response.RedirectTo(location, code...) +} diff --git a/library/libUtils/utils.go b/library/libUtils/utils.go new file mode 100644 index 0000000..5cb3d8e --- /dev/null +++ b/library/libUtils/utils.go @@ -0,0 +1,173 @@ +/* +* @desc:工具 +* +* +* @Date: 2022/3/4 22:16 + */ + +package libUtils + +import ( + "context" + "fmt" + "github.com/gogf/gf/v2/crypto/gmd5" + "github.com/gogf/gf/v2/encoding/gcharset" + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/encoding/gurl" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "net" + "net/http" + "os" + "path" + "strings" +) + +// EncryptPassword 密码加密 +func EncryptPassword(password, salt string) string { + return gmd5.MustEncryptString(gmd5.MustEncryptString(password) + gmd5.MustEncryptString(salt)) +} + +// GetDomain 获取当前请求接口域名 +func GetDomain(ctx context.Context) string { + r := g.RequestFromCtx(ctx) + pathInfo, err := gurl.ParseURL(r.GetUrl(), -1) + if err != nil { + g.Log().Error(ctx, err) + return "" + } + return fmt.Sprintf("%s://%s:%s/", pathInfo["scheme"], pathInfo["host"], pathInfo["port"]) +} + +// GetClientIp 获取客户端IP +func GetClientIp(ctx context.Context) string { + return g.RequestFromCtx(ctx).GetClientIp() +} + +// GetUserAgent 获取user-agent +func GetUserAgent(ctx context.Context) string { + return ghttp.RequestFromCtx(ctx).Header.Get("User-Agent") +} + +// GetLocalIP 服务端ip +func GetLocalIP() (ip string, err error) { + var addrs []net.Addr + addrs, err = net.InterfaceAddrs() + if err != nil { + return + } + for _, addr := range addrs { + ipAddr, ok := addr.(*net.IPNet) + if !ok { + continue + } + if ipAddr.IP.IsLoopback() { + continue + } + if !ipAddr.IP.IsGlobalUnicast() { + continue + } + return ipAddr.IP.String(), nil + } + return +} + +// GetCityByIp 获取ip所属城市 +func GetCityByIp(ip string) string { + if ip == "" { + return "" + } + if ip == "[::1]" || ip == "127.0.0.1" { + return "内网IP" + } + url := "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip + bytes := g.Client().GetBytes(context.TODO(), url) + src := string(bytes) + srcCharset := "GBK" + tmp, _ := gcharset.ToUTF8(srcCharset, src) + json, err := gjson.DecodeToJson(tmp) + if err != nil { + return "" + } + if json.Get("code").Int() == 0 { + city := fmt.Sprintf("%s %s", json.Get("pro").String(), json.Get("city").String()) + return city + } else { + return "" + } +} + +// 写入文件 +func WriteToFile(fileName string, content string) error { + f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) + if err != nil { + return err + } + n, _ := f.Seek(0, os.SEEK_END) + _, err = f.WriteAt([]byte(content), n) + defer f.Close() + return err +} + +// 文件或文件夹是否存在 +func FileIsExisted(filename string) bool { + existed := true + if _, err := os.Stat(filename); os.IsNotExist(err) { + existed = false + } + return existed +} + +// 解析路径获取文件名称及后缀 +func ParseFilePath(pathStr string) (fileName string, fileType string) { + fileNameWithSuffix := path.Base(pathStr) + fileType = path.Ext(fileNameWithSuffix) + fileName = strings.TrimSuffix(fileNameWithSuffix, fileType) + return +} + +// IsNotExistMkDir 检查文件夹是否存在 +// 如果不存在则新建文件夹 +func IsNotExistMkDir(src string) error { + if exist := !FileIsExisted(src); exist == false { + if err := MkDir(src); err != nil { + return err + } + } + + return nil +} + +// MkDir 新建文件夹 +func MkDir(src string) error { + err := os.MkdirAll(src, os.ModePerm) + if err != nil { + return err + } + + return nil +} + +//获取文件后缀 +func GetExt(fileName string) string { + return path.Ext(fileName) +} + +// GetType 获取文件类型 +func GetType(p string) (result string, err error) { + file, err := os.Open(p) + if err != nil { + g.Log().Error(context.TODO(), err) + return + } + buff := make([]byte, 512) + + _, err = file.Read(buff) + + if err != nil { + g.Log().Error(context.TODO(), err) + return + } + filetype := http.DetectContentType(buff) + return filetype, nil +} diff --git a/library/liberr/err.go b/library/liberr/err.go new file mode 100644 index 0000000..ac0e5c7 --- /dev/null +++ b/library/liberr/err.go @@ -0,0 +1,30 @@ +/* +* @desc:错误处理 +* +* +* @Date: 2022/3/2 14:53 + */ + +package liberr + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" +) + +func ErrIsNil(ctx context.Context, err error, msg ...string) { + if !g.IsNil(err) { + if len(msg) > 0 { + g.Log().Error(ctx, err.Error()) + panic(msg[0]) + } else { + panic(err.Error()) + } + } +} + +func ValueIsNil(value interface{}, msg string) { + if g.IsNil(value) { + panic(msg) + } +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..950061d --- /dev/null +++ b/main.go @@ -0,0 +1,27 @@ +package main + +import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + "github.com/gogf/gf/v2/os/glog" + "tyj_admin/internal/cmd" + _ "tyj_admin/internal/packed" + "tyj_admin/internal/service" +) + +func init() { + ctx := gctx.New() + if service.SysInitConfig["autoInit"].Bool() && service.SysInit().IsCreateConfigFile() { + // 加载配置文件 + err := service.SysInit().LoadConfigFile() + if err != nil { + g.Log().Panic(ctx, err) + } + } +} + +func main() { + g.Log().SetFlags(glog.F_ASYNC | glog.F_TIME_DATE | glog.F_TIME_TIME | glog.F_FILE_LONG) + cmd.Main.Run(gctx.New()) +} diff --git a/manifest/config/config.yaml.bak b/manifest/config/config.yaml.bak new file mode 100644 index 0000000..fb126ee --- /dev/null +++ b/manifest/config/config.yaml.bak @@ -0,0 +1,93 @@ +server: + address: ":8201" + serverRoot: "resource/public" + dumpRouterMap: true + routeOverWrite: true + openapiPath: "/api.json" + swaggerPath: "/swagger" + NameToUriType: 3 + maxHeaderBytes: "20KB" + clientMaxBodySize: "50MB" + # Logging配置 + logPath: "resource/log/server" # 日志文件存储目录路径,建议使用绝对路径。默认为空,表示关闭 + logStdout: true # 日志是否输出到终端。默认为true + errorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true + errorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true + errorLogPattern: "error-{Ymd}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log" + accessLogEnabled: true # 是否记录访问日志。默认为false + accessLogPattern: "access-{Ymd}.log" # 访问日志文件格式。默认为"access-{Ymd}.log" + +logger: + path: "resource/log/run" + file: "{Y-m-d}.log" + level: "all" + stdout: true + +# Database. +database: + logger: + level: "all" + stdout: true + Path: "resource/log/sql" + + default: + link: "mysql:gfast3:gfast333@tcp(192.168.0.212:3306)/gfast-v3" + debug: true + charset: "utf8mb4" #数据库编码 + dryRun: false #空跑 + maxIdle: 10 #连接池最大闲置的连接数 + maxOpen: 10 #连接池最大打开的连接数 + maxLifetime: 30 #(单位秒)连接对象可重复使用的时间长度 + +gfToken: + cacheKey: "gfToken_" + timeOut: 10800 + maxRefresh: 5400 + multiLogin: true + encryptKey: "49c54195e750b04e74a8429b17896586" + cacheModel: "redis" + excludePaths: + - "/api/v1/system/xxx" + - "/api/v1/system/xxx2" + +# Redis 配置示例 +redis: + # 单实例配置 + default: + address: 127.0.0.1:6379 + db: 1 + idleTimeout: 600 + maxActive: 100 + +system: + notCheckAuthAdminIds: [1,2,31] #无需验证后台权限的用户id + dataDir: "./resource/data" + cache: + model: "redis" #缓存模式 memory OR redis + prefix: "gFastV3Cache_" #缓存前缀 + +#casbin配置 +casbin: + modelFile: "./resource/casbin/rbac_model.conf" + policyFile: "./resource/casbin/rbac_policy.csv" + + +# CLI. +gfcli: + gen: + dao: + - link: "mysql:gfast3:gfast333@tcp(192.168.0.212:3306)/gfast-v3" + tables: "sys_user_post" + removePrefix: "gf_" + descriptionTag: true + noModelComment: true + path: "./internal/app/system" + +# 上传配置 +upload: + default: 0 # 默认上传至本地 + tencentCOS: + upPath : "/gfast/" + rawUrl : "https://xxxx-xxxxxxxx.cos.ap-xxxxxxxx.myqcloud.com" + secretID : "xxxxxxxxxxxxxxxxxxxxxxxxx" + secretKey : "xxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/manifest/config/initialize.yaml b/manifest/config/initialize.yaml new file mode 100644 index 0000000..f91a4fe --- /dev/null +++ b/manifest/config/initialize.yaml @@ -0,0 +1,4 @@ +initialize: + autoInit: false # 开启系统自动初始化 + configPath: "./manifest/config/db.yaml" # 生成的配置文件所在路径 + sqlFilePath: "./resource/data/gfast-v3.sql" # sql文件所在路径 \ No newline at end of file diff --git a/manifest/deploy/kustomize/base/deployment.yaml b/manifest/deploy/kustomize/base/deployment.yaml new file mode 100644 index 0000000..28f1d69 --- /dev/null +++ b/manifest/deploy/kustomize/base/deployment.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: template-single + labels: + app: template-single +spec: + replicas: 1 + selector: + matchLabels: + app: template-single + template: + metadata: + labels: + app: template-single + spec: + containers: + - name : main + image: template-single + imagePullPolicy: Always + diff --git a/manifest/deploy/kustomize/base/kustomization.yaml b/manifest/deploy/kustomize/base/kustomization.yaml new file mode 100644 index 0000000..302d92d --- /dev/null +++ b/manifest/deploy/kustomize/base/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- deployment.yaml +- service.yaml + + + diff --git a/manifest/deploy/kustomize/base/service.yaml b/manifest/deploy/kustomize/base/service.yaml new file mode 100644 index 0000000..608771c --- /dev/null +++ b/manifest/deploy/kustomize/base/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: template-single +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 8000 + selector: + app: template-single + diff --git a/manifest/deploy/kustomize/overlays/develop/configmap.yaml b/manifest/deploy/kustomize/overlays/develop/configmap.yaml new file mode 100644 index 0000000..3b1d0af --- /dev/null +++ b/manifest/deploy/kustomize/overlays/develop/configmap.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: template-single-configmap +data: + config.yaml: | + server: + address: ":8000" + openapiPath: "/api.json" + swaggerPath: "/swagger" + + logger: + level : "all" + stdout: true diff --git a/manifest/deploy/kustomize/overlays/develop/deployment.yaml b/manifest/deploy/kustomize/overlays/develop/deployment.yaml new file mode 100644 index 0000000..04e4851 --- /dev/null +++ b/manifest/deploy/kustomize/overlays/develop/deployment.yaml @@ -0,0 +1,10 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: template-single +spec: + template: + spec: + containers: + - name : main + image: template-single:develop \ No newline at end of file diff --git a/manifest/deploy/kustomize/overlays/develop/kustomization.yaml b/manifest/deploy/kustomize/overlays/develop/kustomization.yaml new file mode 100644 index 0000000..4731c47 --- /dev/null +++ b/manifest/deploy/kustomize/overlays/develop/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../../base +- configmap.yaml + +patchesStrategicMerge: +- deployment.yaml + +namespace: default + + + diff --git a/manifest/docker/Dockerfile b/manifest/docker/Dockerfile new file mode 100644 index 0000000..399619e --- /dev/null +++ b/manifest/docker/Dockerfile @@ -0,0 +1,19 @@ +FROM loads/alpine:3.8 + +############################################################################### +# INSTALLATION +############################################################################### + +ENV WORKDIR /app + +ADD resource $WORKDIR/ + +ADD ./bin/linux_amd64/main $WORKDIR/main + +RUN chmod +x $WORKDIR/main + +############################################################################### +# START +############################################################################### +WORKDIR $WORKDIR +CMD ./main diff --git a/manifest/docker/docker.sh b/manifest/docker/docker.sh new file mode 100644 index 0000000..ff393f9 --- /dev/null +++ b/manifest/docker/docker.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This shell is executed before docker build. + + + + + diff --git a/resource/casbin/rbac_model.conf b/resource/casbin/rbac_model.conf new file mode 100644 index 0000000..71159e3 --- /dev/null +++ b/resource/casbin/rbac_model.conf @@ -0,0 +1,14 @@ +[request_definition] +r = sub, obj, act + +[policy_definition] +p = sub, obj, act + +[role_definition] +g = _, _ + +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act \ No newline at end of file diff --git a/resource/casbin/rbac_policy.csv b/resource/casbin/rbac_policy.csv new file mode 100644 index 0000000..f93d6df --- /dev/null +++ b/resource/casbin/rbac_policy.csv @@ -0,0 +1,5 @@ +p, alice, data1, read +p, bob, data2, write +p, data2_admin, data2, read +p, data2_admin, data2, write +g, alice, data2_admin \ No newline at end of file diff --git a/resource/data/.gitkeep b/resource/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/data/gfast-v3.sql b/resource/data/gfast-v3.sql new file mode 100644 index 0000000..aab0e78 --- /dev/null +++ b/resource/data/gfast-v3.sql @@ -0,0 +1,1025 @@ +/* + Navicat Premium Data Transfer + + Source Server : localhost + Source Server Type : MySQL + Source Server Version : 50736 + Source Host : localhost:3306 + Source Schema : gfast-v3 + + Target Server Type : MySQL + Target Server Version : 50736 + File Encoding : 65001 + + Date: 22/04/2022 18:17:11 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for casbin_rule +-- ---------------------------- +DROP TABLE IF EXISTS `casbin_rule`; +CREATE TABLE `casbin_rule` ( + `ptype` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v0` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v1` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v2` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v3` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v4` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `v5` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of casbin_rule +-- ---------------------------- +INSERT INTO `casbin_rule` VALUES ('p', '2', '2', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '3', '2', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '4', '2', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '3', '3', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '2', '3', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '5', '4', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '2', '10', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '8', '2', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '8', '4', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '1', '10', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '1', '12', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '1', '13', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '1', '14', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '42', '1', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '42', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '1', '1', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '1', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '2', '3', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '2', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '4', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '5', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '7', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '8', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '10', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '14', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '15', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '16', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '4', '1', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '2', '1', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '8', '1', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('p', '1', '1', 'All', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '6', '2', '', '', '', ''); +INSERT INTO `casbin_rule` VALUES ('g', '3', '2', '', '', '', ''); + +-- ---------------------------- +-- Table structure for sys_auth_rule +-- ---------------------------- +DROP TABLE IF EXISTS `sys_auth_rule`; +CREATE TABLE `sys_auth_rule` ( + `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `pid` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '父ID', + `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则名称', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '规则名称', + `icon` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '图标', + `condition` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '条件', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '备注', + `menu_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '类型 0目录 1菜单 2按钮', + `weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重', + `is_hide` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '显示状态', + `path` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '路由地址', + `component` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '组件路径', + `is_link` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否外链 1是 0否', + `module_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '所属模块', + `model_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '模型ID', + `is_iframe` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否内嵌iframe', + `is_cached` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否缓存', + `redirect` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '路由重定向地址', + `is_affix` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否固定', + `link_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '链接地址', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '修改日期', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `name`(`name`) USING BTREE, + INDEX `pid`(`pid`) USING BTREE, + INDEX `weigh`(`weigh`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '菜单节点表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_auth_rule +-- ---------------------------- +INSERT INTO `sys_auth_rule` VALUES (1, 0, 'api/v1/system/auth', '权限管理', 'ele-Stamp', '', '', 0, 30, 0, '/system/auth', 'layout/routerView/parent', 0, '', 0, 0, 1, '0', 0, '', '2022-03-24 15:03:37', '2022-04-14 16:29:19'); +INSERT INTO `sys_auth_rule` VALUES (2, 1, 'api/v1/system/auth/menuList', '菜单管理', 'ele-Calendar', '', '', 1, 0, 0, '/system/auth/menuList', 'system/menu/index', 0, '', 0, 0, 1, '', 0, '', '2022-03-24 17:24:13', '2022-03-29 10:54:49'); +INSERT INTO `sys_auth_rule` VALUES (3, 2, 'api/v1/system/menu/add', '添加菜单', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-03-29 16:48:43', '2022-03-29 17:05:19'); +INSERT INTO `sys_auth_rule` VALUES (4, 2, 'api/v1/system/menu/update', '修改菜单', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-03-29 17:04:25', '2022-03-29 18:11:36'); +INSERT INTO `sys_auth_rule` VALUES (10, 1, 'api/v1/system/role/list', '角色管理', 'iconfont icon-juxingkaobei', '', '', 1, 0, 0, '/system/auth/roleList', 'system/role/index', 0, '', 0, 0, 1, '', 0, '', '2022-03-29 18:15:03', '2022-03-30 10:25:34'); +INSERT INTO `sys_auth_rule` VALUES (11, 2, 'api/v1/system/menu/delete', '删除菜单', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-06 14:49:10', '2022-04-06 14:49:17'); +INSERT INTO `sys_auth_rule` VALUES (12, 10, 'api/v1/system/role/add', '添加角色', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-06 14:49:46', '2022-04-06 14:49:46'); +INSERT INTO `sys_auth_rule` VALUES (13, 10, '/api/v1/system/role/edit', '修改角色', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-06 14:50:08', '2022-04-06 14:50:08'); +INSERT INTO `sys_auth_rule` VALUES (14, 10, '/api/v1/system/role/delete', '删除角色', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-06 14:50:22', '2022-04-06 14:50:22'); +INSERT INTO `sys_auth_rule` VALUES (15, 1, 'api/v1/system/dept/list', '部门管理', 'iconfont icon-siweidaotu', '', '', 1, 0, 0, '/system/auth/deptList', 'system/dept/index', 0, '', 0, 0, 1, '', 0, '', '2022-04-06 14:52:23', '2022-04-07 22:59:20'); +INSERT INTO `sys_auth_rule` VALUES (16, 17, 'aliyun', '阿里云-iframe', 'iconfont icon-diannao1', '', '', 1, 0, 0, '/demo/outLink/aliyun', 'layout/routerView/iframes', 1, '', 0, 1, 1, '', 0, 'https://www.aliyun.com/daily-act/ecs/activity_selection?spm=5176.8789780.J_3965641470.5.568845b58KHj51', '2022-04-06 17:26:29', '2022-04-07 15:27:17'); +INSERT INTO `sys_auth_rule` VALUES (17, 0, 'outLink', '外链测试', 'iconfont icon-zhongduancanshu', '', '', 0, 20, 0, '/demo/outLink', 'layout/routerView/parent', 0, '', 0, 0, 1, '', 0, '', '2022-04-07 15:20:51', '2022-04-14 16:29:07'); +INSERT INTO `sys_auth_rule` VALUES (18, 17, 'tenyun', '腾讯云-外链', 'iconfont icon-shouye_dongtaihui', '', '', 1, 0, 0, '/demo/outLink/tenyun', 'layout/routerView/link', 1, '', 0, 0, 1, '', 0, 'https://cloud.tencent.com/act/new?cps_key=20b1c3842f74986b2894e2c5fcde7ea2&fromSource=gwzcw.3775555.3775555.3775555&utm_id=gwzcw.3775555.3775555.3775555&utm_medium=cpc', '2022-04-07 15:23:52', '2022-04-07 15:27:25'); +INSERT INTO `sys_auth_rule` VALUES (19, 15, 'api/v1/system/dept/add', '添加部门', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-07 22:56:39', '2022-04-07 22:56:39'); +INSERT INTO `sys_auth_rule` VALUES (20, 15, 'api/v1/system/dept/edit', '修改部门', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-07 22:57:00', '2022-04-07 22:57:00'); +INSERT INTO `sys_auth_rule` VALUES (21, 15, 'api/v1/system/dept/delete', '删除部门', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-07 22:57:30', '2022-04-07 22:57:30'); +INSERT INTO `sys_auth_rule` VALUES (22, 1, 'api/v1/system/post/list', '岗位管理', 'iconfont icon-neiqianshujuchucun', '', '', 1, 0, 0, '/system/auth/postList', 'system/post/index', 0, '', 0, 0, 1, '', 0, '', '2022-04-07 22:58:46', '2022-04-09 14:26:15'); +INSERT INTO `sys_auth_rule` VALUES (23, 22, 'api/v1/system/post/add', '添加岗位', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-09 14:14:49', '2022-04-09 14:14:49'); +INSERT INTO `sys_auth_rule` VALUES (24, 22, 'api/v1/system/post/edit', '修改岗位', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-09 14:15:25', '2022-04-09 14:15:25'); +INSERT INTO `sys_auth_rule` VALUES (25, 22, 'api/v1/system/post/delete', '删除岗位', '', '', '', 2, 0, 0, '', '', 0, '', 0, 0, 1, '', 0, '', '2022-04-09 14:15:47', '2022-04-09 14:15:47'); +INSERT INTO `sys_auth_rule` VALUES (26, 1, 'api/v1/system/user/list', '用户管理', 'ele-User', '', '', 1, 0, 0, '/system/auth/user/list', 'system/user/index', 0, '', 0, 0, 1, '', 0, '', '2022-04-09 14:19:10', '2022-04-09 14:19:58'); +INSERT INTO `sys_auth_rule` VALUES (27, 0, 'api/v1/system/dict', '系统配置', 'iconfont icon-shuxingtu', '', '', 0, 40, 0, '/system/dict', 'layout/routerView/parent', 0, '', 0, 0, 1, '654', 0, '', '2022-04-14 16:28:51', '2022-04-18 14:40:56'); +INSERT INTO `sys_auth_rule` VALUES (28, 27, 'api/v1/system/dict/type/list', '字典管理', 'iconfont icon-crew_feature', '', '', 1, 0, 0, '/system/dict/type/list', 'system/dict/index', 0, '', 0, 0, 1, '', 0, '', '2022-04-14 16:32:10', '2022-04-16 17:02:50'); +INSERT INTO `sys_auth_rule` VALUES (29, 27, 'api/v1/system/dict/dataList', '字典数据管理', 'iconfont icon-putong', '', '', 1, 0, 1, '/system/dict/data/list/:dictType', 'system/dict/dataList', 0, '', 0, 0, 1, '', 0, '', '2022-04-18 12:04:17', '2022-04-18 14:58:43'); +INSERT INTO `sys_auth_rule` VALUES (30, 27, 'api/v1/system/config/list', '参数管理', 'ele-Cherry', '', '', 1, 0, 0, '/system/config/list', 'system/config/index', 0, '', 0, 0, 1, '', 0, '', '2022-04-18 21:05:20', '2022-04-18 21:13:19'); +INSERT INTO `sys_auth_rule` VALUES (31, 0, 'api/v1/system/monitor', '系统监控', 'iconfont icon-xuanzeqi', '', '', 0, 30, 0, '/system/monitor', 'layout/routerView/parent', 0, '', 0, 0, 1, '', 0, '', '2022-04-19 10:40:19', '2022-04-19 10:44:38'); +INSERT INTO `sys_auth_rule` VALUES (32, 31, 'api/v1/system/monitor/server', '服务监控', 'iconfont icon-shuju', '', '', 1, 0, 0, '/system/monitor/server', 'system/monitor/server/index', 0, '', 0, 0, 1, '', 0, '', '2022-04-19 10:43:32', '2022-04-19 10:44:47'); +INSERT INTO `sys_auth_rule` VALUES (33, 31, 'api/swagger', 'api文档', 'iconfont icon--chaifenlie', '', '', 1, 0, 0, '/system/swagger', 'layout/routerView/iframes', 1, '', 0, 1, 1, '', 0, 'http://localhost:8201/swagger', '2022-04-21 09:23:43', '2022-04-21 11:19:49'); + +-- ---------------------------- +-- Table structure for sys_config +-- ---------------------------- +DROP TABLE IF EXISTS `sys_config`; +CREATE TABLE `sys_config` ( + `config_id` int(5) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '参数主键', + `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数名称', + `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数键名', + `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数键值', + `config_type` tinyint(1) NULL DEFAULT 0 COMMENT '系统内置(Y是 N否)', + `create_by` int(64) UNSIGNED NULL DEFAULT 0 COMMENT '创建者', + `update_by` int(64) UNSIGNED NULL DEFAULT 0 COMMENT '更新者', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + PRIMARY KEY (`config_id`) USING BTREE, + UNIQUE INDEX `uni_config_key`(`config_key`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_config +-- ---------------------------- +INSERT INTO `sys_config` VALUES (1, '文件上传-文件大小', 'sys.uploadFile.fileSize', '50M', 1, 31, 31, '文件上传大小限制', NULL, '2021-07-06 14:57:35'); +INSERT INTO `sys_config` VALUES (2, '文件上传-文件类型', 'sys.uploadFile.fileType', 'doc,docx,zip,xls,xlsx,rar,jpg,jpeg,gif,npm,png', 1, 31, 31, '文件上传后缀类型限制', NULL, NULL); +INSERT INTO `sys_config` VALUES (3, '图片上传-图片类型', 'sys.uploadFile.imageType', 'jpg,jpeg,gif,npm,png', 1, 31, 0, '图片上传后缀类型限制', NULL, NULL); +INSERT INTO `sys_config` VALUES (4, '图片上传-图片大小', 'sys.uploadFile.imageSize', '50M', 1, 31, 31, '图片上传大小限制', NULL, NULL); +INSERT INTO `sys_config` VALUES (11, '静态资源', 'static.resource', '/', 1, 2, 0, '', NULL, NULL); + +-- ---------------------------- +-- Table structure for sys_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dept`; +CREATE TABLE `sys_dept` ( + `dept_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '部门id', + `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父部门id', + `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '祖级列表', + `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '部门名称', + `order_num` int(4) NULL DEFAULT 0 COMMENT '显示顺序', + `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '负责人', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系电话', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱', + `status` tinyint(3) UNSIGNED NULL DEFAULT 0 COMMENT '部门状态(0正常 1停用)', + `created_by` bigint(20) UNSIGNED NULL DEFAULT 0 COMMENT '创建人', + `updated_by` bigint(20) NULL DEFAULT NULL COMMENT '修改人', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + `deleted_at` datetime(0) NULL DEFAULT NULL COMMENT '删除时间', + PRIMARY KEY (`dept_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 204 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '部门表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_dept +-- ---------------------------- +INSERT INTO `sys_dept` VALUES (100, 0, '0', '奇讯科技', 0, '若依', '15888888888', 'ry@qq.com', 1, 0, 31, '2021-07-13 15:56:52', '2021-07-13 15:57:05', NULL); +INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', 1, 0, 31, '2021-07-13 15:56:52', '2021-11-04 09:16:38', NULL); +INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (200, 100, '', '大数据', 1, '小刘', '18888888888', 'liou@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (201, 100, '', '开发', 1, '老李', '18888888888', 'li@qq.com', 0, 31, NULL, '2021-07-13 15:56:52', '2022-04-07 22:35:21', NULL); +INSERT INTO `sys_dept` VALUES (202, 108, '', '外勤', 1, '小a', '18888888888', 'aa@qq.com', 1, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); +INSERT INTO `sys_dept` VALUES (203, 108, '', '行政', 0, 'aa', '18888888888', 'aa@qq.com', 0, 0, NULL, '2021-07-13 15:56:52', '2021-07-13 15:56:52', NULL); + +-- ---------------------------- +-- Table structure for sys_dict_data +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_data`; +CREATE TABLE `sys_dict_data` ( + `dict_code` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '字典编码', + `dict_sort` int(4) NULL DEFAULT 0 COMMENT '字典排序', + `dict_label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典标签', + `dict_value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典键值', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', + `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '样式属性(其他样式扩展)', + `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表格回显样式', + `is_default` tinyint(1) NULL DEFAULT 0 COMMENT '是否默认(1是 0否)', + `status` tinyint(1) NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `create_by` bigint(64) UNSIGNED NULL DEFAULT 0 COMMENT '创建者', + `update_by` bigint(64) UNSIGNED NULL DEFAULT 0 COMMENT '更新者', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + PRIMARY KEY (`dict_code`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 102 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典数据表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_dict_data +-- ---------------------------- +INSERT INTO `sys_dict_data` VALUES (1, 0, '男', '1', 'sys_user_sex', '', '', 0, 1, 31, 2, '备注信息', '2022-04-18 16:46:22', NULL); +INSERT INTO `sys_dict_data` VALUES (2, 0, '女', '2', 'sys_user_sex', '', '', 0, 1, 31, 31, '备注信息', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (3, 0, '保密', '0', 'sys_user_sex', '', '', 1, 1, 31, 31, '备注信息', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (24, 0, '频道页', '1', 'cms_category_type', '', '', 0, 1, 31, 31, '作为频道页,不可作为栏目发布文章,可添加下级分类', NULL, '2021-07-21 10:54:22'); +INSERT INTO `sys_dict_data` VALUES (25, 0, '发布栏目', '2', 'cms_category_type', '', '', 0, 1, 31, 31, '作为发布栏目,可添加文章', NULL, '2021-07-21 10:54:22'); +INSERT INTO `sys_dict_data` VALUES (26, 0, '跳转栏目', '3', 'cms_category_type', '', '', 0, 1, 31, 31, '不直接发布内容,用于跳转页面', NULL, '2021-07-21 10:54:22'); +INSERT INTO `sys_dict_data` VALUES (27, 0, '单页栏目', '4', 'cms_category_type', '', '', 0, 1, 31, 31, '单页面模式,分类直接显示为文章', NULL, '2021-07-21 10:54:22'); +INSERT INTO `sys_dict_data` VALUES (28, 0, '正常', '0', 'sys_job_status', '', 'default', 1, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (29, 0, '暂停', '1', 'sys_job_status', '', 'default', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (30, 0, '默认', 'DEFAULT', 'sys_job_group', '', 'default', 1, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (31, 0, '系统', 'SYSTEM', 'sys_job_group', '', 'default', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (32, 0, '成功', '1', 'admin_login_status', '', 'default', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (33, 0, '失败', '0', 'admin_login_status', '', 'default', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (34, 0, '成功', '1', 'sys_oper_log_status', '', 'default', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (35, 0, '失败', '0', 'sys_oper_log_status', '', 'default', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (36, 0, '重复执行', '1', 'sys_job_policy', '', 'default', 1, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (37, 0, '执行一次', '2', 'sys_job_policy', '', 'default', 1, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (38, 0, '显示', '0', 'sys_show_hide', NULL, 'default', 1, 1, 31, 0, NULL, NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (39, 0, '隐藏', '1', 'sys_show_hide', NULL, 'default', 0, 1, 31, 0, NULL, NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (40, 0, '正常', '1', 'sys_normal_disable', '', 'default', 1, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (41, 0, '停用', '0', 'sys_normal_disable', '', 'default', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (49, 0, '是', '1', 'sys_yes_no', '', '', 1, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (50, 0, '否', '0', 'sys_yes_no', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (51, 0, '已发布', '1', 'cms_article_pub_type', '', '', 1, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (54, 0, '未发布', '0', 'cms_article_pub_type', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (55, 0, '置顶', '1', 'cms_article_attr', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (56, 0, '推荐', '2', 'cms_article_attr', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (57, 0, '普通文章', '0', 'cms_article_type', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (58, 0, '跳转链接', '1', 'cms_article_type', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (59, 0, 'cms模型', '6', 'cms_cate_models', '', '', 0, 1, 1, 1, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (61, 0, '政府工作目标', '1', 'gov_cate_models', '', '', 0, 1, 2, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (62, 0, '系统后台', 'sys_admin', 'menu_module_type', '', '', 1, 1, 2, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (63, 0, '政务工作', 'gov_work', 'menu_module_type', '', '', 0, 1, 2, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (64, 0, '幻灯', '3', 'cms_article_attr', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (65, 0, '[work]测试业务表', 'wf_news', 'flow_type', '', '', 0, 1, 2, 2, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (66, 0, '回退修改', '-1', 'flow_status', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (67, 0, '保存中', '0', 'flow_status', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (68, 0, '流程中', '1', 'flow_status', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (69, 0, '审批通过', '2', 'flow_status', '', '', 0, 1, 31, 2, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (70, 2, '发布栏目', '2', 'sys_blog_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (71, 3, '跳转栏目', '3', 'sys_blog_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (72, 4, '单页栏目', '4', 'sys_blog_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (73, 2, '置顶', '1', 'sys_log_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (74, 3, '幻灯', '2', 'sys_log_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (75, 4, '推荐', '3', 'sys_log_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (76, 1, '一般', '0', 'sys_log_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (77, 1, '频道页', '1', 'sys_blog_sign', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (78, 0, '普通', '0', 'flow_level', '', '', 0, 1, 31, 0, '', NULL, '2021-07-20 08:55:20'); +INSERT INTO `sys_dict_data` VALUES (79, 0, '加急', '1', 'flow_level', '', '', 0, 1, 31, 0, '', NULL, '2021-07-20 08:55:20'); +INSERT INTO `sys_dict_data` VALUES (80, 0, '紧急', '2', 'flow_level', '', '', 0, 1, 31, 0, '', NULL, '2021-07-20 08:55:20'); +INSERT INTO `sys_dict_data` VALUES (81, 0, '特急', '3', 'flow_level', '', '', 0, 1, 31, 31, '', NULL, '2021-07-20 08:55:25'); +INSERT INTO `sys_dict_data` VALUES (82, 0, '频道页', '1', 'sys_blog_type', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (83, 0, '发布栏目', '2', 'sys_blog_type', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (84, 0, '跳转栏目', '3', 'sys_blog_type', '', '', 0, 1, 31, 31, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (85, 0, '单页栏目', '4', 'sys_blog_type', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (87, 0, '[cms]文章表', 'cms_news', 'flow_type', '', '', 0, 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_data` VALUES (91, 0, '测试一下', '666', 'cms_article_type', '', '', 0, 1, 31, 0, '', '2021-08-03 17:04:12', '2021-08-03 17:04:12'); +INSERT INTO `sys_dict_data` VALUES (92, 0, '缓存测试222', '33333', 'cms_article_type', '', '', 0, 1, 31, 31, '', '2021-08-03 17:16:45', '2021-08-03 17:19:41'); +INSERT INTO `sys_dict_data` VALUES (93, 0, '缓存测试222', '11111', 'cms_article_type', '', '', 0, 1, 31, 31, '', '2021-08-03 17:26:14', '2021-08-03 17:26:26'); +INSERT INTO `sys_dict_data` VALUES (94, 0, '1折', '10', 'plugin_store_discount', '', '', 0, 1, 31, 0, '', '2021-08-14 11:59:38', '2021-08-14 11:59:38'); +INSERT INTO `sys_dict_data` VALUES (95, 0, '5折', '50', 'plugin_store_discount', '', '', 0, 1, 31, 0, '', '2021-08-14 11:59:49', '2021-08-14 11:59:49'); +INSERT INTO `sys_dict_data` VALUES (96, 0, '8折', '80', 'plugin_store_discount', '', '', 0, 1, 31, 0, '', '2021-08-14 12:00:00', '2021-08-14 12:00:00'); +INSERT INTO `sys_dict_data` VALUES (97, 0, '9折', '90', 'plugin_store_discount', '', '', 0, 1, 31, 0, '', '2021-08-14 12:00:07', '2021-08-14 12:00:07'); +INSERT INTO `sys_dict_data` VALUES (98, 0, '无折扣', '100', 'plugin_store_discount', '', '', 0, 1, 31, 0, '', '2021-08-14 12:00:16', '2021-08-14 12:00:16'); +INSERT INTO `sys_dict_data` VALUES (99, 0, '不显示', 'none', 'cms_nav_position', '', '', 1, 1, 22, 0, '', '2021-08-31 15:37:35', '2021-08-31 15:37:35'); +INSERT INTO `sys_dict_data` VALUES (100, 0, '顶部导航', 'top', 'cms_nav_position', '', '', 0, 1, 22, 0, '', '2021-08-31 15:37:57', '2021-08-31 15:37:57'); +INSERT INTO `sys_dict_data` VALUES (101, 0, '底部导航', 'bottom', 'cms_nav_position', '', '', 0, 1, 22, 0, '', '2021-08-31 15:38:08', '2021-08-31 15:38:08'); + +-- ---------------------------- +-- Table structure for sys_dict_type +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_type`; +CREATE TABLE `sys_dict_type` ( + `dict_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '字典主键', + `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典名称', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', + `status` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `create_by` int(64) UNSIGNED NULL DEFAULT 0 COMMENT '创建者', + `update_by` int(64) UNSIGNED NULL DEFAULT 0 COMMENT '更新者', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '修改日期', + PRIMARY KEY (`dict_id`) USING BTREE, + UNIQUE INDEX `dict_type`(`dict_type`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 50 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典类型表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_dict_type +-- ---------------------------- +INSERT INTO `sys_dict_type` VALUES (1, '用户性别', 'sys_user_sex', 1, 31, 1, '用于选择用户性别', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (2, '分类类型', 'cms_category_type', 1, 31, 3, '文章分类类型', NULL, '2021-07-21 10:54:22'); +INSERT INTO `sys_dict_type` VALUES (3, '任务状态', 'sys_job_status', 1, 31, 31, '任务状态列表', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (13, '任务分组', 'sys_job_group', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (14, '管理员登录状态', 'admin_login_status', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (15, '操作日志状态', 'sys_oper_log_status', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (16, '任务策略', 'sys_job_policy', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (17, '菜单状态', 'sys_show_hide', 1, 31, 0, '菜单状态', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (18, '系统开关', 'sys_normal_disable', 1, 31, 31, '系统开关', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (24, '系统内置', 'sys_yes_no', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (25, '文章发布状态', 'cms_article_pub_type', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (26, '文章附加状态', 'cms_article_attr', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (27, '文章类型', 'cms_article_type', 1, 31, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (28, '文章栏目模型分类', 'cms_cate_models', 1, 1, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (29, '政务工作模型分类', 'gov_cate_models', 1, 2, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (30, '菜单模块类型', 'menu_module_type', 1, 2, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (31, '工作流程类型', 'flow_type', 1, 2, 0, '', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (32, '工作流程审批状态', 'flow_status', 1, 31, 0, '工作流程审批状态', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (33, '博客分类类型', 'sys_blog_type', 1, 31, 31, '博客分类中的标志', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (34, '博客日志标志', 'sys_log_sign', 1, 31, 0, '博客日志管理中的标志数据字典', NULL, NULL); +INSERT INTO `sys_dict_type` VALUES (35, '工作流紧急状态', 'flow_level', 1, 31, 31, '', NULL, '2021-07-20 08:55:20'); +INSERT INTO `sys_dict_type` VALUES (48, '插件商城折扣', 'plugin_store_discount', 1, 31, 0, '', '2021-08-14 11:59:26', '2021-08-14 11:59:26'); +INSERT INTO `sys_dict_type` VALUES (49, 'CMS栏目导航位置', 'cms_nav_position', 1, 22, 0, '', '2021-08-31 15:37:04', '2021-08-31 15:37:04'); + +-- ---------------------------- +-- Table structure for sys_login_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_login_log`; +CREATE TABLE `sys_login_log` ( + `info_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '访问ID', + `login_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录账号', + `ipaddr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录IP地址', + `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录地点', + `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '浏览器类型', + `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作系统', + `status` tinyint(4) NULL DEFAULT 0 COMMENT '登录状态(0成功 1失败)', + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '提示消息', + `login_time` datetime(0) NULL DEFAULT NULL COMMENT '登录时间', + `module` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录模块', + PRIMARY KEY (`info_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 886 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统访问记录' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_login_log +-- ---------------------------- +INSERT INTO `sys_login_log` VALUES (449, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 12:14:56', '系统后台'); +INSERT INTO `sys_login_log` VALUES (450, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 14:23:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (451, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 14:23:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (452, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 14:25:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (453, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:30:17', '系统后台'); +INSERT INTO `sys_login_log` VALUES (454, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:31:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (455, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:32:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (456, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:39:41', '系统后台'); +INSERT INTO `sys_login_log` VALUES (457, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:39:45', '系统后台'); +INSERT INTO `sys_login_log` VALUES (458, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:41:04', '系统后台'); +INSERT INTO `sys_login_log` VALUES (459, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:42:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (460, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:45:02', '系统后台'); +INSERT INTO `sys_login_log` VALUES (461, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:45:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (462, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:45:45', '系统后台'); +INSERT INTO `sys_login_log` VALUES (463, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:45:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (464, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:46:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (465, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:46:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (466, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:47:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (467, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:47:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (468, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 17:47:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (469, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:02:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (470, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:03:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (471, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:04:29', '系统后台'); +INSERT INTO `sys_login_log` VALUES (472, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:06:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (473, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:08:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (474, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:08:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (475, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:10:19', '系统后台'); +INSERT INTO `sys_login_log` VALUES (476, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:15:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (477, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:18:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (478, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:18:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (479, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-08 18:24:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (480, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 09:22:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (481, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 11:04:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (482, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 11:09:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (483, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 15:50:29', '系统后台'); +INSERT INTO `sys_login_log` VALUES (484, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 15:51:35', '系统后台'); +INSERT INTO `sys_login_log` VALUES (485, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 15:52:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (486, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 15:53:34', '系统后台'); +INSERT INTO `sys_login_log` VALUES (487, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 16:54:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (488, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 16:58:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (489, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 16:59:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (490, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 17:02:25', '系统后台'); +INSERT INTO `sys_login_log` VALUES (491, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 17:03:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (492, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-09 17:05:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (493, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:21:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (494, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:22:03', '系统后台'); +INSERT INTO `sys_login_log` VALUES (495, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:22:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (496, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:31:53', '系统后台'); +INSERT INTO `sys_login_log` VALUES (497, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:32:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (498, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:39:56', '系统后台'); +INSERT INTO `sys_login_log` VALUES (499, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:55:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (500, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:56:15', '系统后台'); +INSERT INTO `sys_login_log` VALUES (501, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:58:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (502, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:58:51', '系统后台'); +INSERT INTO `sys_login_log` VALUES (503, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 10:59:58', '系统后台'); +INSERT INTO `sys_login_log` VALUES (504, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 11:01:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (505, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 11:01:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (506, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:32:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (507, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:34:53', '系统后台'); +INSERT INTO `sys_login_log` VALUES (508, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:34:55', '系统后台'); +INSERT INTO `sys_login_log` VALUES (509, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:35:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (510, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:35:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (511, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:36:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (512, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:36:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (513, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-11 16:37:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (514, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 09:46:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (515, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 09:51:58', '系统后台'); +INSERT INTO `sys_login_log` VALUES (516, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 09:55:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (517, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 10:57:45', '系统后台'); +INSERT INTO `sys_login_log` VALUES (518, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 10:58:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (519, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 11:39:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (520, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 11:40:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (521, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 11:40:40', '系统后台'); +INSERT INTO `sys_login_log` VALUES (522, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:13:48', '系统后台'); +INSERT INTO `sys_login_log` VALUES (523, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:13:57', '系统后台'); +INSERT INTO `sys_login_log` VALUES (524, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:14:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (525, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:14:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (526, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:14:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (527, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (528, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:26', '系统后台'); +INSERT INTO `sys_login_log` VALUES (529, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (530, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:29', '系统后台'); +INSERT INTO `sys_login_log` VALUES (531, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (532, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (533, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (534, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (535, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:15:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (536, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:16:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (537, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:16:17', '系统后台'); +INSERT INTO `sys_login_log` VALUES (538, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:16:19', '系统后台'); +INSERT INTO `sys_login_log` VALUES (539, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:16:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (540, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-14 15:16:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (541, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 09:18:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (542, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 09:20:55', '系统后台'); +INSERT INTO `sys_login_log` VALUES (543, 'asda', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:17:33', '系统后台'); +INSERT INTO `sys_login_log` VALUES (544, 'asdasd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:19:02', '系统后台'); +INSERT INTO `sys_login_log` VALUES (545, 'sadasd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:21:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (546, 'sadasd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:21:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (547, 'asd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:23:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (548, 'asd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:23:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (549, 'asd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:23:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (550, 'asd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:25:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (551, 'asd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:25:25', '系统后台'); +INSERT INTO `sys_login_log` VALUES (552, 'sada', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:27:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (553, 'asd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:28:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (554, 'sadas', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:41:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (555, 'sadas', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:41:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (556, 'asdasd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:42:10', '系统后台'); +INSERT INTO `sys_login_log` VALUES (557, 'asdasd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:42:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (558, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:42:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (559, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:42:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (560, 'sda', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:43:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (561, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:45:53', '系统后台'); +INSERT INTO `sys_login_log` VALUES (562, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:45:58', '系统后台'); +INSERT INTO `sys_login_log` VALUES (563, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:45:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (564, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:46:01', '系统后台'); +INSERT INTO `sys_login_log` VALUES (565, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:46:03', '系统后台'); +INSERT INTO `sys_login_log` VALUES (566, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:46:04', '系统后台'); +INSERT INTO `sys_login_log` VALUES (567, 'dema', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-15 14:46:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (568, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:46:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (569, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:46:16', '系统后台'); +INSERT INTO `sys_login_log` VALUES (570, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:46:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (571, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:46:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (572, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:48:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (573, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:49:26', '系统后台'); +INSERT INTO `sys_login_log` VALUES (574, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:49:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (575, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:49:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (576, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:49:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (577, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:59:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (578, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 14:59:55', '系统后台'); +INSERT INTO `sys_login_log` VALUES (579, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:02:02', '系统后台'); +INSERT INTO `sys_login_log` VALUES (580, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:03:01', '系统后台'); +INSERT INTO `sys_login_log` VALUES (581, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:04:25', '系统后台'); +INSERT INTO `sys_login_log` VALUES (582, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:04:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (583, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:04:34', '系统后台'); +INSERT INTO `sys_login_log` VALUES (584, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:05:50', '系统后台'); +INSERT INTO `sys_login_log` VALUES (585, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:06:36', '系统后台'); +INSERT INTO `sys_login_log` VALUES (586, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:10:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (587, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:11:17', '系统后台'); +INSERT INTO `sys_login_log` VALUES (588, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:12:15', '系统后台'); +INSERT INTO `sys_login_log` VALUES (589, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:13:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (590, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:15:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (591, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:16:02', '系统后台'); +INSERT INTO `sys_login_log` VALUES (592, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:20:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (593, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:21:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (594, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:21:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (595, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:21:56', '系统后台'); +INSERT INTO `sys_login_log` VALUES (596, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:26:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (597, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:49:34', '系统后台'); +INSERT INTO `sys_login_log` VALUES (598, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:49:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (599, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:57:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (600, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 15:57:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (601, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 16:00:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (602, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 16:02:47', '系统后台'); +INSERT INTO `sys_login_log` VALUES (603, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 16:02:58', '系统后台'); +INSERT INTO `sys_login_log` VALUES (604, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 16:10:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (605, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 16:30:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (606, 'admin', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 16:31:16', '系统后台'); +INSERT INTO `sys_login_log` VALUES (607, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 16:31:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (608, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 16:33:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (609, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 16:34:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (610, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 17:55:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (611, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 17:56:40', '系统后台'); +INSERT INTO `sys_login_log` VALUES (612, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 17:57:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (613, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 18:00:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (614, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-15 18:01:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (615, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 18:05:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (616, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 18:21:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (617, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 18:21:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (618, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 18:22:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (619, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-15 18:23:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (620, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 09:30:54', '系统后台'); +INSERT INTO `sys_login_log` VALUES (621, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 09:57:49', '系统后台'); +INSERT INTO `sys_login_log` VALUES (622, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 09:58:17', '系统后台'); +INSERT INTO `sys_login_log` VALUES (623, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 10:14:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (624, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 10:20:26', '系统后台'); +INSERT INTO `sys_login_log` VALUES (625, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 10:22:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (626, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 10:22:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (627, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 10:22:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (628, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 10:22:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (629, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 10:32:10', '系统后台'); +INSERT INTO `sys_login_log` VALUES (630, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 10:32:49', '系统后台'); +INSERT INTO `sys_login_log` VALUES (631, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 11:30:03', '系统后台'); +INSERT INTO `sys_login_log` VALUES (632, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 12:03:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (633, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 12:06:17', '系统后台'); +INSERT INTO `sys_login_log` VALUES (634, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 14:14:50', '系统后台'); +INSERT INTO `sys_login_log` VALUES (635, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 15:57:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (636, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 16:43:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (637, 'demosada', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:17:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (638, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:17:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (639, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:17:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (640, 'demoasdasd', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:17:53', '系统后台'); +INSERT INTO `sys_login_log` VALUES (641, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:18:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (642, 'zsasda', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:18:26', '系统后台'); +INSERT INTO `sys_login_log` VALUES (643, 'zsa', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:18:41', '系统后台'); +INSERT INTO `sys_login_log` VALUES (644, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:18:48', '系统后台'); +INSERT INTO `sys_login_log` VALUES (645, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:19:45', '系统后台'); +INSERT INTO `sys_login_log` VALUES (646, 'demo55', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:21:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (647, 'demo4564646', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:21:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (648, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:21:56', '系统后台'); +INSERT INTO `sys_login_log` VALUES (649, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:22:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (650, 'demo2', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:24:11', '系统后台'); +INSERT INTO `sys_login_log` VALUES (651, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:24:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (652, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:25:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (653, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:25:22', '系统后台'); +INSERT INTO `sys_login_log` VALUES (654, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:25:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (655, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-16 17:25:56', '系统后台'); +INSERT INTO `sys_login_log` VALUES (656, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:26:03', '系统后台'); +INSERT INTO `sys_login_log` VALUES (657, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:26:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (658, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:27:17', '系统后台'); +INSERT INTO `sys_login_log` VALUES (659, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:27:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (660, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:28:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (661, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:28:10', '系统后台'); +INSERT INTO `sys_login_log` VALUES (662, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:28:31', '系统后台'); +INSERT INTO `sys_login_log` VALUES (663, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:29:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (664, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-16 17:30:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (665, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:30:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (666, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:31:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (667, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:31:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (668, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:32:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (669, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:37:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (670, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:42:16', '系统后台'); +INSERT INTO `sys_login_log` VALUES (671, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:44:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (672, 'zsss', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:45:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (673, 'zsss', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:45:29', '系统后台'); +INSERT INTO `sys_login_log` VALUES (674, 'zsss', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-16 17:45:34', '系统后台'); +INSERT INTO `sys_login_log` VALUES (675, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 17:50:57', '系统后台'); +INSERT INTO `sys_login_log` VALUES (676, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 18:05:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (677, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 18:18:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (678, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 18:22:40', '系统后台'); +INSERT INTO `sys_login_log` VALUES (679, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 18:24:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (680, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 18:24:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (681, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-16 18:24:51', '系统后台'); +INSERT INTO `sys_login_log` VALUES (682, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:00:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (683, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:04:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (684, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:05:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (685, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 10:29:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (686, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 10:35:19', '系统后台'); +INSERT INTO `sys_login_log` VALUES (687, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 10:43:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (688, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-17 10:45:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (689, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 10:45:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (690, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-17 10:45:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (691, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 0, '账号密码错误', '2022-03-17 10:46:50', '系统后台'); +INSERT INTO `sys_login_log` VALUES (692, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 10:47:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (693, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 10:48:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (694, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 10:51:19', '系统后台'); +INSERT INTO `sys_login_log` VALUES (695, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:52:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (696, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:55:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (697, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:55:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (698, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:55:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (699, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:55:45', '系统后台'); +INSERT INTO `sys_login_log` VALUES (700, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 10:57:36', '系统后台'); +INSERT INTO `sys_login_log` VALUES (701, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:06:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (702, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:09:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (703, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:11:10', '系统后台'); +INSERT INTO `sys_login_log` VALUES (704, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:26:31', '系统后台'); +INSERT INTO `sys_login_log` VALUES (705, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:30:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (706, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:36:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (707, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:42:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (708, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:45:25', '系统后台'); +INSERT INTO `sys_login_log` VALUES (709, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 11:54:51', '系统后台'); +INSERT INTO `sys_login_log` VALUES (710, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 14:41:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (711, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 14:45:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (712, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 14:55:57', '系统后台'); +INSERT INTO `sys_login_log` VALUES (713, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:15:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (714, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:20:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (715, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:21:49', '系统后台'); +INSERT INTO `sys_login_log` VALUES (716, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:24:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (717, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:46:38', '系统后台'); +INSERT INTO `sys_login_log` VALUES (718, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:48:02', '系统后台'); +INSERT INTO `sys_login_log` VALUES (719, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:49:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (720, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:50:36', '系统后台'); +INSERT INTO `sys_login_log` VALUES (721, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:51:48', '系统后台'); +INSERT INTO `sys_login_log` VALUES (722, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:54:50', '系统后台'); +INSERT INTO `sys_login_log` VALUES (723, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:56:04', '系统后台'); +INSERT INTO `sys_login_log` VALUES (724, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:57:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (725, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 15:58:24', '系统后台'); +INSERT INTO `sys_login_log` VALUES (726, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 16:04:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (727, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:04:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (728, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 16:10:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (729, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:13:49', '系统后台'); +INSERT INTO `sys_login_log` VALUES (730, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:16:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (731, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:32:57', '系统后台'); +INSERT INTO `sys_login_log` VALUES (732, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:39:26', '系统后台'); +INSERT INTO `sys_login_log` VALUES (733, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:42:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (734, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:44:38', '系统后台'); +INSERT INTO `sys_login_log` VALUES (735, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:46:11', '系统后台'); +INSERT INTO `sys_login_log` VALUES (736, 'zs', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:48:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (737, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 16:54:33', '系统后台'); +INSERT INTO `sys_login_log` VALUES (738, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-17 17:06:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (739, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 17:55:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (740, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-17 18:07:51', '系统后台'); +INSERT INTO `sys_login_log` VALUES (741, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-18 09:44:38', '系统后台'); +INSERT INTO `sys_login_log` VALUES (742, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-18 14:29:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (743, 'zs', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-18 15:22:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (744, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-18 15:22:29', '系统后台'); +INSERT INTO `sys_login_log` VALUES (745, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 09:21:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (746, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 14:14:54', '系统后台'); +INSERT INTO `sys_login_log` VALUES (747, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 14:14:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (748, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 14:15:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (749, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 14:16:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (750, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 14:38:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (751, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 15:17:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (752, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 15:29:55', '系统后台'); +INSERT INTO `sys_login_log` VALUES (753, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 15:58:22', '系统后台'); +INSERT INTO `sys_login_log` VALUES (754, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-21 18:06:31', '系统后台'); +INSERT INTO `sys_login_log` VALUES (755, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-22 09:01:15', '系统后台'); +INSERT INTO `sys_login_log` VALUES (756, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-22 09:11:55', '系统后台'); +INSERT INTO `sys_login_log` VALUES (757, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 09:00:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (758, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-24 09:59:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (759, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 14:45:09', '系统后台'); +INSERT INTO `sys_login_log` VALUES (760, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 14:47:54', '系统后台'); +INSERT INTO `sys_login_log` VALUES (761, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 14:48:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (762, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 14:52:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (763, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 15:02:19', '系统后台'); +INSERT INTO `sys_login_log` VALUES (764, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 15:02:36', '系统后台'); +INSERT INTO `sys_login_log` VALUES (765, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-24 15:05:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (766, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 17:06:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (767, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-24 17:09:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (768, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-25 15:08:31', '系统后台'); +INSERT INTO `sys_login_log` VALUES (769, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-25 15:11:56', '系统后台'); +INSERT INTO `sys_login_log` VALUES (770, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-25 15:12:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (771, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-25 16:06:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (772, 'demo2', '127.0.0.1', '内网IP', 'ApiPOST', '', 0, '账号密码错误', '2022-03-25 16:41:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (773, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-28 10:24:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (774, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-28 10:37:47', '系统后台'); +INSERT INTO `sys_login_log` VALUES (775, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-28 14:27:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (776, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-28 14:29:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (777, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-28 16:27:11', '系统后台'); +INSERT INTO `sys_login_log` VALUES (778, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-29 10:10:16', '系统后台'); +INSERT INTO `sys_login_log` VALUES (779, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-29 10:49:47', '系统后台'); +INSERT INTO `sys_login_log` VALUES (780, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 09:06:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (781, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-30 09:58:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (782, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 10:19:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (783, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 10:20:01', '系统后台'); +INSERT INTO `sys_login_log` VALUES (784, 'test', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 10:50:40', '系统后台'); +INSERT INTO `sys_login_log` VALUES (785, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 10:51:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (786, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 11:08:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (787, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 11:09:44', '系统后台'); +INSERT INTO `sys_login_log` VALUES (788, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 11:09:49', '系统后台'); +INSERT INTO `sys_login_log` VALUES (789, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 11:23:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (790, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-30 11:41:01', '系统后台'); +INSERT INTO `sys_login_log` VALUES (791, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-03-30 11:44:36', '系统后台'); +INSERT INTO `sys_login_log` VALUES (792, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-03-31 09:34:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (793, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-01 10:09:45', '系统后台'); +INSERT INTO `sys_login_log` VALUES (794, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-01 10:13:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (795, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-01 10:16:04', '系统后台'); +INSERT INTO `sys_login_log` VALUES (796, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-01 15:02:11', '系统后台'); +INSERT INTO `sys_login_log` VALUES (797, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-02 09:15:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (798, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-02 09:15:34', '系统后台'); +INSERT INTO `sys_login_log` VALUES (799, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-02 09:59:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (800, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-02 11:04:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (801, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-06 09:51:48', '系统后台'); +INSERT INTO `sys_login_log` VALUES (802, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-06 16:21:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (803, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-06 17:40:57', '系统后台'); +INSERT INTO `sys_login_log` VALUES (804, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-07 09:34:50', '系统后台'); +INSERT INTO `sys_login_log` VALUES (805, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-07 15:17:03', '系统后台'); +INSERT INTO `sys_login_log` VALUES (806, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-07 15:58:53', '系统后台'); +INSERT INTO `sys_login_log` VALUES (807, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-07 22:13:22', '系统后台'); +INSERT INTO `sys_login_log` VALUES (808, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-08 09:26:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (809, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-08 12:03:47', '系统后台'); +INSERT INTO `sys_login_log` VALUES (810, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-08 14:17:47', '系统后台'); +INSERT INTO `sys_login_log` VALUES (811, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-08 14:24:23', '系统后台'); +INSERT INTO `sys_login_log` VALUES (812, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-09 12:58:53', '系统后台'); +INSERT INTO `sys_login_log` VALUES (813, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-11 09:01:47', '系统后台'); +INSERT INTO `sys_login_log` VALUES (814, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-11 09:13:10', '系统后台'); +INSERT INTO `sys_login_log` VALUES (815, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-11 09:36:58', '系统后台'); +INSERT INTO `sys_login_log` VALUES (816, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-11 16:42:45', '系统后台'); +INSERT INTO `sys_login_log` VALUES (817, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-12 08:59:10', '系统后台'); +INSERT INTO `sys_login_log` VALUES (818, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-12 09:11:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (819, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-12 14:20:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (820, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-12 16:13:56', '系统后台'); +INSERT INTO `sys_login_log` VALUES (821, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-13 09:30:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (822, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-13 11:51:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (823, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-13 15:00:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (824, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-13 15:07:04', '系统后台'); +INSERT INTO `sys_login_log` VALUES (825, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 11:38:33', '系统后台'); +INSERT INTO `sys_login_log` VALUES (826, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 15:08:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (827, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 15:09:03', '系统后台'); +INSERT INTO `sys_login_log` VALUES (828, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 15:11:46', '系统后台'); +INSERT INTO `sys_login_log` VALUES (829, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 15:40:42', '系统后台'); +INSERT INTO `sys_login_log` VALUES (830, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 15:41:48', '系统后台'); +INSERT INTO `sys_login_log` VALUES (831, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 15:46:52', '系统后台'); +INSERT INTO `sys_login_log` VALUES (832, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 15:48:41', '系统后台'); +INSERT INTO `sys_login_log` VALUES (833, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 17:50:00', '系统后台'); +INSERT INTO `sys_login_log` VALUES (834, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 18:08:01', '系统后台'); +INSERT INTO `sys_login_log` VALUES (835, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-14 21:10:21', '系统后台'); +INSERT INTO `sys_login_log` VALUES (836, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-16 10:07:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (837, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-16 10:48:15', '系统后台'); +INSERT INTO `sys_login_log` VALUES (838, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 11:15:08', '系统后台'); +INSERT INTO `sys_login_log` VALUES (839, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 11:15:16', '系统后台'); +INSERT INTO `sys_login_log` VALUES (840, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 11:15:18', '系统后台'); +INSERT INTO `sys_login_log` VALUES (841, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 11:15:20', '系统后台'); +INSERT INTO `sys_login_log` VALUES (842, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 15:59:10', '系统后台'); +INSERT INTO `sys_login_log` VALUES (843, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 15:59:12', '系统后台'); +INSERT INTO `sys_login_log` VALUES (844, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 15:59:14', '系统后台'); +INSERT INTO `sys_login_log` VALUES (845, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 15:59:15', '系统后台'); +INSERT INTO `sys_login_log` VALUES (846, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 15:59:16', '系统后台'); +INSERT INTO `sys_login_log` VALUES (847, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-16 15:59:17', '系统后台'); +INSERT INTO `sys_login_log` VALUES (848, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-16 16:11:58', '系统后台'); +INSERT INTO `sys_login_log` VALUES (849, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-16 17:01:43', '系统后台'); +INSERT INTO `sys_login_log` VALUES (850, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-18 10:33:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (851, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-18 10:45:05', '系统后台'); +INSERT INTO `sys_login_log` VALUES (852, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-18 16:27:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (853, 'demo', '::1', '安徽省 合肥市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-18 20:59:19', '系统后台'); +INSERT INTO `sys_login_log` VALUES (854, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-18 22:18:35', '系统后台'); +INSERT INTO `sys_login_log` VALUES (855, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-19 08:49:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (856, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-19 08:55:49', '系统后台'); +INSERT INTO `sys_login_log` VALUES (857, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-19 08:57:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (858, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:50:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (859, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:06', '系统后台'); +INSERT INTO `sys_login_log` VALUES (860, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:07', '系统后台'); +INSERT INTO `sys_login_log` VALUES (861, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:29', '系统后台'); +INSERT INTO `sys_login_log` VALUES (862, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (863, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (864, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:31', '系统后台'); +INSERT INTO `sys_login_log` VALUES (865, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (866, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-19 09:51:32', '系统后台'); +INSERT INTO `sys_login_log` VALUES (867, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-19 11:08:39', '系统后台'); +INSERT INTO `sys_login_log` VALUES (868, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-19 11:50:30', '系统后台'); +INSERT INTO `sys_login_log` VALUES (869, 'demo', '127.0.0.1', '内网IP', 'Firefox', 'Windows 10', 1, '登录成功', '2022-04-19 15:07:34', '系统后台'); +INSERT INTO `sys_login_log` VALUES (870, 'admin', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-19 16:38:37', '系统后台'); +INSERT INTO `sys_login_log` VALUES (871, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-19 17:29:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (872, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 08:42:41', '系统后台'); +INSERT INTO `sys_login_log` VALUES (873, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 09:51:36', '系统后台'); +INSERT INTO `sys_login_log` VALUES (874, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 10:41:01', '系统后台'); +INSERT INTO `sys_login_log` VALUES (875, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 10:50:15', '系统后台'); +INSERT INTO `sys_login_log` VALUES (876, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 10:50:19', '系统后台'); +INSERT INTO `sys_login_log` VALUES (877, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 10:50:59', '系统后台'); +INSERT INTO `sys_login_log` VALUES (878, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 14:38:28', '系统后台'); +INSERT INTO `sys_login_log` VALUES (879, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-20 16:26:04', '系统后台'); +INSERT INTO `sys_login_log` VALUES (880, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-20 16:27:13', '系统后台'); +INSERT INTO `sys_login_log` VALUES (881, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-21 08:31:03', '系统后台'); +INSERT INTO `sys_login_log` VALUES (882, 'demo', '::1', '云南省 曲靖市', 'Chrome', 'Windows 10', 1, '登录成功', '2022-04-21 09:22:27', '系统后台'); +INSERT INTO `sys_login_log` VALUES (883, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-21 17:17:35', '系统后台'); +INSERT INTO `sys_login_log` VALUES (884, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-21 17:27:48', '系统后台'); +INSERT INTO `sys_login_log` VALUES (885, 'demo', '127.0.0.1', '内网IP', 'ApiPOST', '', 1, '登录成功', '2022-04-21 17:28:09', '系统后台'); + +-- ---------------------------- +-- Table structure for sys_oper_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_oper_log`; +CREATE TABLE `sys_oper_log` ( + `oper_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '日志主键', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '模块标题', + `business_type` int(2) NULL DEFAULT 0 COMMENT '业务类型(0其它 1新增 2修改 3删除)', + `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '方法名称', + `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求方式', + `operator_type` int(1) NULL DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)', + `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作人员', + `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '部门名称', + `oper_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求URL', + `oper_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '主机地址', + `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作地点', + `oper_param` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求参数', + `json_result` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '返回参数', + `status` int(1) NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)', + `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '错误消息', + `oper_time` datetime(0) NULL DEFAULT NULL COMMENT '操作时间', + PRIMARY KEY (`oper_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '操作日志记录' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_post`; +CREATE TABLE `sys_post` ( + `post_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '岗位ID', + `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位编码', + `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位名称', + `post_sort` int(4) NOT NULL COMMENT '显示顺序', + `status` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + `created_by` bigint(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT '创建人', + `updated_by` bigint(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT '修改人', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + `deleted_at` datetime(0) NULL DEFAULT NULL COMMENT '删除时间', + PRIMARY KEY (`post_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '岗位信息表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_post +-- ---------------------------- +INSERT INTO `sys_post` VALUES (1, 'ceo', '董事长', 1, 1, '', 0, 0, '2021-07-11 11:32:58', NULL, NULL); +INSERT INTO `sys_post` VALUES (2, 'se', '项目经理', 2, 1, '', 0, 0, '2021-07-12 11:01:26', NULL, NULL); +INSERT INTO `sys_post` VALUES (3, 'hr', '人力资源', 3, 1, '', 0, 0, '2021-07-12 11:01:30', NULL, NULL); +INSERT INTO `sys_post` VALUES (4, 'user', '普通员工', 4, 0, '普通员工', 0, 31, '2021-07-12 11:01:33', '2022-04-08 15:32:23', NULL); +INSERT INTO `sys_post` VALUES (5, 'it', 'IT部', 5, 1, '信息部', 31, 31, '2021-07-12 11:09:42', '2022-04-09 12:59:12', NULL); +INSERT INTO `sys_post` VALUES (6, '1111', '1111', 0, 1, '11111', 31, 0, '2022-04-08 15:32:44', '2022-04-08 15:32:44', '2022-04-08 15:51:24'); +INSERT INTO `sys_post` VALUES (7, '222', '2222', 0, 1, '22222', 31, 0, '2022-04-08 15:32:55', '2022-04-08 15:32:55', '2022-04-08 15:51:24'); +INSERT INTO `sys_post` VALUES (8, '33333', '3333', 0, 0, '33333', 31, 0, '2022-04-08 15:33:01', '2022-04-08 15:33:01', '2022-04-08 15:51:40'); +INSERT INTO `sys_post` VALUES (9, '222', '111', 0, 1, '2313213', 31, 0, '2022-04-08 15:52:53', '2022-04-08 15:52:53', '2022-04-08 15:52:56'); + +-- ---------------------------- +-- Table structure for sys_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '状态;0:禁用;1:正常', + `list_order` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '排序', + `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '角色名称', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '备注', + `data_scope` tinyint(3) UNSIGNED NOT NULL DEFAULT 3 COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `status`(`status`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_role +-- ---------------------------- +INSERT INTO `sys_role` VALUES (1, 1, 0, '超级管理员', '备注', 3, '2022-04-01 11:38:39', '2022-04-09 12:59:28'); +INSERT INTO `sys_role` VALUES (2, 1, 0, '普通管理员', '备注', 3, '2022-04-01 11:38:39', '2022-04-01 11:38:39'); +INSERT INTO `sys_role` VALUES (3, 1, 0, '站点管理员', '站点管理人员', 3, '2022-04-01 11:38:39', '2022-04-01 11:38:39'); +INSERT INTO `sys_role` VALUES (4, 1, 0, '初级管理员', '初级管理员', 3, '2022-04-01 11:38:39', '2022-04-01 11:38:39'); +INSERT INTO `sys_role` VALUES (5, 1, 0, '高级管理员', '高级管理员', 2, '2022-04-01 11:38:39', '2022-04-01 11:38:39'); +INSERT INTO `sys_role` VALUES (8, 1, 0, '区级管理员', '', 2, '2022-04-01 11:38:39', '2022-04-06 09:53:40'); + +-- ---------------------------- +-- Table structure for sys_role_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_dept`; +CREATE TABLE `sys_role_dept` ( + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + `dept_id` bigint(20) NOT NULL COMMENT '部门ID', + PRIMARY KEY (`role_id`, `dept_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色和部门关联表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_role_dept +-- ---------------------------- +INSERT INTO `sys_role_dept` VALUES (5, 103); +INSERT INTO `sys_role_dept` VALUES (5, 104); +INSERT INTO `sys_role_dept` VALUES (5, 105); +INSERT INTO `sys_role_dept` VALUES (8, 105); +INSERT INTO `sys_role_dept` VALUES (8, 106); + +-- ---------------------------- +-- Table structure for sys_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, + `user_name` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户名', + `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '中国手机不带国家代码,国际手机号格式为:国家代码-手机号', + `user_nickname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '用户昵称', + `birthday` int(11) NOT NULL DEFAULT 0 COMMENT '生日', + `user_password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '登录密码;cmf_password加密', + `user_salt` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '加密盐', + `user_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT '用户状态;0:禁用,1:正常,2:未验证', + `user_email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户登录邮箱', + `sex` tinyint(2) NOT NULL DEFAULT 0 COMMENT '性别;0:保密,1:男,2:女', + `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户头像', + `dept_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT '部门id', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '备注', + `is_admin` tinyint(4) NOT NULL DEFAULT 1 COMMENT '是否后台管理员 1 是 0 否', + `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '联系地址', + `describe` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT ' 描述信息', + `last_login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '最后登录ip', + `last_login_time` datetime(0) NULL DEFAULT NULL COMMENT '最后登录时间', + `created_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updated_at` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `deleted_at` datetime(0) NULL DEFAULT NULL COMMENT '删除时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `user_login`(`user_name`, `deleted_at`) USING BTREE, + UNIQUE INDEX `mobile`(`mobile`, `deleted_at`) USING BTREE, + INDEX `user_nickname`(`user_nickname`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 43 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +INSERT INTO `sys_user` VALUES (1, 'admin', '13578342363', '超级管理员', 0, 'c567ae329f9929b518759d3bea13f492', 'f9aZTAa8yz', 1, 'yxh669@qq.com', 1, 'https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2021-07-19/ccwpeuqz1i2s769hua.jpeg', 101, '', 1, 'asdasfdsaf大发放打发士大夫发按时', '描述信息', '::1', '2022-04-19 16:38:37', '2021-06-22 17:58:00', '2022-04-19 16:38:37', NULL); +INSERT INTO `sys_user` VALUES (2, 'yixiaohu', '13699885599', '奈斯', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, 'yxh@qq.com', 1, 'pub_upload/2020-11-02/c6sntzg7r96c7p9gqf.jpeg', 102, '备注', 1, '', '', '[::1]', '2022-02-14 18:10:40', '2021-06-22 17:58:00', '2022-04-13 11:20:03', NULL); +INSERT INTO `sys_user` VALUES (3, 'zs', '16399669855', '张三', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, 'zs@qq.com', 0, 'https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2021-08-02/cd8nif79egjg9kbkgk.jpeg', 101, '', 1, '', '', '127.0.0.1', '2022-03-18 15:22:13', '2021-06-22 17:58:00', '2022-04-21 11:20:06', NULL); +INSERT INTO `sys_user` VALUES (4, 'qlgl', '13758596696', '测试c', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, 'qlgl@qq.com', 0, '', 102, '', 1, '', '', '127.0.0.1', NULL, '2021-06-22 17:58:00', '2022-04-12 17:55:28', NULL); +INSERT INTO `sys_user` VALUES (5, 'test', '13845696696', '测试2', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '123@qq.com', 0, '', 101, '', 0, '', '', '::1', '2022-03-30 10:50:39', '2021-06-22 17:58:00', '2022-04-12 17:55:31', NULL); +INSERT INTO `sys_user` VALUES (6, '18999998889', '13755866654', '刘大大', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '1223@qq.com', 0, '', 103, '', 1, '', '', '[::1]', '2022-02-25 14:29:22', '2021-06-22 17:58:00', '2022-04-14 21:11:06', NULL); +INSERT INTO `sys_user` VALUES (7, 'zmm', '13788566696', '张明明', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '11123@qq.com', 0, '', 104, '', 1, '', '', '127.0.0.1', NULL, '2021-06-22 17:58:00', '2022-04-12 17:55:42', NULL); +INSERT INTO `sys_user` VALUES (8, 'lxx', '13756566696', '李小小', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '123333@qq.com', 0, '', 101, '', 1, '', '', '127.0.0.1', NULL, '2021-06-22 17:58:00', '2022-04-12 17:55:45', NULL); +INSERT INTO `sys_user` VALUES (10, 'xmm', '13588999969', '小秘密', 0, '2de2a8df703bfc634cfda2cb2f6a59be', 'Frz7LJY7SE', 1, '696@qq.com', 0, '', 101, '', 1, '', '', '[::1]', '2021-07-22 17:08:53', '2021-06-22 17:58:00', '2022-04-12 17:55:50', NULL); +INSERT INTO `sys_user` VALUES (14, 'cd_19', '13699888899', '看金利科技', 0, '1169d5fe4119fd4277a95f02d7036171', '7paigEoedh', 1, '', 0, '', 102, '', 1, '', '', '', NULL, '2021-06-22 17:58:00', '2022-04-12 18:13:22', NULL); +INSERT INTO `sys_user` VALUES (15, 'lmm', '13587754545', '刘敏敏', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, 'a@coc.com', 0, '', 201, '', 1, '', '', '127.0.0.1', NULL, '2021-06-22 17:58:00', '2022-04-12 17:56:23', NULL); +INSERT INTO `sys_user` VALUES (16, 'ldn', '13899658874', '李大牛', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, 'a@ll.con', 0, '', 102, '', 1, '', '', '127.0.0.1', NULL, '2021-06-22 17:58:00', '2022-04-12 17:56:27', NULL); +INSERT INTO `sys_user` VALUES (20, 'dbc', '13877555566', '大百词', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '', 0, '', 0, '', 1, '', '', '', NULL, '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (22, 'yxfmlbb', '15969423326', '大数据部门测试', 0, '66f89b40ee4a10aabaf70c15756429ea', 'mvd2OtUe8f', 1, 'yxh6691@qq.com', 0, 'https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2021-09-29/cem20k3fdciosy7nwo.jpeg', 200, '', 1, '2222233', '1222', '[::1]', '2021-10-28 11:36:07', '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (23, 'wangming', '13699888855', '王明', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '', 0, '', 0, '', 1, '', '', '', NULL, '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (24, 'zhk', '13699885591', '综合科', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '', 0, '', 0, '', 1, '', '', '192.168.0.146', NULL, '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (28, 'demo3', '18699888855', '测试账号1', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '123132@qq.com', 0, '', 109, '', 1, '', '', '192.168.0.229', NULL, '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (31, 'demo', '15334455789', '李四', 0, '39978de67915a11e94bfe9c879b2d9a1', 'gqwLs4n95E', 1, '223@qq.com', 2, 'https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2021-11-30/cg30rab8myj85vjzcf.jpeg', 109, '', 1, '云南省曲靖市22223', '12345', '127.0.0.1', '2022-04-21 17:28:09', '2021-06-22 17:58:00', '2022-04-21 17:28:09', NULL); +INSERT INTO `sys_user` VALUES (32, 'demo100', '18699888859', '测试账号1', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '', 0, '', 0, '', 1, '', '', '[::1]', '2021-11-24 18:01:21', '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (33, 'demo110', '18699888853', '测试账号1', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '', 0, '', 0, '', 1, '', '', '', NULL, '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (34, 'yxfmlbb2', '15969423327', '研发部门测试', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '1111@qqq.com', 1, '', 103, '', 0, '', '', '127.0.0.1', NULL, '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (35, 'wk666', '18888888888', 'wk', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '396861557@qq.com', 1, '', 100, '', 1, '', '', '[::1]', '2021-12-09 14:52:37', '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (36, 'zxd', '13699885565', '张晓东', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, 'zxk@qq.com', 1, '', 201, '666', 1, '', '', '', NULL, '2021-06-22 17:58:00', '2021-06-22 17:58:00', NULL); +INSERT INTO `sys_user` VALUES (37, 'yxfmlbb3', '13513513511', '张三', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '111@qq.com', 0, '', 204, '', 1, '', '', '[::1]', '2021-07-26 14:49:25', '2021-06-22 17:58:00', '2021-07-26 14:49:18', NULL); +INSERT INTO `sys_user` VALUES (38, 'test_user', '18888888880', 'test', 0, '542a6e44dbac171f260fc4a032cd5522', 'dlqVVBTADg', 1, '11@qq.com', 1, '', 200, '111', 0, '', '', '', NULL, '2021-06-22 17:58:00', '2021-07-12 22:05:29', NULL); +INSERT INTO `sys_user` VALUES (39, 'asan', '18687460555', '阿三', 0, '2354837137115700e2adf870ac113dcf', 'drdDvbtYZW', 1, '456654@qq.com', 1, '', 201, '666666', 1, '', '', '', NULL, '2021-07-12 17:21:43', '2021-07-12 21:13:31', '2021-07-12 22:00:44'); +INSERT INTO `sys_user` VALUES (40, 'asi', '13655888888', '啊四', 0, 'fbb755b35d48759dad47bb1540249fd1', '9dfUstcxrz', 1, '5464@qq.com', 1, '', 201, 'adsaasd', 1, '', '', '', '0000-00-00 00:00:00', '2021-07-12 17:46:27', '2021-07-12 21:29:41', '2021-07-12 22:00:44'); +INSERT INTO `sys_user` VALUES (41, 'awu', '13578556546', '阿五', 0, '3b36a96afa0dfd66aa915e0816e0e9f6', '9gHRa9ho4U', 0, '132321@qq.com', 1, '', 201, 'asdasdasd', 1, '', '', '', NULL, '2021-07-12 17:54:31', '2021-07-12 21:46:34', '2021-07-12 21:59:56'); +INSERT INTO `sys_user` VALUES (42, 'demo01', '13699888556', '测试01222', 0, '048dc94116558fb40920f3553ecd5fe8', 'KiVrfzKJQx', 1, '456@qq.com', 2, '', 109, '测试用户', 1, '', '', '', NULL, '2022-04-12 16:15:23', '2022-04-12 17:54:49', NULL); + +-- ---------------------------- +-- Table structure for sys_user_online +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_online`; +CREATE TABLE `sys_user_online` ( + `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, + `uuid` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT '用户标识', + `token` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT '用户token', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '登录时间', + `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名', + `ip` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '登录ip', + `explorer` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '浏览器', + `os` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '操作系统', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uni_token`(`token`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 17387 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户在线状态表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_user_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_post`; +CREATE TABLE `sys_user_post` ( + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `post_id` bigint(20) NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`, `post_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of sys_user_post +-- ---------------------------- +INSERT INTO `sys_user_post` VALUES (1, 2); +INSERT INTO `sys_user_post` VALUES (1, 3); +INSERT INTO `sys_user_post` VALUES (2, 1); +INSERT INTO `sys_user_post` VALUES (2, 2); +INSERT INTO `sys_user_post` VALUES (3, 2); +INSERT INTO `sys_user_post` VALUES (5, 2); +INSERT INTO `sys_user_post` VALUES (10, 1); +INSERT INTO `sys_user_post` VALUES (10, 2); +INSERT INTO `sys_user_post` VALUES (10, 3); +INSERT INTO `sys_user_post` VALUES (10, 4); +INSERT INTO `sys_user_post` VALUES (10, 5); +INSERT INTO `sys_user_post` VALUES (14, 1); +INSERT INTO `sys_user_post` VALUES (15, 4); +INSERT INTO `sys_user_post` VALUES (16, 2); +INSERT INTO `sys_user_post` VALUES (22, 1); +INSERT INTO `sys_user_post` VALUES (22, 2); +INSERT INTO `sys_user_post` VALUES (31, 2); +INSERT INTO `sys_user_post` VALUES (34, 1); +INSERT INTO `sys_user_post` VALUES (35, 2); +INSERT INTO `sys_user_post` VALUES (35, 3); +INSERT INTO `sys_user_post` VALUES (36, 1); +INSERT INTO `sys_user_post` VALUES (37, 3); +INSERT INTO `sys_user_post` VALUES (38, 2); +INSERT INTO `sys_user_post` VALUES (38, 3); +INSERT INTO `sys_user_post` VALUES (42, 2); +INSERT INTO `sys_user_post` VALUES (42, 3); + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/resource/i18n/.gitkeep b/resource/i18n/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/html/.gitkeep b/resource/public/html/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/plugin/.gitkeep b/resource/public/plugin/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/resource/css/.gitkeep b/resource/public/resource/css/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/resource/demo.html b/resource/public/resource/demo.html new file mode 100644 index 0000000..f336480 --- /dev/null +++ b/resource/public/resource/demo.html @@ -0,0 +1,10 @@ + + + + + demo + + +hello word + + \ No newline at end of file diff --git a/resource/public/resource/image/.gitkeep b/resource/public/resource/image/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/public/resource/js/.gitkeep b/resource/public/resource/js/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/scripts/.gitkeep b/resource/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resource/template/.gitkeep b/resource/template/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/utility/.gitkeep b/utility/.gitkeep new file mode 100644 index 0000000..e69de29