This commit is contained in:
孟帅 2022-11-24 23:37:34 +08:00
parent 4ffe54b6ac
commit 29bda0dcdd
1487 changed files with 97869 additions and 96539 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*.zip
.idea
.user.ini
pull.bat
push.sh
/dist

2
.idea/.gitignore generated vendored
View File

@ -1,2 +0,0 @@
# Default ignored files
/workspace.xml

8
.idea/hotgo.iml generated
View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

6
.idea/misc.xml generated
View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

8
.idea/modules.xml generated
View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/hotgo.iml" filepath="$PROJECT_DIR$/.idea/hotgo.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated
View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

260
README.md
View File

@ -1,83 +1,247 @@
# hotgo
# HotGO-V2
<div align="center">
<img width="140px" src="https://bufanyun.cn-bj.ufileos.com/hotgo/logo.sig.png">
<p>
<h1>HotGO V2.0</h1>
</p>
<p align="center">
<a href="https://goframe.org/pages/viewpage.action?pageId=1114119" target="_blank">
<img src="https://img.shields.io/badge/goframe-2.1-green" alt="goframe">
</a>
<a href="https://v3.vuejs.org/" target="_blank">
<img src="https://img.shields.io/badge/vue.js-vue3.x-green" alt="vue">
</a>
<a href="https://www.naiveui.com" target="_blank">
<img src="https://img.shields.io/badge/naiveui-%3E2.0.0-blue" alt="naiveui">
</a>
<a href="https://www.tslang.cn/" target="_blank">
<img src="https://img.shields.io/badge/typescript-%3E4.0.0-blue" alt="typescript">
</a>
<a href="https://vitejs.dev/" target="_blank">
<img src="https://img.shields.io/badge/vite-%3E2.0.0-yellow" alt="vite">
</a>
<a href="https://raw.githubusercontent.com/tusen-ai/naive-ui/main/LICENSE" target="_blank">
<img src="https://img.shields.io/badge/license-MIT-success" alt="license">
</a>
</p>
</div>
#### HotGo 是一个基于 vue 和 goframe2.0 开发的全栈前后端分离的开发基础平台和移动应用平台集成jwt鉴权动态路由动态菜单casbin鉴权消息队列定时任务等功能提供多种常用场景文件让您把更多时间专注在业务开发上。
## 技术选型
## 平台简介
* 基于全新Go Frame 2.0+Vue3+Naive UI开发的全栈前后端分离的管理系统
* 前端采用naive-ui-admin 、Vue、Naive UI。
* 后端:用 goframe2.0 快速搭建基础APIgoframe2.0 是一个go语言编写的Web框架。
* 前端:用基于 JeeSite Mobile Uni-App+aidex-sharp 构建基础页面。
* 数据库采用MySql(8.0)版本,使用 gorm 实现对数据库的基本操作。
* 缓存使用Redis实现记录当前活跃用户的jwt令牌并实现多点登录限制。
* API文档使用Swagger构建自动化文档。
* 消息队列:同时兼容 kafka、redis、rocketmq一键配置切换到自己想用的MQ。
## 特征
* 高生产率:几分钟即可搭建一个后台管理系统
* 模块化:单应用多系统的模式,将一个完整的应用拆分为多个系统,后续扩展更加便捷,增加代码复用性。
* 插件化: 可通过插件的方式扩展系统功能
* 认证机制采用jwt的用户状态认证及casbin的权限认证
* 路由模式得利于goframe2.0提供了规范化的路由注册方式,无需注解自动生成api文档
* 面向接口开发
## 系统截图
#### * web端
![image](https://user-images.githubusercontent.com/26652343/155689571-e6a0a5a3-011b-44cc-b84b-a1c82301b207.png)
## 内置功能
![image](https://user-images.githubusercontent.com/26652343/155689646-d3395261-6061-469f-8256-3cd0ff9f5d05.png)
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、岗位),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 配置管理:对系统动态配置常用参数。
8. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
9. 登录日志:系统登录日志记录查询包含登录异常。
10. 调度日志:服务端运行所产生的警告、异常、崩溃日志的详细数据和堆栈信息。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成:前后端代码的生成。
14. 服务监控监视当前系统CPU、内存、磁盘、网络、堆栈等相关信息。
15. 附件管理:文件上传,多种上传方式适配。
16. 消息队列:同时兼容 kafka、redis、rocketmq一键配置切换到自己想用的MQ。
17. 通知公告采用websocket及时推送在线用户最新公告。
18. 地区编码:整合国内通用省市区编码,运用于项目于一身。
19. 常用工具:集成常用的工具包和命令行工具,可以快速开发自定义命令行,多种启动入口。
![image](https://user-images.githubusercontent.com/26652343/155689709-5ddac1d3-1c01-4fab-9d3a-9ece72ca5ba0.png)
#### * 移动端
![image](https://user-images.githubusercontent.com/26652343/155689481-2fc019eb-18e4-4a94-b417-50524e945089.png)
![image](https://user-images.githubusercontent.com/26652343/155689738-ac97f9c0-47ae-499b-b3fe-0cb4ce97f3bc.png)
> HotGo开源以来得到了大家的很多支持本项目初衷只为互相学习交流没有任何盈利性目的欢迎为HotGO贡献代码或提供建议
## 演示地址
- [https://hotgo.facms.cn/admin](https://hotgo.facms.cn/admin)
> 账号admin 密码123456
## 环境要求
- node版本 >= v14.0.0
- golang版本 >= v1.16
- node版本 >= v16.0.0
- golang版本 >= v1.18
- gf版本 >=2.1
- IDE推荐Goland
- mysql版本 >=8.0
- redis版本 >=5.0
- mysql版本 >=5.7
- redis版本 >=3.0
## 快速开始
一、拉取代码到你已经安装好以上环境的服务器中
一、拉取代码到你已经安装好以上环境的服务器中
```shell script
git clone https://github.com/bufanyun/hotgo.git
git clone https://github.com/bufanyun/hotgo.git && cd hotgo
```
二、配置你的站点信息
服务端:
- 创建mysql数据库将数据库文件导入你的mysql目录地址/hotgo-server/storage/hotgo.sql
- 将/hotgo-server/config/config.example.yaml 改为config.yaml并根据你实际环境情况进行配置
- 项目数据库文件 `resource/data/db.sql` 创建数据库并导入
- 修改配置 `manifest/config/config.yaml.bak` 复制改为`manifest/config/config.yaml`
web+uinapp端
- 配置服务端地址,包含在一下文件中:
* hotgo-uniapp/common/config.js
* /hotgo-uniapp/manifest.json
* hotgo-uniapp/common/config.js
其中hotgo配置
```yaml
hotgo:
debug: true # debug开关开启后接口出现错误时会输出堆栈信息默认为true
ipMethod: "cz88" # IP归属地解析方法可选cz88|whois默认为cz88
wsAddr: "ws://你的IP:8000/socket" # 客户端websocket连接地址如果项目在公网请填写公网IP:运行端口
isDemo: false # 是否為演示系統 false | true
ssl: # https
switch: false # 是否开启https访问需要配置sslCrtPath、sslKeyPath证书夹
crtPath: "resource/ssl/server.crt"
keyPath: "resource/ssl/server.key"
log: # 全局请求日志
switch: true # 日志开关默认为true
queue: true # 是否启用队列启用时需要配置队列信息默认为true
module: [ "admin", "api", "default" ] # 需要记录的模块
skipCode: [ ] # 不记录的状态码,如: ["0", "-1"]
admin:
superIds: [ 1,2 ] # 后台超管账号ID通过ID验证超管
superRoleKey: "super" # 超管角色唯一标识符,通过角色验证超管
defaultPage: 10 # 列表分页默认加载数量
defaultPageSize: 1 # 列表分页默认加载页码
```
后台前端:
- 配置服务端地址,包含在以下文件中:
* /hotgo/web/.env.development
* /hotgo/web/.env.production
* /hotgo/web/.env
其中必改配置
```
VITE_PROXY=[["/admin","http://你的IP:8000/admin"]]
```
三、 启动服务
服务端:
```shell script
cd hotgo-server
go mod tidy #更新包
go run main.go #启动服务
cd server
# 更新包
go mod tidy
# 查看命令行方法
go run main.go
# 启动所有服务
gf run main.go --args "all"
# 如果顺利至此到浏览器打开http://你的IP:8000/admin即可看到后台登录地址
# 登录账号admin, 密码123456
# 好奇为什么没有运行前端代码就能将后台运行起来这要得益于gf强大的pack功能
# 当然这只是为了降低运行门槛,如果想对前端进行开发请继续往下看
```
web端
```shell script
cd hotgo-web
npm install #安装依赖
npm run dev #启动web项目
cd web
# 首先确定你以安装node16.0以上版本并安装了包[npm、yarn],否则可能会出现一些未知报错
# 安装依赖
yarn install
# 启动web项目
npm run dev
# 如果顺利至此到浏览器打开http://你的IP:8001/admin
```
uinapp端
- 1、下载并安装集成开发环境 HBuilderX (推荐,也可以使用 VSCode 或 WebStorm
- 2、菜单文件 -> 导入 -> 从本地目录导入,选择 “jeesite4-uniapp” 文件夹。
- 3、菜单运行 -> 运行到内置浏览器(或运行到浏览器 -> Chrome 浏览器)。
- 4、等待 HBuliderX 控制台编译完成后,会自动弹出手机登录页面。
## 特别感谢(以下排名不分先后)
## 文档地址
> 文档正在书写中,请耐心等一等。
* goframe2.0 https://goframe.org
* JeeSite Mobile Uni-App https://gitee.com/thinkgem/jeesite4-uniapp
* aidex-sharp https://gitee.com/big-hedgehog/aidex-sharp
## 开源声明
* 目前项目还在持续更新中,仅供参考学习,如遇到问题请联系作者下方微信!
## 演示图
<table>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/1.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/2.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/3.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/4.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/5.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/6.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/7.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/8.png"/></td>
</tr>
<tr>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/9.png"/></td>
<td><img src="https://bufanyun.cn-bj.ufileos.com/hotgo/example/10.png"/></td>
</tr>
</table>
## 感谢(排名不分先后)
> gf框架 [https://github.com/gogf/gf](https://github.com/gogf/gf)
>
> naive-ui [https://www.naiveui.com](https://www.naiveui.com)
>
> naive-ui-admin [https://github.com/jekip/naive-ui-admin](https://github.com/jekip/naive-ui-admin)
>
> websocket [https://github.com/gorilla/websocket](github.com/gorilla/websocket)
>
> casbin [https://github.com/casbin/casbin](https://github.com/casbin/casbin)
## 交流QQ群
交流群①190966648 <a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=mJafkvme3VNyiQlCFIFNRtY8Xlr7pj9U&jump_from=webapi&authKey=jL10vIESr+vO8wpxwyd6DlChzkrbHpzN9uhAsIHgAinL/Vvd+nvuRyilf2UqUlCy"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="HotGo框架交流1群" title="HotGo框架交流1群"></a>
> <img src="https://bufanyun.cn-bj.ufileos.com/hotgo/hotgo1qun.png" width="400px"/>
> 感谢你使用HotGo,公司团队精力时间有限,因此我们不再提供免费的技术服务!
>
> 同时您也可以联系我们,雇佣我们团队为您干活,谢谢合作!
## 商用说明
> HotGo 是开源免费的,遵循 MIT 开源协议,意味着您无需支付任何费用,也无需授权,即可将它应用到您的产品中。
* 使用本项目必须保留所有版权信息。
* 本项目包含的第三方源码和二进制文件之版权信息另行标注。
* 版权所有Copyright © 2022-2024 by Ms (https://github.com/bufanyun/hotgo)
* All rights reserved。
## 免责声明:
* HotGo为开源学习项目一切商业行为与HotGo无关。
* 用户不得利用HotGo从事非法行为用户应当合法合规的使用发现用户在使用产品时有任何的非法行为HotGo有权配合有关机关进行调查或向政府部门举报HotGo不承担用户因非法行为造成的任何法律责任一切法律责任由用户自行承担如因用户使用造成第三方损害的用户应当依法予以赔偿。
* 所有与使用HotGo相关的资源直接风险均由用户承担。
#### 如果对您有帮助,您可以点右上角 💘Star💘支持
## [感谢JetBrains提供的免费GoLand](https://jb.gg/OpenSource)
[![avatar](https://camo.githubusercontent.com/323657c6e81419b8e151e9da4c71f409e3fcc65d630535170c59fe4807dbc905/68747470733a2f2f676f6672616d652e6f72672f646f776e6c6f61642f7468756d626e61696c732f313131343131392f6a6574627261696e732e706e67)](https://jb.gg/OpenSource)
![image](https://user-images.githubusercontent.com/26652343/155691271-1ded98d8-f0f1-4467-9079-26cec1195af5.png)

View File

@ -1,21 +0,0 @@
.DS_Store
.buildpath
.hgignore.swp
.project
.orig
.swp
.idea/
.settings/
config/config.yaml
runtime/log/logger/*.log
runtime/log/logger/exception/*.log
runtime/log/logger/queue/*.log
runtime/log/server/*.log
runtime/log/server/access/*.log
runtime/log/server/error/*.log
bin/
*/.DS_Store
.vscode
main.exe
main.exe~
hotgo.exe

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 john@goframe.org https://goframe.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1 +0,0 @@
# hotgo 服务端代码

View File

@ -1,108 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package com
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model"
"github.com/gogf/gf/v2/net/ghttp"
)
// 上下文
var Context = new(comContext)
type comContext struct{}
//
//  @Title  初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//  @Param   customCtx
//
func (component *comContext) Init(r *ghttp.Request, customCtx *model.Context) {
r.SetCtxVar(consts.ContextKey, customCtx)
}
//
//  @Title  获得上下文变量如果没有设置那么返回nil
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Return  *model.Context
//
func (component *comContext) Get(ctx context.Context) *model.Context {
value := ctx.Value(consts.ContextKey)
if value == nil {
return nil
}
if localCtx, ok := value.(*model.Context); ok {
return localCtx
}
return nil
}
//
//  @Title  将上下文信息设置到上下文请求中,注意是完整覆盖
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   user
//
func (component *comContext) SetUser(ctx context.Context, user *model.Identity) {
component.Get(ctx).User = user
}
//
//  @Title  设置组件响应 用于全局日志使用
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   response
//
func (component *comContext) SetResponse(ctx context.Context, response *model.Response) {
component.Get(ctx).ComResponse = response
}
//
//  @Title  设置应用模块
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   module
//
func (component *comContext) SetModule(ctx context.Context, module string) {
component.Get(ctx).Module = module
}
//
//  @Title  设置请求耗时
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   module
//
func (component *comContext) SetTakeUpTime(ctx context.Context, takeUpTime int64) {
component.Get(ctx).TakeUpTime = takeUpTime
}
//
//  @Title  获取用户ID
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Return  int
//
func (component *comContext) GetUserId(ctx context.Context) int64 {
user := component.Get(ctx).User
if user == nil {
return 0
}
return user.Id
}

View File

@ -1,256 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package com
import (
"context"
"time"
"github.com/axgle/mahonia"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/utils"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"github.com/kayon/iploc"
)
// IP归属地
var Ip = new(ip)
type ip struct{}
type IpLocationData struct {
Ip string `json:"ip"`
Country string `json:"country"`
Region string `json:"region"`
Province string `json:"province"`
ProvinceCode int `json:"province_code"`
City string `json:"city"`
CityCode int `json:"city_code"`
Area string `json:"area"`
AreaCode int `json:"area_code"`
}
//
//  @Title  通过Whois接口查询IP归属地
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   ip
//  @Return  IpLocationData
//
func (component *ip) WhoisLocation(ctx context.Context, ip string) IpLocationData {
type whoisRegionData struct {
Ip string `json:"ip"`
Pro string `json:"pro" `
ProCode string `json:"proCode" `
City string `json:"city" `
CityCode string `json:"cityCode"`
Region string `json:"region"`
RegionCode string `json:"regionCode"`
Addr string `json:"addr"`
Err string `json:"err"`
}
if !utils.Validate.IsIp(ip) {
return IpLocationData{}
}
response, err := g.Client().Timeout(10*time.Second).Get(ctx, "http://whois.pconline.com.cn/ipJson.jsp?ip="+ip+"&json=true")
if err != nil {
err = gerror.New(err.Error())
return IpLocationData{
Ip: ip,
}
}
defer response.Close()
var enc mahonia.Decoder
enc = mahonia.NewDecoder("gbk")
data := enc.ConvertString(response.ReadAllString())
g.Log().Print(ctx, "data:", data)
whoisData := whoisRegionData{}
if err := gconv.Struct(data, &whoisData); err != nil {
err = gerror.New(err.Error())
g.Log().Print(ctx, "err:", err)
return IpLocationData{
Ip: ip,
}
}
g.Log().Print(ctx, "whoisData:", whoisData)
return IpLocationData{
Ip: whoisData.Ip,
//Country string `json:"country"`
Region: whoisData.Addr,
Province: whoisData.Pro,
ProvinceCode: gconv.Int(whoisData.ProCode),
City: whoisData.City,
CityCode: gconv.Int(whoisData.CityCode),
Area: whoisData.Region,
AreaCode: gconv.Int(whoisData.RegionCode),
}
}
//
//  @Title  通过Cz88的IP库查询IP归属地
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   ip
//  @Return  IpLocationData
//
func (component *ip) Cz88Find(ctx context.Context, ip string) IpLocationData {
if !utils.Validate.IsIp(ip) {
g.Log().Print(ctx, "ip格式错误:", ip)
return IpLocationData{}
}
loc, err := iploc.OpenWithoutIndexes("./storage/ip/qqwry-utf8.dat")
if err != nil {
err = gerror.New(err.Error())
return IpLocationData{
Ip: ip,
}
}
detail := loc.Find(ip)
if detail == nil {
return IpLocationData{
Ip: ip,
}
}
locationData := IpLocationData{
Ip: ip,
Country: detail.Country,
Region: detail.Region,
Province: detail.Province,
City: detail.City,
Area: detail.County,
}
if gstr.LenRune(locationData.Province) == 0 {
return locationData
}
var (
provinceModel *entity.SysProvinces
cityModel *entity.SysProvinces
areaModel *entity.SysProvinces
)
err = g.DB().Model("hg_sys_provinces").
Where("level", 1).
WhereLike("title", "%"+locationData.Province+"%").
Scan(&provinceModel)
if err != nil {
err = gerror.New(err.Error())
return locationData
}
if provinceModel != nil {
locationData.ProvinceCode = provinceModel.Id
locationData.Province = provinceModel.Title
}
if gstr.LenRune(locationData.City) == 0 {
return locationData
// 是否为直辖市
} else if component.IsJurisdictionByIpTitle(locationData.City) {
locationData.CityCode = provinceModel.Id + 100
locationData.City = "直辖市"
} else {
//替换掉
locationData.City = gstr.Replace(locationData.City, "地区", "")
err = g.DB().Model("hg_sys_provinces").
Where("level", 2).
Where("pid", locationData.ProvinceCode).
WhereLike("title", "%"+locationData.City+"%").
Scan(&cityModel)
if err != nil {
err = gerror.New(err.Error())
return locationData
}
if cityModel != nil {
locationData.CityCode = cityModel.Id
locationData.City = cityModel.Title
}
}
if gstr.LenRune(locationData.Area) == 0 {
return locationData
}
err = g.DB().Model("hg_sys_provinces").
Where("level", 3).
Where("pid", locationData.CityCode).
WhereLike("title", "%"+locationData.Area+"%").
Scan(&areaModel)
if err != nil {
err = gerror.New(err.Error())
return locationData
}
if areaModel != nil {
locationData.AreaCode = areaModel.Id
locationData.Area = areaModel.Title
}
return locationData
}
//
//  @Title  判断地区名称是否为直辖市
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   title
//  @Return  bool
//
func (component *ip) IsJurisdictionByIpTitle(title string) bool {
lists := []string{"北京市", "天津市", "重庆市", "上海市"}
for i := 0; i < len(lists); i++ {
if gstr.Contains(lists[i], title) {
return true
}
}
return false
}
//
//  @Title  获取IP归属地信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   ip
//  @Return  IpLocationData
//
func (component *ip) GetLocation(ctx context.Context, ip string) IpLocationData {
method, _ := g.Cfg().Get(ctx, "hotgo.ipMethod", "cz88")
if method.String() == "whois" {
return component.WhoisLocation(ctx, ip)
}
return component.Cz88Find(ctx, ip)
}

View File

@ -1,162 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package com
import (
"context"
"fmt"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model"
"github.com/dgrijalva/jwt-go"
"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/net/ghttp"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"time"
)
// jwt鉴权
type JWT struct{}
var Jwt = new(JWT)
//
//  @Title  为指定用户生成token
//  @Description  主要用于登录成功的jwt鉴权绑定
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   user 用户信息
//  @Param   isRefresh 是否是刷新token
//  @Return  interface{}
//  @Return  error
//
func (component *JWT) GenerateLoginToken(ctx context.Context, user *model.Identity, isRefresh bool) (interface{}, error) {
jwtVersion, _ := g.Cfg().Get(ctx, "jwt.version", "1.0")
jwtSign, _ := g.Cfg().Get(ctx, "jwt.sign", "hotGo")
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"id": user.Id,
"username": user.Username,
"realname": user.Realname,
"avatar": user.Avatar,
"email": user.Email,
"mobile": user.Mobile,
"last_time": user.LastTime,
"last_ip": user.LastIp,
"exp": user.Exp,
"expires": user.Expires,
"app": user.App,
"role": user.Role,
"visit_count": user.VisitCount,
"is_refresh": isRefresh,
"jwt_version": jwtVersion.String(),
})
tokenString, err := token.SignedString(jwtSign.Bytes())
if err != nil {
err := gerror.New(err.Error())
return nil, err
}
tokenStringMd5 := gmd5.MustEncryptString(tokenString)
// TODO 绑定登录token
cache := Cache.New()
key := consts.RedisJwtToken + tokenStringMd5
// TODO 将有效期转为持续时间,单位:秒
expires, _ := time.ParseDuration(fmt.Sprintf("+%vs", user.Expires))
err = cache.Set(ctx, key, tokenString, expires)
if err != nil {
err := gerror.New(err.Error())
return nil, err
}
_ = cache.Set(ctx, consts.RedisJwtUserBind+user.App+":"+gconv.String(user.Id), key, expires)
return tokenString, err
}
//
//  @Title  解析token
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   tokenString
//  @Param   secret
//  @Return  jwt.MapClaims
//  @Return  error
//
func (component *JWT) ParseToken(tokenString string, secret []byte) (jwt.MapClaims, error) {
if tokenString == "" {
err := gerror.New("token 为空")
return nil, err
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return secret, nil
})
if token == nil {
err := gerror.New("token不存在")
return nil, err
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims, nil
} else {
return nil, err
}
}
/**
token有效正确返回用户id
*/
//func(component *JWT) VerifyLoginToken(tokenString string) (uint, err error) {
// //if tokenString == "" {
// // err = gerror.New("token不能为空")
// // return 0, err
// //}
//
//}
//
//  @Title  获取 authorization
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//  @Return  string
//
func (component *JWT) GetAuthorization(r *ghttp.Request) string {
// TODO 默认从请求头获取
var authorization = r.Header.Get("Authorization")
// TODO 如果请求头不存在则从get参数获取
if authorization == "" {
return r.Get("authorization").String()
}
return gstr.Replace(authorization, "Bearer ", "")
}
/**
清掉所以的相关的redis
*/
func (component *JWT) Layout(adminUserId int, tokenString string) {
if tokenString == "" {
return
}
//g.Redis().Do("HDEL", "VerifyLoginToken", gmd5.MustEncryptString(tokenString))
//// 删除
//g.Redis().Do("HDEL", "VerifyLoginTokenAdminUserId", adminUserId)
}

View File

@ -1,83 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package com
import (
"context"
"github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/database/gredis"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
var Redis = new(redis)
type redis struct{}
//
//  @Title  实例化redis
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   name
//  @Return  *gredis.Redis
//
func (component *redis) Instance(name ...string) *gredis.Redis {
return g.Redis(name...)
}
//
//  @Title  获取
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   key
//  @Return  *gvar.Var
//  @Return  error
//
func (component *redis) Get(ctx context.Context, key string) (*gvar.Var, error) {
data, err := Redis.Instance().Do(ctx, "GET", key)
if err != nil {
err := gerror.New(err.Error())
return nil, err
}
return data, nil
}
//
//  @Title  设置
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   key
//  @Param   value
//  @Param   expire
//  @Return  *gvar.Var
//  @Return  error
//
func (component *redis) Set(ctx context.Context, key string, value string, expire interface{}) (*gvar.Var, error) {
redisInstance := Redis.Instance()
response, err := redisInstance.Do(ctx, "SET", key, value)
if err != nil {
err := gerror.New(err.Error())
return nil, err
}
exp := gconv.Int(expire)
// TODO 设置有效期
if exp > 0 {
_, err = redisInstance.Do(ctx, "EXPIRE", key, exp)
if err != nil {
err := gerror.New(err.Error())
return nil, err
}
}
return response, nil
}

View File

@ -1,122 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package com
import (
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"time"
)
// 统一响应
var Response = new(response)
type response struct{}
//
//  @Title  返回JSON数据并退出当前HTTP执行函数
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//  @Param   code
//  @Param   message
//  @Param   data
//
func (component *response) JsonExit(r *ghttp.Request, code int, message string, data ...interface{}) {
component.RJson(r, code, message, data...)
r.Exit()
}
//
//  @Title  标准返回结果数据结构封装
//  @Description  返回固定数据结构的JSON
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//  @Param   code 状态码(200:成功,302跳转和http请求状态码一至)
//  @Param   message 请求结果信息
//  @Param   data 请求结果,根据不同接口返回结果的数据结构不同
//
func (component *response) RJson(r *ghttp.Request, code int, message string, data ...interface{}) {
responseData := interface{}(nil)
if len(data) > 0 {
responseData = data[0]
}
Res := &model.Response{
Code: code,
Message: message,
Timestamp: time.Now().Unix(),
ReqId: Context.Get(r.Context()).ReqId,
}
// TODO 如果不是正常的返回则将data转为error
if consts.CodeOK == code {
Res.Data = responseData
} else {
Res.Error = responseData
}
// TODO 清空响应
r.Response.ClearBuffer()
// TODO 写入响应
if err := r.Response.WriteJson(Res); err != nil {
g.Log().Error(r.Context(), "响应异常:", err)
}
// TODO 加入到上下文
Context.SetResponse(r.Context(), Res)
}
//
//  @Title  返回成功JSON
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   isExit
//  @Param   r
//  @Param   message
//  @Param   data
//
func (component *response) SusJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
if isExit {
component.JsonExit(r, consts.CodeOK, message, data...)
}
component.RJson(r, consts.CodeOK, message, data...)
}
//
//  @Title  返回失败JSON
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   isExit
//  @Param   r
//  @Param   message
//  @Param   data
//
func (component *response) FailJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
if isExit {
component.JsonExit(r, consts.CodeNil, message, data...)
}
component.RJson(r, consts.CodeNil, message, data...)
}
//
//  @Title  重定向
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//  @Param   location
//  @Param   code
//
func (component *response) Redirect(r *ghttp.Request, location string, code ...int) {
r.Response.RedirectTo(location, code...)
}
func (component *response) Download(r *ghttp.Request, location string, code ...int) {
r.Response.ServeFileDownload("test.txt")
}

View File

@ -1,8 +0,0 @@
package consts
// 碎片
const (
// 默认分页
DebrisPageSize = 10
)

View File

@ -1,173 +0,0 @@
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/sysService"
"github.com/gogf/gf/v2/util/gconv"
)
// 配置
var Config = config{}
type config struct{}
//
//  @Title  名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *config) GetValue(ctx context.Context, req *adminForm.ConfigGetValueReq) (*adminForm.ConfigGetValueRes, error) {
data, err := sysService.Config.GetValue(ctx, input.SysConfigGetValueInp{Key: req.Key})
if err != nil {
return nil, err
}
var res adminForm.ConfigGetValueRes
res.Value = data.Value
return &res, nil
}
//
//  @Title  名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *config) NameUnique(ctx context.Context, req *adminForm.ConfigNameUniqueReq) (*adminForm.ConfigNameUniqueRes, error) {
data, err := sysService.Config.NameUnique(ctx, input.SysConfigNameUniqueInp{Id: req.Id, Name: req.Name})
if err != nil {
return nil, err
}
var res adminForm.ConfigNameUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *config) Delete(ctx context.Context, req *adminForm.ConfigDeleteReq) (res *adminForm.ConfigDeleteRes, err error) {
var in input.SysConfigDeleteInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = sysService.Config.Delete(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *config) Edit(ctx context.Context, req *adminForm.ConfigEditReq) (res *adminForm.ConfigEditRes, err error) {
var in input.SysConfigEditInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = sysService.Config.Edit(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *config) MaxSort(ctx context.Context, req *adminForm.ConfigMaxSortReq) (*adminForm.ConfigMaxSortRes, error) {
data, err := sysService.Config.MaxSort(ctx, input.SysConfigMaxSortInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.ConfigMaxSortRes
res.Sort = data.Sort
return &res, nil
}
//
//  @Title  获取指定信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *config) View(ctx context.Context, req *adminForm.ConfigViewReq) (*adminForm.ConfigViewRes, error) {
data, err := sysService.Config.View(ctx, input.SysConfigViewInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.ConfigViewRes
res.SysConfigViewModel = data
return &res, nil
}
//
//  @Title  查看列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *config) List(ctx context.Context, req *adminForm.ConfigListReq) (*adminForm.ConfigListRes, error) {
var (
in input.SysConfigListInp
res adminForm.ConfigListRes
)
if err := gconv.Scan(req, &in); err != nil {
return nil, err
}
list, totalCount, err := sysService.Config.List(ctx, in)
if err != nil {
return nil, err
}
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}

View File

@ -1,177 +0,0 @@
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/util/gconv"
)
// 部门
var Dept = dept{}
type dept struct{}
//
//  @Title  名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dept) NameUnique(ctx context.Context, req *adminForm.DeptNameUniqueReq) (*adminForm.DeptNameUniqueRes, error) {
data, err := adminService.Dept.NameUnique(ctx, input.AdminDeptNameUniqueInp{Id: req.Id, Name: req.Name})
if err != nil {
return nil, err
}
var res adminForm.DeptNameUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dept) Delete(ctx context.Context, req *adminForm.DeptDeleteReq) (res *adminForm.DeptDeleteRes, err error) {
var in input.AdminDeptDeleteInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Dept.Delete(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dept) Edit(ctx context.Context, req *adminForm.DeptEditReq) (res *adminForm.DeptEditRes, err error) {
var in input.AdminDeptEditInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Dept.Edit(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dept) MaxSort(ctx context.Context, req *adminForm.DeptMaxSortReq) (*adminForm.DeptMaxSortRes, error) {
data, err := adminService.Dept.MaxSort(ctx, input.AdminDeptMaxSortInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.DeptMaxSortRes
res.Sort = data.Sort
return &res, nil
}
//
//  @Title  获取指定信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dept) View(ctx context.Context, req *adminForm.DeptViewReq) (*adminForm.DeptViewRes, error) {
data, err := adminService.Dept.View(ctx, input.AdminDeptViewInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.DeptViewRes
res.AdminDeptViewModel = data
return &res, nil
}
//
//  @Title  查看列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dept) List(ctx context.Context, req *adminForm.DeptListReq) (*adminForm.DeptListRes, error) {
var (
in input.AdminDeptListInp
res adminForm.DeptListRes
)
if err := gconv.Scan(req, &in); err != nil {
return nil, err
}
data, err := adminService.Dept.List(ctx, in)
if err != nil {
return nil, err
}
_ = gconv.Structs(data, &res)
return &res, nil
}
//
//  @Title  查看列表树
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dept) ListTree(ctx context.Context, req *adminForm.DeptListTreeReq) (*adminForm.DeptListTreeRes, error) {
var (
in input.AdminDeptListTreeInp
res adminForm.DeptListTreeRes
)
if err := gconv.Scan(req, &in); err != nil {
return nil, err
}
data, err := adminService.Dept.ListTree(ctx, in)
if err != nil {
return nil, err
}
_ = gconv.Structs(data, &res)
return &res, nil
}

View File

@ -1,253 +0,0 @@
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/service/sysService"
)
// 字典
var Dict = dict{}
type dict struct{}
//
//  @Title  数据键值是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) DataUnique(ctx context.Context, req *adminForm.DictDataUniqueReq) (res *adminForm.DictDataUniqueRes, err error) {
res, err = sysService.Dict.DataUnique(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  查询字典数据最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) DataMaxSort(ctx context.Context, req *adminForm.DictDataMaxSortReq) (res *adminForm.DictDataMaxSortRes, err error) {
res, err = sysService.Dict.DataMaxSort(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  删除字典数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) DataDelete(ctx context.Context, req *adminForm.DictDataDeleteReq) (res *adminForm.DictDataDeleteRes, err error) {
if err = sysService.Dict.DataDelete(ctx, req); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增字典数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) DataEdit(ctx context.Context, req *adminForm.DictDataEditReq) (res *adminForm.DictDataEditRes, err error) {
if err = sysService.Dict.DataEdit(ctx, req); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  获取指定字典类型信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) DataView(ctx context.Context, req *adminForm.DictDataViewReq) (res *adminForm.DictDataViewRes, err error) {
res, err = sysService.Dict.DataView(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  获取字典数据列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) DataList(ctx context.Context, req *adminForm.DictDataListReq) (res *adminForm.DictDataListRes, err error) {
res, err = sysService.Dict.DataList(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  获取指定字典类型的属性数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) Attribute(ctx context.Context, req *adminForm.DictAttributeReq) (res *adminForm.DictAttributeRes, err error) {
res, err = sysService.Dict.Attribute(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  导出字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) TypeExport(ctx context.Context, req *adminForm.DictTypeExportReq) (res *adminForm.DictTypeExportRes, err error) {
if err = sysService.Dict.TypeExport(ctx, req); err != nil {
return nil, err
}
return
}
//
//  @Title  刷新字典缓存
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) TypeRefreshCache(ctx context.Context, req *adminForm.DictTypeRefreshCacheReq) (res *adminForm.DictTypeRefreshCacheRes, err error) {
return nil, nil
}
//
//  @Title  删除字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) TypeDelete(ctx context.Context, req *adminForm.DictTypeDeleteReq) (res *adminForm.DictTypeDeleteRes, err error) {
if err = sysService.Dict.TypeDelete(ctx, req); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) TypeEdit(ctx context.Context, req *adminForm.DictTypeEditReq) (res *adminForm.DictTypeEditRes, err error) {
if err = sysService.Dict.TypeEdit(ctx, req); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  类型是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) TypeUnique(ctx context.Context, req *adminForm.DictTypeUniqueReq) (res *adminForm.DictTypeUniqueRes, err error) {
res, err = sysService.Dict.TypeUnique(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  获取指定字典类型信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) TypeView(ctx context.Context, req *adminForm.DictTypeViewReq) (res *adminForm.DictTypeViewRes, err error) {
res, err = sysService.Dict.TypeView(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  获取字典类型列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) TypeList(ctx context.Context, req *adminForm.DictTypeListReq) (res *adminForm.DictTypeListRes, err error) {
res, err = sysService.Dict.TypeList(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}

View File

@ -1,96 +0,0 @@
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/sysService"
"github.com/gogf/gf/v2/errors/gerror"
)
// 日志
var Log = log{}
type log struct{}
//
//  @Title  清空日志
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *log) Clear(ctx context.Context, req *adminForm.LogClearReq) (res *adminForm.LogClearRes, err error) {
err = gerror.New("考虑安全,请到数据库清空")
return
}
//
//  @Title  导出
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *log) Export(ctx context.Context, req *adminForm.LogExportReq) (res *adminForm.LogExportRes, err error) {
err = sysService.Log.Export(ctx, input.LogListInp{
Page: req.Page,
Limit: req.Limit,
Module: req.Module,
Method: req.Method,
Url: req.Url,
Ip: req.Ip,
ErrorCode: req.ErrorCode,
StartTime: req.StartTime,
EndTime: req.EndTime,
MemberId: req.MemberId,
TakeUpTime: req.TakeUpTime,
})
if err != nil {
return nil, err
}
return
}
//
//  @Title  获取全局日志列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *log) List(ctx context.Context, req *adminForm.LogListReq) (*adminForm.LogListRes, error) {
list, totalCount, err := sysService.Log.List(ctx, input.LogListInp{
Page: req.Page,
Limit: req.Limit,
Module: req.Module,
Method: req.Method,
Url: req.Url,
Ip: req.Ip,
ErrorCode: req.ErrorCode,
StartTime: req.StartTime,
EndTime: req.EndTime,
MemberId: req.MemberId,
TakeUpTime: req.TakeUpTime,
})
if err != nil {
return nil, err
}
var res adminForm.LogListRes
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}

View File

@ -1,104 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/util/gconv"
)
var Login = login{}
type login struct{}
//
//  @Title  登录验证码
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *login) Captcha(ctx context.Context, req *adminForm.LoginCaptchaReq) (res *adminForm.LoginCaptchaRes, err error) {
// TODO  获取生成的验证码图片
Cid, Base64 := com.Captcha.GetVerifyImgString(ctx)
res = &adminForm.LoginCaptchaRes{Cid: Cid, Base64: Base64}
return
}
//
//  @Title  提交登录
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *login) Sign(ctx context.Context, req *adminForm.LoginReq) (res *adminForm.LoginRes, err error) {
//// 校验 验证码
//if !com.Captcha.VerifyString(req.Cid, req.Code) {
// err = gerror.New("验证码错误")
// return
//}
var in input.AdminMemberLoginSignInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
model, err := adminService.Member.Login(ctx, in)
if err != nil {
return nil, err
}
if err = gconv.Scan(model, &res); err != nil {
return nil, err
}
return
}
//
//  @Title  注销登录
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *login) Logout(ctx context.Context, req *adminForm.LoginLogoutReq) (res *adminForm.LoginLogoutRes, err error) {
var authorization = com.Jwt.GetAuthorization(com.Context.Get(ctx).Request)
// TODO 获取jwtToken
jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization)
if len(jwtToken) == 0 {
err = gerror.New("当前用户未登录!")
return res, err
}
// TODO  删除登录token
cache := com.Cache.New()
_, err = cache.Remove(ctx, jwtToken)
if err != nil {
return res, err
}
return
}

View File

@ -1,372 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/util/gconv"
)
// 会员
var Member = member{}
type member struct{}
//
//  @Title  修改登录密码
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) UpdateProfile(ctx context.Context, req *adminForm.MemberUpdateProfileReq) (res *adminForm.MemberUpdateProfileRes, err error) {
var in input.AdminMemberUpdateProfileInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Member.UpdateProfile(ctx, in); err != nil {
return nil, err
}
return
}
//
//  @Title  修改登录密码
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) UpdatePwd(ctx context.Context, req *adminForm.MemberUpdatePwdReq) (res *adminForm.MemberUpdatePwdRes, err error) {
memberId := com.Context.Get(ctx).User.Id
if memberId <= 0 {
err := gerror.New("获取用户信息失败!")
return nil, err
}
if err = adminService.Member.
UpdatePwd(ctx, input.AdminMemberUpdatePwdInp{Id: memberId, OldPassword: req.OldPassword, NewPassword: req.NewPassword}); err != nil {
return nil, err
}
return
}
//
//  @Title  获取登录用户的基本信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) Profile(ctx context.Context, req *adminForm.MemberProfileReq) (*adminForm.MemberProfileRes, error) {
var res adminForm.MemberProfileRes
memberId := com.Context.Get(ctx).User.Id
if memberId <= 0 {
err := gerror.New("获取用户信息失败!")
return nil, err
}
// TODO  用户基本信息
memberInfo, err := adminService.Member.View(ctx, input.AdminMemberViewInp{Id: memberId})
if err != nil {
return nil, err
}
res.User = memberInfo
// TODO  所在部门
sysDept, err := adminService.Dept.View(ctx, input.AdminDeptViewInp{Id: memberInfo.DeptId})
if err != nil {
return nil, err
}
res.SysDept = sysDept
// TODO  角色列表
sysRoles, err := adminService.Role.GetMemberList(ctx, memberInfo.Role)
if err != nil {
return nil, err
}
res.SysRoles = sysRoles
// TODO  获取角色名称
roleGroup, err := adminService.Role.GetName(ctx, memberInfo.Role)
if err != nil {
return nil, err
}
res.RoleGroup = roleGroup
// TODO  获取第一岗位名称
postGroup, err := adminService.Post.GetMemberByStartName(ctx, memberInfo.Id)
if err != nil {
return nil, err
}
res.PostGroup = postGroup
return &res, nil
}
//
//  @Title  重置密码
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) ResetPwd(ctx context.Context, req *adminForm.MemberResetPwdReq) (res *adminForm.MemberResetPwdRes, err error) {
if err = adminService.Member.
ResetPwd(ctx, input.AdminMemberResetPwdInp{Id: req.Id, Password: req.Password}); err != nil {
return nil, err
}
return
}
//
//  @Title  邮箱是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) EmailUnique(ctx context.Context, req *adminForm.MemberEmailUniqueReq) (*adminForm.MemberEmailUniqueRes, error) {
data, err := adminService.Member.EmailUnique(ctx, input.AdminMemberEmailUniqueInp{Id: req.Id, Email: req.Email})
if err != nil {
return nil, err
}
var res adminForm.MemberEmailUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  手机号是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) MobileUnique(ctx context.Context, req *adminForm.MemberMobileUniqueReq) (*adminForm.MemberMobileUniqueRes, error) {
data, err := adminService.Member.MobileUnique(ctx, input.AdminMemberMobileUniqueInp{Id: req.Id, Mobile: req.Mobile})
if err != nil {
return nil, err
}
var res adminForm.MemberMobileUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) NameUnique(ctx context.Context, req *adminForm.MemberNameUniqueReq) (*adminForm.MemberNameUniqueRes, error) {
data, err := adminService.Member.NameUnique(ctx, input.AdminMemberNameUniqueInp{Id: req.Id, Username: req.Username})
if err != nil {
return nil, err
}
var res adminForm.MemberNameUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) Delete(ctx context.Context, req *adminForm.MemberDeleteReq) (res *adminForm.MemberDeleteRes, err error) {
err = gerror.New("考虑安全暂时不允许删除用户,请选择禁用!")
return nil, err
var in input.AdminMemberDeleteInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Member.Delete(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) Edit(ctx context.Context, req *adminForm.MemberEditReq) (res *adminForm.MemberEditRes, err error) {
var in input.AdminMemberEditInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Member.Edit(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) MaxSort(ctx context.Context, req *adminForm.MemberMaxSortReq) (*adminForm.MemberMaxSortRes, error) {
data, err := adminService.Member.MaxSort(ctx, input.AdminMemberMaxSortInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.MemberMaxSortRes
res.Sort = data.Sort
return &res, nil
}
//
//  @Title  获取指定信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) View(ctx context.Context, req *adminForm.MemberViewReq) (*adminForm.MemberViewRes, error) {
postsList, _, err := adminService.Post.List(ctx, input.AdminPostListInp{})
if err != nil {
return nil, err
}
roleList, _, err := adminService.Role.List(ctx, input.AdminRoleListInp{})
if err != nil {
return nil, err
}
var res adminForm.MemberViewRes
res.Posts = postsList
res.Roles = roleList
if req.Id <= 0 {
return &res, err
}
memberInfo, err := adminService.Member.View(ctx, input.AdminMemberViewInp{Id: req.Id})
if err != nil {
return nil, err
}
res.AdminMemberViewModel = memberInfo
res.PostIds, err = adminService.MemberPost.GetMemberByIds(ctx, memberInfo.Id)
if err != nil {
return nil, err
}
res.RoleIds = []int64{memberInfo.Role}
res.DeptName, err = adminService.Dept.GetName(ctx, memberInfo.DeptId)
if err != nil {
return nil, err
}
return &res, nil
}
//
//  @Title  查看列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) List(ctx context.Context, req *adminForm.MemberListReq) (*adminForm.MemberListRes, error) {
var (
in input.AdminMemberListInp
res adminForm.MemberListRes
)
if err := gconv.Scan(req, &in); err != nil {
return nil, err
}
list, totalCount, err := adminService.Member.List(ctx, in)
if err != nil {
return nil, err
}
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}
//
//  @Title  登录用户信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) Info(ctx context.Context, req *adminForm.MemberInfoReq) (res *adminForm.MemberInfoRes, err error) {
return adminService.Member.LoginMemberInfo(ctx, req)
}

View File

@ -1,189 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/util/gconv"
)
// 菜单
var Menu = menu{}
type menu struct{}
//
//  @Title  查询角色菜单列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) RoleList(ctx context.Context, req *adminForm.MenuRoleListReq) (*adminForm.MenuRoleListRes, error) {
var in input.MenuRoleListInp
if err := gconv.Scan(req, &in); err != nil {
return nil, err
}
data, err := adminService.Menu.RoleList(ctx, in)
if err != nil {
return nil, err
}
var res adminForm.MenuRoleListRes
res.CheckedKeys = data.CheckedKeys
res.Menus = data.Menus
return &res, nil
}
//
//  @Title  查询菜单列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) SearchList(ctx context.Context, req *adminForm.MenuSearchListReq) (res *adminForm.MenuSearchListRes, err error) {
res, err = adminService.Menu.SearchList(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) MaxSort(ctx context.Context, req *adminForm.MenuMaxSortReq) (res *adminForm.MenuMaxSortRes, err error) {
res, err = adminService.Menu.MaxSort(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  菜单名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) NameUnique(ctx context.Context, req *adminForm.MenuNameUniqueReq) (res *adminForm.MenuNameUniqueRes, err error) {
res, err = adminService.Menu.NameUnique(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  菜单编码是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) CodeUnique(ctx context.Context, req *adminForm.MenuCodeUniqueReq) (res *adminForm.MenuCodeUniqueRes, err error) {
res, err = adminService.Menu.CodeUnique(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) Delete(ctx context.Context, req *adminForm.MenuDeleteReq) (res *adminForm.MenuDeleteRes, err error) {
if err = adminService.Menu.Delete(ctx, req); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) Edit(ctx context.Context, req *adminForm.MenuEditReq) (res *adminForm.MenuEditRes, err error) {
if err = adminService.Menu.Edit(ctx, req); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  获取信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) View(ctx context.Context, req *adminForm.MenuViewReq) (res *adminForm.MenuViewRes, err error) {
res, err = adminService.Menu.View(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *menu) List(ctx context.Context, req *adminForm.MenuListReq) (res *adminForm.MenuListRes, err error) {
res, err = adminService.Menu.List(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}

View File

@ -1,152 +0,0 @@
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/util/gconv"
)
// 公告
var Notice = notice{}
type notice struct{}
//
//  @Title  名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *notice) NameUnique(ctx context.Context, req *adminForm.NoticeNameUniqueReq) (*adminForm.NoticeNameUniqueRes, error) {
data, err := adminService.Notice.NameUnique(ctx, input.AdminNoticeNameUniqueInp{Id: req.Id, Title: req.Title})
if err != nil {
return nil, err
}
var res adminForm.NoticeNameUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *notice) Delete(ctx context.Context, req *adminForm.NoticeDeleteReq) (res *adminForm.NoticeDeleteRes, err error) {
var in input.AdminNoticeDeleteInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Notice.Delete(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *notice) Edit(ctx context.Context, req *adminForm.NoticeEditReq) (res *adminForm.NoticeEditRes, err error) {
var in input.AdminNoticeEditInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Notice.Edit(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *notice) MaxSort(ctx context.Context, req *adminForm.NoticeMaxSortReq) (*adminForm.NoticeMaxSortRes, error) {
data, err := adminService.Notice.MaxSort(ctx, input.AdminNoticeMaxSortInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.NoticeMaxSortRes
res.Sort = data.Sort
return &res, nil
}
//
//  @Title  获取指定信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *notice) View(ctx context.Context, req *adminForm.NoticeViewReq) (*adminForm.NoticeViewRes, error) {
data, err := adminService.Notice.View(ctx, input.AdminNoticeViewInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.NoticeViewRes
res.AdminNoticeViewModel = data
return &res, nil
}
//
//  @Title  查看列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *notice) List(ctx context.Context, req *adminForm.NoticeListReq) (*adminForm.NoticeListRes, error) {
var (
in input.AdminNoticeListInp
res adminForm.NoticeListRes
)
if err := gconv.Scan(req, &in); err != nil {
return nil, err
}
list, totalCount, err := adminService.Notice.List(ctx, in)
if err != nil {
return nil, err
}
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}

View File

@ -1,171 +0,0 @@
package adminController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/util/gconv"
)
// 岗位
var Post = post{}
type post struct{}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *post) Delete(ctx context.Context, req *adminForm.PostDeleteReq) (res *adminForm.PostDeleteRes, err error) {
var in input.AdminPostDeleteInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Post.Delete(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *post) Edit(ctx context.Context, req *adminForm.PostEditReq) (res *adminForm.PostEditRes, err error) {
var in input.AdminPostEditInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
if err = adminService.Post.Edit(ctx, in); err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *post) MaxSort(ctx context.Context, req *adminForm.PostMaxSortReq) (*adminForm.PostMaxSortRes, error) {
data, err := adminService.Post.MaxSort(ctx, input.AdminPostMaxSortInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.PostMaxSortRes
res.Sort = data.Sort
return &res, nil
}
//
//  @Title  名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *post) NameUnique(ctx context.Context, req *adminForm.PostNameUniqueReq) (*adminForm.PostNameUniqueRes, error) {
data, err := adminService.Post.NameUnique(ctx, input.AdminPostNameUniqueInp{Id: req.Id, Name: req.Name})
if err != nil {
return nil, err
}
var res adminForm.PostNameUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  编码是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *post) CodeUnique(ctx context.Context, req *adminForm.PostCodeUniqueReq) (*adminForm.PostCodeUniqueRes, error) {
data, err := adminService.Post.CodeUnique(ctx, input.AdminPostCodeUniqueInp{Id: req.Id, Code: req.Code})
if err != nil {
return nil, err
}
var res adminForm.PostCodeUniqueRes
res.IsUnique = data.IsUnique
return &res, nil
}
//
//  @Title  获取指定信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *post) View(ctx context.Context, req *adminForm.PostViewReq) (*adminForm.PostViewRes, error) {
data, err := adminService.Post.View(ctx, input.AdminPostViewInp{Id: req.Id})
if err != nil {
return nil, err
}
var res adminForm.PostViewRes
res.AdminPostViewModel = data
return &res, nil
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *post) List(ctx context.Context, req *adminForm.PostListReq) (*adminForm.PostListRes, error) {
list, totalCount, err := adminService.Post.List(ctx, input.AdminPostListInp{
Page: req.Page,
Limit: req.Limit,
Name: req.Name,
Code: req.Code,
Status: req.Status,
})
if err != nil {
return nil, err
}
var res adminForm.PostListRes
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}

View File

@ -1,115 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminController
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
)
// 角色
var Role = role{}
type role struct{}
//
//  @Title  获取角色下的会员列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *role) RoleMemberList(ctx context.Context, req *adminForm.RoleMemberListReq) (*adminForm.RoleMemberListRes, error) {
var in input.AdminRoleMemberListInp
if err := gconv.Scan(req, &in); err != nil {
return nil, err
}
list, totalCount, err := adminService.Member.RoleMemberList(ctx, in)
if err != nil {
return nil, err
}
var res adminForm.RoleMemberListRes
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *role) List(ctx context.Context, req *adminForm.RoleListReq) (*adminForm.RoleListRes, error) {
list, totalCount, err := adminService.Role.List(ctx, input.AdminRoleListInp{
Page: req.Page,
Limit: req.Limit,
})
if err != nil {
return nil, err
}
var res adminForm.RoleListRes
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}
//
//  @Title  动态路由
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *role) Dynamic(ctx context.Context, req *adminForm.RoleDynamicReq) (res *adminForm.RoleDynamicRes, err error) {
res, err = adminService.Menu.GetMenuList(ctx, com.Context.GetUserId(ctx))
if err != nil {
return nil, err
}
return res, nil
}
//
//  @Title  修改角色菜单权限
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *role) Edit(ctx context.Context, req *adminForm.RoleMenuEditReq) (res *adminForm.RoleMenuEditRes, err error) {
err = adminService.Role.EditRoleMenu(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}

View File

@ -1,96 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package apiController
import (
"context"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/apiForm"
"github.com/bufanyun/hotgo/app/model"
"github.com/gogf/gf/v2/frame/g"
"github.com/xuri/excelize/v2"
"time"
)
// 基础
var Base = base{}
type base struct{}
//
//  @Title  获取lang信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *base) Lang(ctx context.Context, req *apiForm.BaseLangReq) (res *apiForm.BaseLangRes, err error) {
return
}
//
//  @Title  获取IP归属地信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *base) IpLocation(ctx context.Context, req *apiForm.IpLocationReq) (res *apiForm.IpLocationRes, err error) {
panic("测试panic...")
data := com.Ip.GetLocation(ctx, req.Ip)
res = &apiForm.IpLocationRes{data}
return
}
func (controller *base) Excel(ctx context.Context, req *apiForm.ExportReq) (res *apiForm.ExportRes, err error) {
w := com.Context.Get(ctx).Request.Response
// 文件名
fileName := "demo.xlsx"
// 创建excel文件 第三方excel包
file := excelize.NewFile()
// 填充数据
index := file.NewSheet("Sheet1")
err = file.SetCellValue("Sheet1", "A1", "Hello world.")
if err != nil {
g.Log().Print(ctx, "SetCellValue:", err)
return nil, err
}
err = file.SetCellValue("Sheet1", "B1", 100)
if err != nil {
g.Log().Print(ctx, "SetCellValue2:", err)
return nil, err
}
file.SetActiveSheet(index)
// 设置header头
w.Header().Add("Content-Disposition", "attachment; filename="+fileName)
w.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
// 写入字节数据
err = file.Write(w.Writer)
if err != nil {
g.Log().Print(ctx, "Write:", err)
return nil, err
}
// TODO 加入到上下文
com.Context.SetResponse(ctx, &model.Response{
Code: consts.CodeOK,
Message: "",
Timestamp: time.Now().Unix(),
ReqId: com.Context.Get(ctx).ReqId,
})
//com.Context.Get(ctx).Request.Exit()
return
}

View File

@ -1,30 +0,0 @@
package apiController
import (
"context"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/service/sysService"
)
// 字典
var Dict = dict{}
type dict struct{}
//
//  @Title  获取指定字典类型的属性数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *dict) Attribute(ctx context.Context, req *adminForm.DictAttributeReq) (res *adminForm.DictAttributeRes, err error) {
res, err = sysService.Dict.Attribute(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}

View File

@ -1,96 +0,0 @@
package apiController
import (
"context"
"github.com/bufanyun/hotgo/app/form/apiForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/sysService"
"github.com/gogf/gf/v2/errors/gerror"
)
// 日志
var Log = log{}
type log struct{}
//
//  @Title  清空日志
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *log) Clear(ctx context.Context, req *apiForm.LogClearReq) (res *apiForm.LogClearRes, err error) {
err = gerror.New("考虑安全,请到数据库清空")
return
}
//
//  @Title  导出
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *log) Export(ctx context.Context, req *apiForm.LogExportReq) (res *apiForm.LogExportRes, err error) {
err = sysService.Log.Export(ctx, input.LogListInp{
Page: req.Page,
Limit: req.Limit,
Module: req.Module,
Method: req.Method,
Url: req.Url,
Ip: req.Ip,
ErrorCode: req.ErrorCode,
StartTime: req.StartTime,
EndTime: req.EndTime,
MemberId: req.MemberId,
TakeUpTime: req.TakeUpTime,
})
if err != nil {
return nil, err
}
return
}
//
//  @Title  获取全局日志列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *log) List(ctx context.Context, req *apiForm.LogListReq) (*apiForm.LogListRes, error) {
list, totalCount, err := sysService.Log.List(ctx, input.LogListInp{
Page: req.Page,
Limit: req.Limit,
Module: req.Module,
Method: req.Method,
Url: req.Url,
Ip: req.Ip,
ErrorCode: req.ErrorCode,
StartTime: req.StartTime,
EndTime: req.EndTime,
MemberId: req.MemberId,
TakeUpTime: req.TakeUpTime,
})
if err != nil {
return nil, err
}
var res apiForm.LogListRes
res.List = list
res.TotalCount = totalCount
res.Limit = req.Page
res.Limit = req.Limit
return &res, nil
}

View File

@ -1,99 +0,0 @@
package apiController
import (
"context"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/apiForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/util/gconv"
)
// 登录
var Login = login{}
type login struct{}
//
//  @Title  检查登录
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *login) Check(ctx context.Context, req *apiForm.LoginCheckReq) (*apiForm.LoginCheckRes, error) {
var res apiForm.LoginCheckRes
res.IsValidCodeLogin = false
res.Result = "login"
return &res, nil
}
//
//  @Title  提交登录
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *login) Sign(ctx context.Context, req *apiForm.LoginReq) (res *apiForm.LoginRes, err error) {
//// 校验 验证码
//if !com.Captcha.VerifyString(req.Cid, req.Code) {
// err = gerror.New("验证码错误")
// return
//}
var in input.AdminMemberLoginSignInp
if err = gconv.Scan(req, &in); err != nil {
return nil, err
}
model, err := adminService.Member.Login(ctx, in)
if err != nil {
return nil, err
}
if err = gconv.Scan(model, &res); err != nil {
return nil, err
}
return
}
//
//  @Title  注销登录
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *login) Logout(ctx context.Context, req *apiForm.LoginLogoutReq) (res *apiForm.LoginLogoutRes, err error) {
var authorization = com.Jwt.GetAuthorization(com.Context.Get(ctx).Request)
// TODO 获取jwtToken
jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization)
if len(jwtToken) == 0 {
err = gerror.New("当前用户未登录!")
return res, err
}
// TODO  删除登录token
cache := com.Cache.New()
_, err = cache.Remove(ctx, jwtToken)
if err != nil {
return res, err
}
return
}

View File

@ -1,72 +0,0 @@
package apiController
import (
"context"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/form/apiForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/adminService"
"github.com/gogf/gf/v2/errors/gerror"
)
// 会员
var Member = member{}
type member struct{}
//
//  @Title  获取登录用户的基本信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (controller *member) Profile(ctx context.Context, req *apiForm.MemberProfileReq) (*apiForm.MemberProfileRes, error) {
var res apiForm.MemberProfileRes
memberId := com.Context.Get(ctx).User.Id
if memberId <= 0 {
err := gerror.New("获取用户信息失败!")
return nil, err
}
// TODO  用户基本信息
memberInfo, err := adminService.Member.View(ctx, input.AdminMemberViewInp{Id: memberId})
if err != nil {
return nil, err
}
res.User = memberInfo
// TODO  所在部门
sysDept, err := adminService.Dept.View(ctx, input.AdminDeptViewInp{Id: memberInfo.DeptId})
if err != nil {
return nil, err
}
res.SysDept = sysDept
// TODO  角色列表
sysRoles, err := adminService.Role.GetMemberList(ctx, memberInfo.Role)
if err != nil {
return nil, err
}
res.SysRoles = sysRoles
// TODO  获取角色名称
roleGroup, err := adminService.Role.GetName(ctx, memberInfo.Role)
if err != nil {
return nil, err
}
res.RoleGroup = roleGroup
// TODO  获取第一岗位名称
postGroup, err := adminService.Post.GetMemberByStartName(ctx, memberInfo.Id)
if err != nil {
return nil, err
}
res.PostGroup = postGroup
return &res, nil
}

View File

@ -1,63 +0,0 @@
package queue
import (
"container/list"
"sync"
)
type Queue struct {
l *list.List
m sync.Mutex
}
func NewQueue() *Queue {
return &Queue{l: list.New()}
}
func (q *Queue) LPush(v interface{}) {
if v == nil {
return
}
q.m.Lock()
defer q.m.Unlock()
q.l.PushFront(v)
}
func (q *Queue) RPush(v interface{}) {
if v == nil {
return
}
q.m.Lock()
defer q.m.Unlock()
q.l.PushBack(v)
}
func (q *Queue) LPop() interface{} {
q.m.Lock()
defer q.m.Unlock()
element := q.l.Front()
if element == nil {
return nil
}
q.l.Remove(element)
return element.Value
}
func (q *Queue) RPop() interface{} {
q.m.Lock()
defer q.m.Unlock()
element := q.l.Back()
if element == nil {
return nil
}
q.l.Remove(element)
return element.Value
}
func (q *Queue) Len() int {
return q.l.Len()
}

View File

@ -1,248 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package queue
import (
"github.com/bufanyun/hotgo/app/utils"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"sync"
"time"
)
//
//  MqProducer
//  @Description 
//
type MqProducer interface {
SendMsg(topic string, body string) (mqMsg MqMsg, err error)
SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error)
}
//
//  MqConsumer
//  @Description 
//
type MqConsumer interface {
ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error)
}
const (
_ = iota
SendMsg
ReceiveMsg
)
type MqMsg struct {
RunType int `json:"run_type"`
Topic string `json:"topic"`
MsgId string `json:"msg_id"`
Offset int64 `json:"offset"`
Partition int32 `json:"partition"`
Timestamp time.Time `json:"timestamp"`
Body []byte `json:"body"`
}
var (
ctx = gctx.New()
mqProducerInstanceMap map[string]MqProducer
mqConsumerInstanceMap map[string]MqConsumer
mutex sync.Mutex
)
func init() {
mqProducerInstanceMap = make(map[string]MqProducer)
mqConsumerInstanceMap = make(map[string]MqConsumer)
}
//
//  @Title  实例化消费者
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Return  mqClient
//  @Return  err
//
func InstanceConsumer() (mqClient MqConsumer, err error) {
groupName, _ := g.Cfg().Get(ctx, "queue.groupName", "hotgo")
return NewConsumer(groupName.String())
}
//
//  @Title  实例化生产者
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Return  mqClient
//  @Return  err
//
func InstanceProducer() (mqClient MqProducer, err error) {
groupName, _ := g.Cfg().Get(ctx, "queue.groupName", "hotgo")
return NewProducer(groupName.String())
}
//
//  @Title  新建一个生产者实例
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   groupName
//  @Return  mqClient
//  @Return  err
//
func NewProducer(groupName string) (mqClient MqProducer, err error) {
if item, ok := mqProducerInstanceMap[groupName]; ok {
return item, nil
}
if groupName == "" {
return mqClient, gerror.New("mq groupName is empty.")
}
// 驱动
driver, _ := g.Cfg().Get(ctx, "queue.driver", "")
// 重试次数
retryCount, _ := g.Cfg().Get(ctx, "queue.retry", 2)
retry := retryCount.Int()
switch driver.String() {
case "rocketmq":
address, _ := g.Cfg().Get(ctx, "queue.rocketmq.address", nil)
if len(address.Strings()) == 0 {
panic("queue rocketmq address is not support")
}
mqClient = RegisterRocketProducerMust(address.Strings(), groupName, retry)
case "kafka":
address, _ := g.Cfg().Get(ctx, "queue.kafka.address", nil)
if len(address.Strings()) == 0 {
panic("queue kafka address is not support")
}
version, _ := g.Cfg().Get(ctx, "queue.kafka.version", "2.0.0")
mqClient = RegisterKafkaProducerMust(KafkaConfig{
Brokers: address.Strings(),
GroupID: groupName,
Version: version.String(),
})
case "redis":
address, _ := g.Cfg().Get(ctx, "queue.redis.address", nil)
if len(address.String()) == 0 {
panic("queue redis address is not support")
}
db, _ := g.Cfg().Get(ctx, "queue.redis.db", 0)
pass, _ := g.Cfg().Get(ctx, "queue.redis.pass", "")
timeout, _ := g.Cfg().Get(ctx, "queue.redis.timeout", 0)
mqClient = RegisterRedisMqProducerMust(RedisOption{
Addr: address.String(),
Passwd: pass.String(),
DBnum: db.Int(),
Timeout: timeout.Int(),
}, PoolOption{
5, 50, 5,
}, groupName, retry)
default:
panic("queue driver is not support")
}
mutex.Lock()
defer mutex.Unlock()
mqProducerInstanceMap[groupName] = mqClient
return mqClient, nil
}
//
//  @Title  新建一个消费者实例
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   groupName
//  @Return  mqClient
//  @Return  err
//
func NewConsumer(groupName string) (mqClient MqConsumer, err error) {
// 是否支持创建多个消费者
multiComsumer, _ := g.Cfg().Get(ctx, "queue.multiComsumer", true)
randTag := string(utils.Charset.RandomCreateBytes(6))
if multiComsumer.Bool() == false {
randTag = "001"
}
if item, ok := mqConsumerInstanceMap[groupName+"-"+randTag]; ok {
return item, nil
}
driver, _ := g.Cfg().Get(ctx, "queue.driver", "")
if groupName == "" {
return mqClient, gerror.New("mq groupName is empty.")
}
switch driver.String() {
case "rocketmq":
address, _ := g.Cfg().Get(ctx, "queue.rocketmq.address", nil)
if address == nil {
return nil, gerror.New("queue.rocketmq.address is empty.")
}
mqClient = RegisterRocketConsumerMust(address.Strings(), groupName)
case "kafka":
address, _ := g.Cfg().Get(ctx, "queue.kafka.address", nil)
if len(address.Strings()) == 0 {
panic("queue kafka address is not support")
}
version, _ := g.Cfg().Get(ctx, "queue.kafka.version", "2.0.0")
clientId := "HOTGO-Consumer-" + groupName
randClient, _ := g.Cfg().Get(ctx, "queue.kafka.randClient", true)
if randClient.Bool() {
clientId += "-" + randTag
}
mqClient = RegisterKafkaMqConsumerMust(KafkaConfig{
Brokers: address.Strings(),
GroupID: groupName,
Version: version.String(),
ClientId: clientId,
})
case "redis":
address, _ := g.Cfg().Get(ctx, "queue.redis.address", nil)
if len(address.String()) == 0 {
panic("queue redis address is not support")
}
db, _ := g.Cfg().Get(ctx, "queue.redis.db", 0)
pass, _ := g.Cfg().Get(ctx, "queue.redis.pass", "")
timeout, _ := g.Cfg().Get(ctx, "queue.redis.pass", 0)
mqClient = RegisterRedisMqConsumerMust(RedisOption{
Addr: address.String(),
Passwd: pass.String(),
DBnum: db.Int(),
Timeout: timeout.Int(),
}, PoolOption{
5, 50, 5,
}, groupName)
default:
panic("queue driver is not support")
}
mutex.Lock()
defer mutex.Unlock()
mqConsumerInstanceMap[groupName] = mqClient
return mqClient, nil
}
//
//  @Title  返回消息体
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Return  string
//
func (m *MqMsg) BodyString() string {
return string(m.Body)
}

View File

@ -1,133 +0,0 @@
package queue
import (
"fmt"
"testing"
"time"
)
func TestRPushQueue(t *testing.T) {
ll := NewQueue()
ll.RPush("1")
ll.RPush("2")
ll.RPush("3")
go func() {
ll.RPush("4")
}()
go func() {
ll.RPush("5")
}()
go func() {
ll.RPush("6")
}()
time.Sleep(1 * time.Second)
if ll.Len() != 6 {
t.Error("list Len() do error #1")
}
listVal := fmt.Sprintf("num=>%v,%v,%v", ll.LPop(), ll.LPop(), ll.LPop())
if listVal != "num=>1,2,3" {
t.Error("list do error #2")
}
if ll.Len() != 3 {
t.Error("list Len() do error #3")
}
ll.LPop()
ll.LPop()
ll.LPop()
c := ll.LPop()
if c != nil {
t.Error("list LPop() do error #4")
}
time.Sleep(1 * time.Second)
}
func TestLPushQueue(t *testing.T) {
ll := NewQueue()
ll.LPush("1")
ll.LPush("2")
ll.LPush("3")
go func() {
ll.LPush("4")
}()
go func() {
ll.LPush("5")
}()
go func() {
ll.LPush("6")
}()
time.Sleep(1 * time.Second)
if ll.Len() != 6 {
t.Error("list Len() do error #1")
}
listVal := fmt.Sprintf("num=>%v,%v,%v", ll.RPop(), ll.RPop(), ll.RPop())
if listVal != "num=>1,2,3" {
t.Error("list do error #2")
}
if ll.Len() != 3 {
t.Error("list Len() do error #3")
}
ll.RPop()
ll.RPop()
ll.RPop()
c := ll.RPop()
if c != nil {
t.Error("list RPop() do error #4")
}
time.Sleep(1 * time.Second)
}
func TestRegisterRocketMqProducer(t *testing.T) {
ins, err := RegisterRocketMqProducer([]string{}, "tests", 2)
if err == nil {
t.Error("RegisterRocketMqProducer err #1")
}
ins, err = RegisterRocketMqProducer([]string{"192.168.1.1:9876"}, "tests", 2)
if err != nil {
t.Error("RegisterRocketMqProducer err #2")
}
if ins.endPoints[0] != "192.168.1.1:9876" {
t.Error("RegisterRocketMqProducer err #3")
}
}
func TestRegisterRocketMqConsumer(t *testing.T) {
ins, err := RegisterRocketMqConsumer([]string{}, "tests")
if err == nil {
t.Error("RegisterRocketMqConsumer err #1")
}
ins, err = RegisterRocketMqProducer([]string{"192.168.1.1:9876"}, "tests", 2)
if err != nil {
t.Error("RegisterRocketMqConsumer err #2")
}
if ins.endPoints[0] != "192.168.1.1:9876" {
t.Error("RegisterRocketMqConsumer err #3")
}
}

View File

@ -1,79 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminForm
import (
"github.com/bufanyun/hotgo/app/form"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/gogf/gf/v2/frame/g"
)
// 获取指定配置键的值
type ConfigGetValueReq struct {
g.Meta `path:"/config/get_value" method:"get" tags:"配置" summary:"获取指定配置键的值"`
Key string `json:"key" v:"required#配置键不能为空" dc:"配置键"`
}
type ConfigGetValueRes struct {
Value string `json:"value" dc:"配置值"`
}
// 名称是否唯一
type ConfigNameUniqueReq struct {
g.Meta `path:"/config/name_unique" method:"get" tags:"配置" summary:"配置名称是否唯一"`
Name string `json:"name" v:"required#配置名称不能为空" dc:"配置名称"`
Id int64 `json:"id" dc:"配置ID"`
}
type ConfigNameUniqueRes struct {
IsUnique bool `json:"is_unique" dc:"是否唯一"`
}
// 查询列表
type ConfigListReq struct {
g.Meta `path:"/config/list" method:"get" tags:"配置" summary:"获取配置列表"`
form.PageReq
form.RangeDateReq
form.StatusReq
Name string `json:"name" dc:"配置名称"`
}
type ConfigListRes struct {
List []*input.SysConfigListModel `json:"list" dc:"数据列表"`
form.PageRes
}
// 获取指定信息
type ConfigViewReq struct {
g.Meta `path:"/config/view" method:"get" tags:"配置" summary:"获取指定信息"`
Id string `json:"id" v:"required#配置ID不能为空" dc:"配置ID"`
}
type ConfigViewRes struct {
*input.SysConfigViewModel
}
// 修改/新增
type ConfigEditReq struct {
g.Meta `path:"/config/edit" method:"post" tags:"配置" summary:"修改/新增配置"`
entity.SysConfig
}
type ConfigEditRes struct{}
// 删除
type ConfigDeleteReq struct {
g.Meta `path:"/config/delete" method:"post" tags:"配置" summary:"删除配置"`
Id interface{} `json:"id" v:"required#配置ID不能为空" dc:"配置ID"`
}
type ConfigDeleteRes struct{}
// 最大排序
type ConfigMaxSortReq struct {
g.Meta `path:"/config/max_sort" method:"get" tags:"配置" summary:"配置最大排序"`
Id int64 `json:"id" dc:"配置ID"`
}
type ConfigMaxSortRes struct {
Sort int `json:"sort" dc:"排序"`
}

View File

@ -1,142 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminForm
import (
"github.com/bufanyun/hotgo/app/form"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/gogf/gf/v2/frame/g"
)
/************************ 字典数据 *****************/
// 数据键值是否唯一
type DictDataUniqueReq struct {
g.Meta `path:"/dict_data/unique" method:"get" tags:"字典" summary:"数据键值是否唯一"`
Value string `json:"value" v:"required#数据键值不能为空" dc:"数据键值"`
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" dc:"字典类型"`
Id int64 `json:"id" dc:"字典数据ID"`
}
type DictDataUniqueRes struct {
IsUnique bool `json:"is_unique" dc:"是否唯一"`
}
// 查询字典数据最大排序
type DictDataMaxSortReq struct {
g.Meta `path:"/dict_data/max_sort" method:"get" tags:"字典" summary:"查询字典数据最大排序"`
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" dc:"字典类型"`
}
type DictDataMaxSortRes struct {
Sort int `json:"sort" dc:"排序"`
}
// 修改/新增字典数据
type DictDataEditReq struct {
g.Meta `path:"/dict_data/edit" method:"post" tags:"字典" summary:"修改/新增字典数据"`
entity.SysDictData
}
type DictDataEditRes struct{}
// 删除字典类型
type DictDataDeleteReq struct {
g.Meta `path:"/dict_data/delete" method:"post" tags:"字典" summary:"删除字典数据"`
Id interface{} `json:"id" v:"required#字典数据ID不能为空" dc:"字典数据ID"`
}
type DictDataDeleteRes struct{}
// 获取指定字典数据信息
type DictDataViewReq struct {
g.Meta `path:"/dict_data/view" method:"get" tags:"字典" summary:"获取指定字典数据信息"`
Id string `json:"id" v:"required#字典数据ID不能为空" dc:"字典数据ID"`
}
type DictDataViewRes struct {
*entity.SysDictData
}
// 获取字典数据列表
type DictDataListReq struct {
g.Meta `path:"/dict_data/list" method:"get" tags:"字典" summary:"获取字典数据列表"`
form.PageReq
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" dc:"字典类型"`
}
type DictDataListRes struct {
List []*entity.SysDictData `json:"list" dc:"数据列表"`
form.PageRes
}
// 获取指定字典类型的属性数据
type DictAttributeReq struct {
g.Meta `path:"/dict/attribute" method:"get" tags:"字典" summary:"获取指定字典类型的属性数据"`
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" dc:"字典类型"`
}
type DictAttributeRes []*entity.SysDictData
/************************ 字典类型 *****************/
// 修改/新增字典类型
type DictTypeExportReq struct {
g.Meta `path:"/dict_type/export" method:"get" tags:"字典" summary:"导出字典类型"`
form.PageReq
form.RangeDateReq
form.StatusReq
Name string `json:"name" dc:"字典名称"`
Type string `json:"type" dc:"字典类型"`
}
type DictTypeExportRes struct{}
// 刷新字典缓存
type DictTypeRefreshCacheReq struct {
g.Meta `path:"/dict_type/refresh_cache" method:"get" tags:"字典" summary:"刷新字典缓存"`
}
type DictTypeRefreshCacheRes struct{}
// 获取字典类型列表
type DictTypeListReq struct {
g.Meta `path:"/dict_type/list" method:"get" tags:"字典" summary:"获取字典类型列表"`
form.PageReq
form.RangeDateReq
form.StatusReq
Name string `json:"name" dc:"字典名称"`
Type string `json:"type" dc:"字典类型"`
}
type DictTypeListRes struct {
List []*entity.SysDictType `json:"list" dc:"数据列表"`
form.PageRes
}
// 修改/新增字典类型
type DictTypeEditReq struct {
g.Meta `path:"/dict_type/edit" method:"post" tags:"字典" summary:"修改/新增字典类型"`
entity.SysDictType
}
type DictTypeEditRes struct{}
// 删除字典类型
type DictTypeDeleteReq struct {
g.Meta `path:"/dict_type/delete" method:"post" tags:"字典" summary:"删除字典类型"`
Id interface{} `json:"id" v:"required#字典类型ID不能为空" dc:"字典类型ID"`
}
type DictTypeDeleteRes struct{}
// 获取指定字典类型信息
type DictTypeViewReq struct {
g.Meta `path:"/dict_type/view" method:"get" tags:"字典" summary:"获取指定字典类型信息"`
Id string `json:"id" v:"required#字典类型ID不能为空" dc:"字典类型ID"`
}
type DictTypeViewRes struct {
*entity.SysDictType
}
// 类型是否唯一
type DictTypeUniqueReq struct {
g.Meta `path:"/dict_type/unique" method:"get" tags:"字典" summary:"类型是否唯一"`
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" dc:"字典类型"`
Id int64 `json:"id" dc:"字典类型ID"`
}
type DictTypeUniqueRes struct {
IsUnique bool `json:"is_unique" dc:"是否唯一"`
}

View File

@ -1,53 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminForm
import (
"github.com/bufanyun/hotgo/app/form"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/gogf/gf/v2/frame/g"
)
// 清空日志
type LogClearReq struct {
g.Meta `path:"/log/clear" method:"post" tags:"日志" summary:"清空日志"`
}
type LogClearRes struct{}
// 导出
type LogExportReq struct {
g.Meta `path:"/log/export" method:"get" tags:"日志" summary:"导出日志"`
form.PageReq
form.RangeDateReq
Module string `json:"module" dc:"应用端口"`
MemberId int `json:"member_id" dc:"用户ID"`
TakeUpTime int `json:"take_up_time" dc:"请求耗时"`
Method string `json:"method" dc:"请求方式"`
Url string `json:"url" dc:"请求路径"`
Ip string `json:"ip" dc:"访问IP"`
ErrorCode string `json:"error_code" dc:"状态码"`
}
type LogExportRes struct{}
// 获取菜单列表
type LogListReq struct {
g.Meta `path:"/log/list" method:"get" tags:"日志" summary:"获取日志列表"`
form.PageReq
form.RangeDateReq
Module string `json:"module" dc:"应用端口"`
MemberId int `json:"member_id" dc:"用户ID"`
TakeUpTime int `json:"take_up_time" dc:"请求耗时"`
Method string `json:"method" dc:"请求方式"`
Url string `json:"url" dc:"请求路径"`
Ip string `json:"ip" dc:"访问IP"`
ErrorCode string `json:"error_code" dc:"状态码"`
}
type LogListRes struct {
List []*input.LogListModel `json:"list" dc:"数据列表"`
form.PageRes
}

View File

@ -1,41 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminForm
import (
"github.com/bufanyun/hotgo/app/model"
"github.com/gogf/gf/v2/frame/g"
)
// 注销登录
type LoginLogoutReq struct {
g.Meta `path:"/login/logout" method:"post" tags:"登录" summary:"注销登录"`
}
type LoginLogoutRes struct{}
// 获取登录验证码
type LoginCaptchaReq struct {
g.Meta `path:"/login/captcha" method:"get" tags:"登录" summary:"获取登录验证码"`
}
type LoginCaptchaRes struct {
Cid string `json:"cid" dc:"验证码ID"`
Base64 string `json:"base64" dc:"验证码"`
}
// 提交登录
type LoginReq struct {
g.Meta `path:"/login/sign" method:"post" tags:"登录" summary:"提交登录"`
Username string `json:"username" v:"required#用户名不能为空" dc:"用户名"`
Password string `json:"password" v:"required#密码不能为空" dc:"密码"`
Cid string `json:"cid" v:"required#验证码ID不能为空" dc:"验证码ID"`
Code string `json:"code" v:"required#验证码不能为空" dc:"验证码"`
Device string `json:"device" dc:"登录设备"`
}
type LoginRes struct {
model.Identity
Token string `json:"token" dc:"登录token"`
}

View File

@ -1,70 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminForm
import (
"github.com/bufanyun/hotgo/app/form"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/gogf/gf/v2/frame/g"
)
// 名称是否唯一
type NoticeNameUniqueReq struct {
g.Meta `path:"/notice/name_unique" method:"get" tags:"公告" summary:"公告名称是否唯一"`
Title string `json:"name" v:"required#公告名称不能为空" dc:"公告名称"`
Id int64 `json:"id" dc:"公告ID"`
}
type NoticeNameUniqueRes struct {
IsUnique bool `json:"is_unique" dc:"是否唯一"`
}
// 查询列表
type NoticeListReq struct {
g.Meta `path:"/notice/list" method:"get" tags:"公告" summary:"获取公告列表"`
form.PageReq
form.RangeDateReq
form.StatusReq
Name string `json:"name" dc:"公告名称"`
}
type NoticeListRes struct {
List []*input.AdminNoticeListModel `json:"list" dc:"数据列表"`
form.PageRes
}
// 获取指定信息
type NoticeViewReq struct {
g.Meta `path:"/notice/view" method:"get" tags:"公告" summary:"获取指定信息"`
Id string `json:"id" v:"required#公告ID不能为空" dc:"公告ID"`
}
type NoticeViewRes struct {
*input.AdminNoticeViewModel
}
// 修改/新增
type NoticeEditReq struct {
g.Meta `path:"/notice/edit" method:"post" tags:"公告" summary:"修改/新增公告"`
entity.AdminNotice
}
type NoticeEditRes struct{}
// 删除
type NoticeDeleteReq struct {
g.Meta `path:"/notice/delete" method:"post" tags:"公告" summary:"删除公告"`
Id interface{} `json:"id" v:"required#公告ID不能为空" dc:"公告ID"`
}
type NoticeDeleteRes struct{}
// 最大排序
type NoticeMaxSortReq struct {
g.Meta `path:"/notice/max_sort" method:"get" tags:"公告" summary:"公告最大排序"`
Id int64 `json:"id" dc:"公告ID"`
}
type NoticeMaxSortRes struct {
Sort int `json:"sort" dc:"排序"`
}

View File

@ -1,98 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminForm
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/bufanyun/hotgo/app/form"
"github.com/bufanyun/hotgo/app/form/input"
)
// 查询列表
type RoleMemberListReq struct {
g.Meta `path:"/role/member_list" method:"get" tags:"角色" summary:"获取角色下的会员列表"`
form.PageReq
form.RangeDateReq
form.StatusReq
Role int `json:"role" description:"角色ID"`
DeptId int `json:"dept_id" description:"部门ID"`
Mobile int `json:"mobile" description:"手机号"`
Username string `json:"username" description:"用户名"`
Realname string `json:"realname" description:"真实姓名"`
StartTime string `json:"start_time" description:"开始时间"`
EndTime string `json:"end_time" description:"结束时间"`
Name string `json:"name" description:"岗位名称"`
Code string `json:"code" description:"岗位编码"`
}
type RoleMemberListRes struct {
List []*input.AdminMemberListModel `json:"list" description:"数据列表"`
form.PageRes
}
// 查询列表
type RoleListReq struct {
g.Meta `path:"/role/list" method:"get" tags:"角色" summary:"获取角色列表"`
form.PageReq
form.RangeDateReq
form.StatusReq
DeptId int `json:"dept_id" description:"部门ID"`
Mobile int `json:"mobile" description:"手机号"`
Username string `json:"username" description:"用户名"`
Realname string `json:"realname" description:"真实姓名"`
StartTime string `json:"start_time" description:"开始时间"`
EndTime string `json:"end_time" description:"结束时间"`
Name string `json:"name" description:"岗位名称"`
Code string `json:"code" description:"岗位编码"`
}
type RoleListRes struct {
List []*input.AdminRoleListModel `json:"list" description:"数据列表"`
form.PageRes
}
// 动态路由
type RoleDynamicReq struct {
g.Meta `path:"/role/dynamic" method:"get" tags:"路由" summary:"获取动态路由" description:"获取登录用户动态路由"`
}
type RoleDynamicMeta struct {
Title string `json:"title" description:"菜单标题"`
Icon string `json:"icon" description:"菜单图标"`
NoCache bool `json:"noCache" description:"是否缓存"`
Remark string `json:"remark" description:"备注"`
}
type RoleDynamicBase struct {
Id int64 `json:"id" description:"菜单ID"`
Pid int64 `json:"pid" description:"父ID"`
Name string `json:"name" description:"菜单名称"`
Code string `json:"code" description:"菜单编码"`
Path string `json:"path" description:"路由地址"`
Hidden bool `json:"hidden" description:"是否隐藏"`
Redirect string `json:"redirect" description:"重定向"`
Component string `json:"component" description:"组件路径"`
AlwaysShow bool `json:"alwaysShow" description:"暂时不知道干啥"`
IsFrame string `json:"isFrame" description:"是否为外链0是 1否"`
Meta *RoleDynamicMeta `json:"meta" description:"配置数据集"`
}
type RoleDynamicMenu struct {
RoleDynamicBase
Children []*RoleDynamicBase `json:"children" description:"子菜单"`
}
type RoleDynamicRes []*RoleDynamicMenu
type RoleMenuEditReq struct {
g.Meta `path:"/role/edit" method:"post" tags:"角色" summary:"编辑角色菜单权限"`
RoleId int64 `json:"id"`
MenuIds []int64 `json:"menuIds"`
}
type RoleMenuEditRes struct{}

View File

@ -1,34 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package apiForm
import (
"github.com/bufanyun/hotgo/app/com"
"github.com/gogf/gf/v2/frame/g"
)
// 获取lang信息
type BaseLangReq struct {
g.Meta `path:"/base/lang" method:"get" tags:"基础接口" summary:"获取lang信息"`
L string `json:"l" v:"required#语言不能为空" dc:"语言"`
}
type BaseLangRes struct {
}
// 获取登录验证码
type IpLocationReq struct {
g.Meta `path:"/base/ip_location" method:"get" tags:"基础接口" summary:"获取IP归属地信息"`
Ip string `json:"ip" v:"required#ip不能为空" dc:"ipv4地址"`
}
type IpLocationRes struct {
com.IpLocationData
}
type ExportReq struct {
g.Meta `path:"/base/export" method:"get" tags:"字典接口" summary:"导出字典类型"`
}
type ExportRes struct{}

View File

@ -1,19 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package apiForm
import (
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/gogf/gf/v2/frame/g"
)
// 获取指定字典类型的属性数据
type DictAttributeReq struct {
g.Meta `path:"/dict/attribute" method:"get" tags:"字典接口" summary:"获取指定字典类型的属性数据"`
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" dc:"字典类型"`
}
type DictAttributeRes []*entity.SysDictData

View File

@ -1,53 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package apiForm
import (
"github.com/bufanyun/hotgo/app/form"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/gogf/gf/v2/frame/g"
)
// 清空日志
type LogClearReq struct {
g.Meta `path:"/log/clear" method:"post" tags:"日志接口" summary:"清空日志"`
}
type LogClearRes struct{}
// 导出
type LogExportReq struct {
g.Meta `path:"/log/export" method:"get" tags:"日志接口" summary:"导出日志"`
form.PageReq
form.RangeDateReq
Module string `json:"module" dc:"应用端口"`
MemberId int `json:"member_id" dc:"用户ID"`
TakeUpTime int `json:"take_up_time" dc:"请求耗时"`
Method string `json:"method" dc:"请求方式"`
Url string `json:"url" dc:"请求路径"`
Ip string `json:"ip" dc:"访问IP"`
ErrorCode string `json:"error_code" dc:"状态码"`
}
type LogExportRes struct{}
// 获取菜单列表
type LogListReq struct {
g.Meta `path:"/log/list" method:"get" tags:"日志接口" summary:"获取日志列表"`
form.PageReq
form.RangeDateReq
Module string `json:"module" dc:"应用端口"`
MemberId int `json:"member_id" dc:"用户ID"`
TakeUpTime int `json:"take_up_time" dc:"请求耗时"`
Method string `json:"method" dc:"请求方式"`
Url string `json:"url" dc:"请求路径"`
Ip string `json:"ip" dc:"访问IP"`
ErrorCode string `json:"error_code" dc:"状态码"`
}
type LogListRes struct {
List []*input.LogListModel `json:"list" dc:"数据列表"`
form.PageRes
}

View File

@ -1,43 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package apiForm
import (
"github.com/bufanyun/hotgo/app/model"
"github.com/gogf/gf/v2/frame/g"
)
// 注销登录
type LoginLogoutReq struct {
g.Meta `path:"/login/logout" method:"get" tags:"登录接口" summary:"注销登录"`
}
type LoginLogoutRes struct{}
// 登录效验
type LoginCheckReq struct {
g.Meta `path:"/login/check" method:"get" tags:"登录接口" summary:"登录效验"`
}
type LoginCheckRes struct {
IsValidCodeLogin bool `json:"isValidCodeLogin" dc:"是否验证码"`
Message string `json:"message" dc:"消息"`
Result string `json:"result" dc:"响应"`
// Sessionid string `json:"sessionid" dc:"sessionid"`
}
// 提交登录
type LoginReq struct {
g.Meta `path:"/login/sign" method:"post" tags:"登录接口" summary:"提交登录"`
Username string `json:"username" v:"required#用户名不能为空" dc:"用户名"`
Password string `json:"password" v:"required#密码不能为空" dc:"密码"`
Cid string `json:"cid" v:"required#验证码ID不能为空" dc:"验证码ID"`
Code string `json:"code" v:"required#验证码不能为空" dc:"验证码"`
Device string `json:"device" dc:"登录设备"`
}
type LoginRes struct {
model.Identity
Token string `json:"token" dc:"登录token"`
}

View File

@ -1,26 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package apiForm
import (
"github.com/bufanyun/hotgo/app/form/input"
"github.com/gogf/gf/v2/frame/g"
)
// 获取登录用户的基本信息
type MemberProfileReq struct {
g.Meta `path:"/member/profile" method:"get" tags:"会员接口" summary:"获取登录用户的基本信息"`
}
type MemberProfileRes struct {
PostGroup string `json:"postGroup" dc:"岗位名称"`
RoleGroup string `json:"roleGroup" dc:"角色名称"`
User *input.AdminMemberViewModel `json:"user" dc:"用户基本信息"`
SysDept *input.AdminDeptViewModel `json:"sysDept" dc:"部门信息"`
SysRoles []*input.AdminRoleListModel `json:"sysRoles" dc:"角色列表"`
PostIds int64 `json:"postIds" dc:"当前岗位"`
RoleIds int64 `json:"roleIds" dc:"当前角色"`
}

View File

@ -1,28 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package form
// 分页
type PageReq struct {
Page int `json:"page" example:"10" d:"1" v:"min:1#页码最小值不能低于1" dc:"当前页码"`
Limit int `json:"limit" example:"1" d:"10" v:"min:1|max:100#|每页数量最小值不能低于1|最大值不能大于100" dc:"每页数量"`
}
type PageRes struct {
PageReq
TotalCount int `json:"total_count" example:"0" dc:"全部数据量"`
}
// 时间查询
type RangeDateReq struct {
StartTime string `json:"start_time" v:"date#开始日期格式不正确" dc:"开始日期"`
EndTime string `json:"end_time" v:"date#结束日期格式不正确" dc:"结束日期"`
}
// 状态查询
type StatusReq struct {
Status int `json:"status" v:"in:0,1,2,3#状态可选范围0~3" dc:"状态"`
}

View File

@ -1,75 +0,0 @@
package input
import "github.com/bufanyun/hotgo/app/model/entity"
// 名称是否唯一
type AdminDeptNameUniqueInp struct {
Name string
Id int64
}
type AdminDeptNameUniqueModel struct {
IsUnique bool
}
// 最大排序
type AdminDeptMaxSortInp struct {
Id int64
}
type AdminDeptMaxSortModel struct {
Sort int
}
// 修改/新增字典数据
type AdminDeptEditInp struct {
entity.AdminDept
}
type AdminDeptEditModel struct{}
// 删除字典类型
type AdminDeptDeleteInp struct {
Id interface{}
}
type AdminDeptDeleteModel struct{}
// 获取信息
type AdminDeptViewInp struct {
Id int64
}
type AdminDeptViewModel struct {
entity.AdminDept
}
// 获取列表
type AdminDeptListInp struct {
Name string
}
// 
type AdminDeptTreeDept struct {
entity.AdminDept
Children []*AdminDeptTreeDept `json:"children"`
}
type AdminDeptListModel AdminDeptTreeDept
// 获取列表树
type AdminDeptListTreeInp struct {
Name string
}
// 
type AdminDeptListTreeDept struct {
Id int64 `json:"id" `
Key int64 `json:"key" `
Pid int64 `json:"pid" `
Label string `json:"label"`
Title string `json:"title"`
Name string `json:"name"`
Type string `json:"type"`
Children []*AdminDeptListTreeDept `json:"children"`
}
type AdminDeptListTreeModel AdminDeptListTreeDept

View File

@ -1,171 +0,0 @@
package input
import (
"github.com/bufanyun/hotgo/app/model"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/gogf/gf/v2/os/gtime"
)
// 更新会员资料
type AdminMemberUpdateProfileInp struct {
Mobile int
Email string
Realname string
}
//  获取指定会员资料
type AdminMemberProfileInp struct {
Id int64
}
type AdminMemberProfileModel struct {
PostGroup string `json:"postGroup" description:"岗位名称"`
RoleGroup string `json:"roleGroup" description:"角色名称"`
User *AdminMemberViewModel `json:"user" description:"用户基本信息"`
SysDept *AdminDeptViewModel `json:"sysDept" description:"部门信息"`
SysRoles []*AdminRoleListModel `json:"sysRoles" description:"角色列表"`
PostIds int64 `json:"postIds" description:"当前岗位"`
RoleIds int64 `json:"roleIds" description:"当前角色"`
}
// 更新会员资料
type MemberUpdateProfileInp struct {
Mobile int
Email string
Realname string
}
// 修改登录密码
type AdminMemberUpdatePwdInp struct {
Id int64
OldPassword string
NewPassword string
}
//  重置密码
type AdminMemberResetPwdInp struct {
Password string
Id int64
}
// 邮箱是否唯一
type AdminMemberEmailUniqueInp struct {
Email string
Id int64
}
type AdminMemberEmailUniqueModel struct {
IsUnique bool
}
// 手机号是否唯一
type AdminMemberMobileUniqueInp struct {
Mobile string
Id int64
}
type AdminMemberMobileUniqueModel struct {
IsUnique bool
}
// 名称是否唯一
type AdminMemberNameUniqueInp struct {
Username string
Id int64
}
type AdminMemberNameUniqueModel struct {
IsUnique bool
}
// 最大排序
type AdminMemberMaxSortInp struct {
Id int64
}
type AdminMemberMaxSortModel struct {
Sort int
}
// 修改/新增字典数据
type AdminMemberEditInp struct {
Id int64 `json:"id" description:""`
PostIds []int64 `json:"postIds" v:"required#岗位不能为空" description:"岗位ID"`
DeptId int64 `json:"dept_id" v:"required#部门不能为空" description:"部门ID"`
Username string `json:"username" v:"required#账号不能为空" description:"帐号"`
Password string `json:"password" description:"密码"`
Realname string `json:"realname" description:"真实姓名"`
Avatar string `json:"avatar" description:"头像"`
Sex string `json:"sex" description:"性别[0:未知;1:男;2:女]"`
Qq string `json:"qq" description:"qq"`
Email string `json:"email" description:"邮箱"`
Birthday *gtime.Time `json:"birthday" description:"生日"`
ProvinceId int `json:"province_id" description:"省"`
CityId int `json:"city_id" description:"城市"`
AreaId int `json:"area_id" description:"地区"`
Address string `json:"address" description:"默认地址"`
Mobile string `json:"mobile" description:"手机号码"`
HomePhone string `json:"home_phone" description:"家庭号码"`
DingtalkRobotToken string `json:"dingtalk_robot_token" description:"钉钉机器人token"`
Role int `json:"role" v:"required#角色不能为空" description:"权限"`
Remark string `json:"remark" description:"备注"`
Status string `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"修改时间"`
}
type AdminMemberAddInp struct {
AdminMemberEditInp
PasswordHash string `json:"password_hash" description:"密码hash"`
Salt string `json:"salt" description:"密码盐"`
}
type AdminMemberEditModel struct{}
// 删除字典类型
type AdminMemberDeleteInp struct {
Id interface{}
}
type AdminMemberDeleteModel struct{}
// 获取信息
type AdminMemberViewInp struct {
Id int64
}
type AdminMemberViewModel struct {
entity.AdminMember
}
// 获取列表
type AdminMemberListInp struct {
Page int
Limit int
Name string
Code string
DeptId int
Mobile int
Username string
Realname string
StartTime string
EndTime string
Status int
}
type AdminMemberListModel struct {
entity.AdminMember
DeptName string `json:"dept_name"`
RoleName string `json:"role_name"`
}
// 登录
type AdminMemberLoginSignInp struct {
Username string
Password string
Device string
Cid string
Code string
}
type AdminMemberLoginSignModel struct {
model.Identity
Token string `json:"token" v:"" description:"登录token"`
}

View File

@ -1,64 +0,0 @@
package input
import "github.com/bufanyun/hotgo/app/model/entity"
// 名称是否唯一
type AdminNoticeNameUniqueInp struct {
Title string
Id int64
}
type AdminNoticeNameUniqueModel struct {
IsUnique bool
}
// 最大排序
type AdminNoticeMaxSortInp struct {
Id int64
}
type AdminNoticeMaxSortModel struct {
Sort int
}
// 修改/新增字典数据
type AdminNoticeEditInp struct {
entity.AdminNotice
}
type AdminNoticeEditModel struct{}
// 删除字典类型
type AdminNoticeDeleteInp struct {
Id interface{}
}
type AdminNoticeDeleteModel struct{}
// 获取信息
type AdminNoticeViewInp struct {
Id string
}
type AdminNoticeViewModel struct {
entity.AdminNotice
}
// 获取列表
type AdminNoticeListInp struct {
Page int
Limit int
Name string
Code string
DeptId int
Mobile int
Username string
Realname string
StartTime string
EndTime string
Status int
}
type AdminNoticeListModel struct {
entity.AdminNotice
DeptName string `json:"dept_name"`
RoleName string `json:"role_name"`
}

View File

@ -1,68 +0,0 @@
package input
import (
"github.com/bufanyun/hotgo/app/model/entity"
)
// 获取列表
type AdminPostListInp struct {
Page int
Limit int
Name string
Code string
Status int
}
type AdminPostListModel struct {
entity.AdminPost
}
// 获取信息
type AdminPostViewInp struct {
Id string
}
type AdminPostViewModel struct {
entity.AdminPost
}
// 编码是否唯一
type AdminPostCodeUniqueInp struct {
Code string
Id int64
}
type AdminPostCodeUniqueModel struct {
IsUnique bool
}
// 名称是否唯一
type AdminPostNameUniqueInp struct {
Name string
Id int64
}
type AdminPostNameUniqueModel struct {
IsUnique bool
}
// 最大排序
type AdminPostMaxSortInp struct {
Id int64
}
type AdminPostMaxSortModel struct {
Sort int
}
// 修改/新增字典数据
type AdminPostEditInp struct {
entity.AdminPost
}
type AdminPostEditModel struct{}
// 删除字典类型
type AdminPostDeleteInp struct {
Id interface{}
}
type AdminPostDeleteModel struct{}

View File

@ -1,72 +0,0 @@
package input
import "github.com/bufanyun/hotgo/app/model/entity"
// 获取指定配置键的值
type SysConfigGetValueInp struct {
Key string
}
type SysConfigGetValueModel struct {
Value string
}
// 名称是否唯一
type SysConfigNameUniqueInp struct {
Name string
Id int64
}
type SysConfigNameUniqueModel struct {
IsUnique bool
}
// 最大排序
type SysConfigMaxSortInp struct {
Id int64
}
type SysConfigMaxSortModel struct {
Sort int
}
// 修改/新增字典数据
type SysConfigEditInp struct {
entity.SysConfig
}
type SysConfigEditModel struct{}
// 删除字典类型
type SysConfigDeleteInp struct {
Id interface{}
}
type SysConfigDeleteModel struct{}
// 获取信息
type SysConfigViewInp struct {
Id string
}
type SysConfigViewModel struct {
entity.SysConfig
}
// 获取列表
type SysConfigListInp struct {
Page int
Limit int
Name string
Code string
DeptId int
Mobile int
Username string
Realname string
StartTime string
EndTime string
Status int
}
type SysConfigListModel struct {
entity.SysConfig
DeptName string `json:"dept_name"`
RoleName string `json:"role_name"`
}

View File

@ -1,26 +0,0 @@
package input
import (
"github.com/bufanyun/hotgo/app/model/entity"
)
// 获取菜单列表
type LogListInp struct {
Page int
Limit int
Module string
MemberId int
TakeUpTime int
Method string
Url string
Ip string
ErrorCode string
StartTime string
EndTime string
}
type LogListModel struct {
entity.SysLog
MemberName string `json:"member_name"`
Region string `json:"region"`
}

View File

@ -1,52 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package hook
import (
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/service/sysService"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gtime"
)
type (
// sHook is service struct of module Hook.
sHook struct{}
)
var (
// insHook is the instance of service Hook.
insHook = sHook{}
)
// Hook returns the interface of Hook service.
func Instance() *sHook {
return &insHook
}
//
//  @Title  全局日志
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//
func (s *sHook) GlobalLog(r *ghttp.Request) {
var (
ctx = r.Context()
)
// 没有上下文的请求不记录doc、favicon.ico等非服务类业务
modelCtx := com.Context.Get(ctx)
if modelCtx == nil {
return
}
// 计算运行耗时
com.Context.SetTakeUpTime(ctx, gtime.TimestampMilli()-r.EnterTime)
go sysService.Log.AutoLog(ctx)
}

View File

@ -1,20 +0,0 @@
//
// @Package  interfaces
// @Description 
// @Author  Ms <133814250@qq.com>
//
package interfaces
//
//  QueueProducer
//  @Description 
//
type QueueProducer interface {
//
//  @Title 
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Return  string
//
Push() string
}

View File

@ -1,127 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package middleware
import (
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model"
"github.com/bufanyun/hotgo/app/utils"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/errors/gcode"
"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"
)
//
//  @Title  后台中间件
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//
func (s *sMiddleware) AdminAuth(r *ghttp.Request) {
var (
ctx = r.Context()
user = new(model.Identity)
authorization = com.Jwt.GetAuthorization(r)
)
// TODO 替换掉模块前缀
routerPrefix, _ := g.Cfg().Get(ctx, "router.admin.prefix", "/admin")
path := gstr.Replace(r.URL.Path, routerPrefix.String(), "", 1)
/// TODO 不需要验证登录的路由地址
if utils.Auth.IsExceptLogin(ctx, path) {
r.Middleware.Next()
return
}
if authorization == "" {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "请先登录!")
return
}
// TODO 获取jwtToken
jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization)
jwtSign, _ := g.Cfg().Get(ctx, "jwt.sign", "hotgo")
data, ParseErr := com.Jwt.ParseToken(authorization, jwtSign.Bytes())
if ParseErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token不正确或已过期", ParseErr.Error())
}
parseErr := gconv.Struct(data, &user)
if parseErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "登录信息解析异常,请重新登录!", parseErr.Error())
}
// TODO 判断token跟redis的缓存的token是否一样
cache := com.Cache.New()
isContains, containsErr := cache.Contains(ctx, jwtToken)
if containsErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token无效", containsErr.Error())
return
}
if !isContains {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期")
return
}
// TODO 是否开启多端登录
if multiPort, _ := g.Cfg().Get(ctx, "jwt.multiPort", true); !multiPort.Bool() {
key := consts.RedisJwtUserBind + consts.AppAdmin + ":" + gconv.String(user.Id)
originJwtToken, originErr := cache.Get(ctx, key)
if originErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "信息异常,请重新登录!", originErr.Error())
return
}
if originJwtToken == nil || originJwtToken.IsEmpty() {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期")
return
}
if jwtToken != originJwtToken.String() {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "账号已在其他地方登录!")
return
}
}
// TODO 保存到上下文
customCtx := &model.Context{}
if user != nil {
customCtx.User = &model.Identity{
Id: user.Id,
Username: user.Username,
Realname: user.Realname,
Avatar: user.Avatar,
Email: user.Email,
Mobile: user.Mobile,
VisitCount: user.VisitCount,
LastTime: user.LastTime,
LastIp: user.LastIp,
Role: user.Role,
Exp: user.Exp,
Expires: user.Expires,
App: user.App,
}
}
com.Context.SetUser(ctx, customCtx.User)
com.Context.SetModule(ctx, consts.AppAdmin)
//// TODO 验证路由访问权限
//verify := adminService.Role.Verify(ctx, customCtx.User.Id, path)
//if !verify {
// com.Response.JsonExit(r, gcode.CodeSecurityReason.Code(), "你没有访问权限!")
// return
//}
r.Middleware.Next()
}

View File

@ -1,127 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package middleware
import (
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model"
"github.com/bufanyun/hotgo/app/utils"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/errors/gcode"
"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"
)
//
//  @Title  接口中间件
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//
func (s *sMiddleware) ApiAuth(r *ghttp.Request) {
var (
ctx = r.Context()
user = new(model.Identity)
authorization = com.Jwt.GetAuthorization(r)
)
// TODO 替换掉模块前缀
routerPrefix, _ := g.Cfg().Get(ctx, "router.api.prefix", "/api")
path := gstr.Replace(r.URL.Path, routerPrefix.String(), "", 1)
/// TODO 不需要验证登录的路由地址
if utils.Auth.IsExceptLogin(ctx, path) {
r.Middleware.Next()
return
}
if authorization == "" {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "请先登录!")
return
}
// TODO 获取jwtToken
jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization)
jwtSign, _ := g.Cfg().Get(ctx, "jwt.sign", "hotgo")
data, ParseErr := com.Jwt.ParseToken(authorization, jwtSign.Bytes())
if ParseErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token不正确或已过期", ParseErr.Error())
}
parseErr := gconv.Struct(data, &user)
if parseErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "登录信息解析异常,请重新登录!", parseErr.Error())
}
// TODO 判断token跟redis的缓存的token是否一样
cache := com.Cache.New()
isContains, containsErr := cache.Contains(ctx, jwtToken)
if containsErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token无效", containsErr.Error())
return
}
if !isContains {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期")
return
}
// TODO 是否开启多端登录
if multiPort, _ := g.Cfg().Get(ctx, "jwt.multiPort", true); !multiPort.Bool() {
key := consts.RedisJwtUserBind + consts.AppApi + ":" + gconv.String(user.Id)
originJwtToken, originErr := cache.Get(ctx, key)
if originErr != nil {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "信息异常,请重新登录!", originErr.Error())
return
}
if originJwtToken == nil || originJwtToken.IsEmpty() {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "token已过期")
return
}
if jwtToken != originJwtToken.String() {
com.Response.JsonExit(r, gcode.CodeNotAuthorized.Code(), "账号已在其他地方登录!")
return
}
}
// TODO 保存到上下文
customCtx := &model.Context{}
if user != nil {
customCtx.User = &model.Identity{
Id: user.Id,
Username: user.Username,
Realname: user.Realname,
Avatar: user.Avatar,
Email: user.Email,
Mobile: user.Mobile,
VisitCount: user.VisitCount,
LastTime: user.LastTime,
LastIp: user.LastIp,
Role: user.Role,
Exp: user.Exp,
Expires: user.Expires,
App: user.App,
}
}
com.Context.SetUser(ctx, customCtx.User)
com.Context.SetModule(ctx, consts.AppApi)
//// TODO 验证路由访问权限
//verify := adminService.Role.Verify(ctx, customCtx.User.Id, path)
//if !verify {
// com.Response.JsonExit(r, gcode.CodeSecurityReason.Code(), "你没有访问权限!")
// return
//}
r.Middleware.Next()
}

View File

@ -1,64 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package middleware
import (
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/model"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/util/grand"
"github.com/gogf/gf/v2/util/guid"
"go.opentelemetry.io/otel/trace"
)
type (
// sMiddleware is service struct of module Middleware.
sMiddleware struct{}
)
var (
// insMiddleware is the instance of service Middleware.
insMiddleware = sMiddleware{}
)
// Middleware returns the interface of Middleware service.
func Instance() *sMiddleware {
return &insMiddleware
}
//
//  @Title  初始化请求上下文
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   r
//
func (s *sMiddleware) Ctx(r *ghttp.Request) {
spanCtx := trace.SpanContextFromContext(r.Context())
reqId := guid.S(grand.B(64))
if traceId := spanCtx.TraceID(); traceId.IsValid() {
reqId = traceId.String()
}
customCtx := &model.Context{
Data: make(g.Map),
Request: r,
ReqId: reqId,
}
com.Context.Init(r, customCtx)
r.Middleware.Next()
}
// CORS allows Cross-origin resource sharing.
func (s *sMiddleware) CORS(r *ghttp.Request) {
r.Response.CORSDefault()
r.Middleware.Next()
}

View File

@ -1,26 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// AdminDept is the golang structure for table admin_dept.
type AdminDept struct {
Id int64 `json:"id" description:"部门id"`
Pid int64 `json:"pid" description:"父部门id"`
Ancestors string `json:"ancestors" description:"祖级列表"`
Name string `json:"name" description:"部门名称"`
Code string `json:"code" description:"部门编码"`
Type string `json:"type" description:"部门类型"`
Leader string `json:"leader" description:"负责人"`
Phone string `json:"phone" description:"联系电话"`
Email string `json:"email" description:"邮箱"`
Sort int `json:"sort" description:"排序"`
Status string `json:"status" description:"部门状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,42 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// AdminMember is the golang structure for table admin_member.
type AdminMember struct {
Id int64 `json:"id" description:""`
DeptId int64 `json:"dept_id" description:"部门ID"`
Username string `json:"username" description:"帐号"`
PasswordHash string `json:"password_hash" description:"密码"`
Salt string `json:"salt" description:"密码盐"`
AuthKey string `json:"auth_key" description:"授权令牌"`
PasswordResetToken string `json:"password_reset_token" description:"密码重置令牌"`
Type string `json:"type" description:"1:普通管理员;10超级管理员"`
Realname string `json:"realname" description:"真实姓名"`
Avatar string `json:"avatar" description:"头像"`
Sex string `json:"sex" description:"性别[0:未知;1:男;2:女]"`
Qq string `json:"qq" description:"qq"`
Email string `json:"email" description:"邮箱"`
Birthday *gtime.Time `json:"birthday" description:"生日"`
ProvinceId int `json:"province_id" description:"省"`
CityId int `json:"city_id" description:"城市"`
AreaId int `json:"area_id" description:"地区"`
Address string `json:"address" description:"默认地址"`
Mobile string `json:"mobile" description:"手机号码"`
HomePhone string `json:"home_phone" description:"家庭号码"`
DingtalkRobotToken string `json:"dingtalk_robot_token" description:"钉钉机器人token"`
VisitCount uint `json:"visit_count" description:"访问次数"`
LastTime int `json:"last_time" description:"最后一次登录时间"`
LastIp string `json:"last_ip" description:"最后一次登录ip"`
Role int64 `json:"role" description:"权限"`
Remark string `json:"remark" description:"备注"`
Status string `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"修改时间"`
}

View File

@ -1,33 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// AdminMenu is the golang structure for table admin_menu.
type AdminMenu struct {
Id int64 `json:"id" description:"菜单ID"`
Pid int64 `json:"pid" description:"父菜单ID"`
Name string `json:"name" description:"菜单名称"`
Code string `json:"code" description:"菜单编码"`
Icon string `json:"icon" description:"菜单图标"`
Type string `json:"type" description:"菜单类型M目录 C菜单 F按钮"`
Perms string `json:"perms" description:"权限标识"`
Path string `json:"path" description:"路由地址"`
Component string `json:"component" description:"组件路径"`
Query string `json:"query" description:"路由参数"`
IsFrame string `json:"is_frame" description:"是否内嵌"`
IsCache string `json:"is_cache" description:"是否不缓存"`
IsVisible string `json:"is_visible" description:"是否隐藏"`
Remark string `json:"remark" description:"备注"`
Level int `json:"level" description:"级别"`
Tree string `json:"tree" description:"树"`
Sort int `json:"sort" description:"排序"`
Status string `json:"status" description:"菜单状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,32 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// AdminMenuOld is the golang structure for table admin_menu_old.
type AdminMenuOld struct {
Id int64 `json:"id" description:"菜单ID"`
Pid int64 `json:"pid" description:"父菜单ID"`
Name string `json:"name" description:"菜单名称"`
Icon string `json:"icon" description:"菜单图标"`
Type string `json:"type" description:"菜单类型M目录 C菜单 F按钮"`
Perms string `json:"perms" description:"权限标识"`
Path string `json:"path" description:"路由地址"`
Component string `json:"component" description:"组件路径"`
Query string `json:"query" description:"路由参数"`
IsFrame int `json:"is_frame" description:"是否为外链0是 1否"`
IsCache int `json:"is_cache" description:"是否缓存0缓存 1不缓存"`
IsVisible int `json:"is_visible" description:"菜单状态0显示 1隐藏"`
Remark string `json:"remark" description:"备注"`
Level int `json:"level" description:"级别"`
Tree string `json:"tree" description:"树"`
Sort int `json:"sort" description:"排序"`
Status int `json:"status" description:"菜单状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,21 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// AdminNotice is the golang structure for table admin_notice.
type AdminNotice struct {
Id int64 `json:"id" description:"公告ID"`
Title string `json:"title" description:"公告标题"`
Type string `json:"type" description:"公告类型1通知 2公告"`
Content string `json:"content" description:"公告内容"`
Remark string `json:"remark" description:"备注"`
Status string `json:"status" description:"公告状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,21 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// AdminPost is the golang structure for table admin_post.
type AdminPost struct {
Id int64 `json:"id" description:"岗位ID"`
Code string `json:"code" description:"岗位编码"`
Name string `json:"name" description:"岗位名称"`
Remark string `json:"remark" description:"备注"`
Sort int `json:"sort" description:"显示顺序"`
Status string `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,24 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// AdminRole is the golang structure for table admin_role.
type AdminRole struct {
Id int64 `json:"id" description:"角色ID"`
Name string `json:"name" description:"角色名称"`
Key string `json:"key" description:"角色权限字符串"`
DataScope int `json:"data_scope" description:"数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限"`
MenuCheckStrictly int `json:"menu_check_strictly" description:"菜单树选择项是否关联显示"`
DeptCheckStrictly int `json:"dept_check_strictly" description:"部门树选择项是否关联显示"`
Remark string `json:"remark" description:"备注"`
Sort int `json:"sort" description:"排序"`
Status string `json:"status" description:"角色状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,22 +0,0 @@
// =================================================================================
// 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 {
Id int64 `json:"id" description:"配置ID"`
Name string `json:"name" description:"参数名称"`
Key string `json:"key" description:"参数键名"`
Value string `json:"value" description:"参数键值"`
IsDefault string `json:"is_default" description:"是否默认"`
Status string `json:"status" description:"状态"`
Remark string `json:"remark" description:"备注"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,24 +0,0 @@
// =================================================================================
// 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 {
Id int64 `json:"id" description:"字典编码"`
Label string `json:"label" description:"字典标签"`
Value string `json:"value" description:"字典键值"`
Type string `json:"type" description:"字典类型"`
ListClass string `json:"list_class" description:"表格回显样式"`
IsDefault string `json:"is_default" description:"是否默认"`
Sort int `json:"sort" description:"字典排序"`
Remark string `json:"remark" description:"备注"`
Status string `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,21 +0,0 @@
// =================================================================================
// 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 {
Id int64 `json:"id" description:"字典主键"`
Name string `json:"name" description:"字典名称"`
Type string `json:"type" description:"字典类型"`
Sort int `json:"sort" description:"排序"`
Remark string `json:"remark" description:"备注"`
Status string `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"更新时间"`
}

View File

@ -1,36 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// SysLog is the golang structure for table sys_log.
type SysLog struct {
Id int64 `json:"id" description:""`
AppId string `json:"app_id" description:"应用id"`
MerchantId uint `json:"merchant_id" description:"商户id"`
MemberId int `json:"member_id" description:"用户id"`
Method string `json:"method" description:"提交类型"`
Module string `json:"module" description:"模块"`
Url string `json:"url" description:"提交url"`
GetData string `json:"get_data" description:"get数据"`
PostData string `json:"post_data" description:"post数据"`
HeaderData string `json:"header_data" description:"header数据"`
Ip string `json:"ip" description:"ip地址"`
ProvinceId int `json:"province_id" description:"省编码"`
CityId int `json:"city_id" description:"市编码"`
ErrorCode int `json:"error_code" description:"报错code"`
ErrorMsg string `json:"error_msg" description:"报错信息"`
ErrorData string `json:"error_data" description:"报错日志"`
ReqId string `json:"req_id" description:"对外id"`
Timestamp int `json:"timestamp" description:"响应时间"`
UserAgent string `json:"user_agent" description:"UA信息"`
TakeUpTime int64 `json:"take_up_time" description:"请求耗时"`
Status string `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updated_at" description:"修改时间"`
}

View File

@ -1,21 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// SysProvinces is the golang structure for table sys_provinces.
type SysProvinces struct {
Id int `json:"id" description:"ID"`
Title string `json:"title" description:"栏目名"`
Pid int `json:"pid" description:"父栏目"`
ShortTitle string `json:"short_title" description:"缩写"`
Areacode int `json:"areacode" description:"区域编码"`
Zipcode int `json:"zipcode" description:"邮政编码"`
Pinyin string `json:"pinyin" description:"拼音"`
Lng string `json:"lng" description:"经度"`
Lat string `json:"lat" description:"纬度"`
Level int `json:"level" description:"级别"`
Tree string `json:"tree" description:""`
Sort uint `json:"sort" description:"排序"`
}

View File

@ -1,17 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package model
// HTTP响应
type Response struct {
Code int `json:"code" example:"0" description:"状态码"`
Message string `json:"message" example:"操作成功" description:"提示消息"`
Data interface{} `json:"data" description:"数据集"`
Error interface{} `json:"error" description:"错误信息"`
Timestamp int64 `json:"timestamp" example:"1640966400" description:"服务器时间戳"`
ReqId string `json:"req_id" v:"0" example:"d0bb93048bc5c9164cdee845dcb7f820" description:"唯一请求ID"`
}

View File

@ -1,358 +0,0 @@
package adminService
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
var Dept = dept{}
type dept struct{}
//
//  @Title  菜单名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *dept) NameUnique(ctx context.Context, in input.AdminDeptNameUniqueInp) (*input.AdminDeptNameUniqueModel, error) {
var res input.AdminDeptNameUniqueModel
isUnique, err := dao.AdminDept.IsUniqueName(ctx, in.Id, in.Name)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.IsUnique = isUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *dept) Delete(ctx context.Context, in input.AdminDeptDeleteInp) error {
exist, err := dao.AdminRoleDept.Ctx(ctx).Where("dept_id", in.Id).One()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !exist.IsEmpty() {
return gerror.New("请先解除该部门下所有已关联用户关联关系!")
}
_, err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *dept) Edit(ctx context.Context, in input.AdminDeptEditInp) (err error) {
if in.Name == "" {
err = gerror.New("名称不能为空")
return err
}
uniqueName, err := dao.AdminDept.IsUniqueName(ctx, in.Id, in.Name)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueName {
err = gerror.New("名称已存在")
return err
}
// 修改
in.UpdatedAt = gtime.Now()
if in.Id > 0 {
_, err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Data(in).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
// 新增
in.CreatedAt = gtime.Now()
_, err = dao.AdminDept.Ctx(ctx).Data(in).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataMaxSortRes
//  @Return  error
//
func (service *dept) MaxSort(ctx context.Context, in input.AdminDeptMaxSortInp) (*input.AdminDeptMaxSortModel, error) {
var res input.AdminDeptMaxSortModel
if in.Id > 0 {
if err := dao.AdminDept.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
}
res.Sort = res.Sort + 10
return &res, nil
}
//
//  @Title  获取指定字典类型信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeViewRes
//  @Return  error
//
func (service *dept) View(ctx context.Context, in input.AdminDeptViewInp) (res *input.AdminDeptViewModel, err error) {
if err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return res, nil
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *dept) List(ctx context.Context, in input.AdminDeptListInp) (list []*input.AdminDeptListModel, err error) {
mod := dao.AdminDept.Ctx(ctx)
var (
dataList []*entity.AdminDept
models []*DeptTree
//searchResult []*entity.AdminDept
//id int64
//ids []int64
)
// 部门名称
if in.Name != "" {
//err = dao.AdminDept.Ctx(ctx).WhereLike("name", "%"+in.Name+"%").Scan(&searchResult)
//if err != nil {
// err = gerror.Wrap(err, consts.ErrorORM)
// return nil, err
//}
//for i := 0; i < len(searchResult); i++ {
// id, err = dao.AdminDept.TopPid(ctx, searchResult[i])
// ids = append(ids, id)
//}
//
//if len(ids) == 0 {
// return nil, nil
//}
//mod = mod.Where("id", ids)
}
err = mod.Order("id desc").Scan(&dataList)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, err
}
_ = gconv.Structs(dataList, &models)
childIds := service.getDeptChildIds(ctx, models, 0)
_ = gconv.Structs(childIds, &list)
return list, nil
}
type DeptTree struct {
entity.AdminDept
Children []*DeptTree `json:"children"`
}
//
//  @Title  将列表转为父子关系列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   lists
//  @Param   pid
//  @Return  []*RelationTree
//
func (service *dept) getDeptChildIds(ctx context.Context, lists []*DeptTree, pid int64) []*DeptTree {
var (
count = len(lists)
newLists []*DeptTree
)
if count == 0 {
return nil
}
for i := 0; i < len(lists); i++ {
if lists[i].Id > 0 && lists[i].Pid == pid {
var row *DeptTree
if err := gconv.Structs(lists[i], &row); err != nil {
panic(err)
}
row.Children = service.getDeptChildIds(ctx, lists, row.Id)
newLists = append(newLists, row)
}
}
return newLists
}
type DeptListTree struct {
Id int64 `json:"id" `
Key int64 `json:"key" `
Pid int64 `json:"pid" `
Label string `json:"label"`
Title string `json:"title"`
Name string `json:"name"`
Type string `json:"type"`
Children []*DeptListTree `json:"children"`
}
//
//  @Title  获取列表树
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *dept) ListTree(ctx context.Context, in input.AdminDeptListTreeInp) (list []*input.AdminDeptListTreeModel, err error) {
mod := dao.AdminDept.Ctx(ctx)
var (
dataList []*entity.AdminDept
models []*DeptListTree
)
err = mod.Order("id desc").Scan(&dataList)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, err
}
_ = gconv.Structs(dataList, &models)
// TODO  重写树入参
for i := 0; i < len(models); i++ {
models[i].Key = models[i].Id
models[i].Title = models[i].Name
models[i].Label = models[i].Name
}
childIds := service.getDeptTreeChildIds(ctx, models, 0)
_ = gconv.Structs(childIds, &list)
return list, nil
}
//
//  @Title  将列表转为父子关系列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   lists
//  @Param   pid
//  @Return  []*RelationTree
//
func (service *dept) getDeptTreeChildIds(ctx context.Context, lists []*DeptListTree, pid int64) []*DeptListTree {
var (
count = len(lists)
newLists []*DeptListTree
)
if count == 0 {
return nil
}
for i := 0; i < len(lists); i++ {
if lists[i].Id > 0 && lists[i].Pid == pid {
var row *DeptListTree
if err := gconv.Structs(lists[i], &row); err != nil {
panic(err)
}
row.Children = service.getDeptTreeChildIds(ctx, lists, row.Id)
newLists = append(newLists, row)
}
}
return newLists
}
//
//  @Title  获取部门名称
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   id
//  @Return  name
//  @Return  err
//
func (service *dept) GetName(ctx context.Context, id int64) (name string, err error) {
var data entity.AdminDept
err = dao.AdminDept.Ctx(ctx).
Where("id", id).
Fields("name").
Scan(&data)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return name, err
}
return data.Name, nil
}

View File

@ -1,657 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminService
import (
"context"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/model"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao"
"github.com/bufanyun/hotgo/app/service/internal/dto"
"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/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
)
var Member = new(member)
type member struct{}
//
//  @Title  修改登录密码
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *member) UpdateProfile(ctx context.Context, in input.AdminMemberUpdateProfileInp) (err error) {
memberId := com.Context.Get(ctx).User.Id
if memberId <= 0 {
err := gerror.New("获取用户信息失败!")
return err
}
var memberInfo entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
_, err = dao.AdminMember.Ctx(ctx).
Where("id", memberId).
Data(g.Map{
"mobile": in.Mobile,
"email": in.Email,
"realname": in.Realname,
}).
Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return
}
//
//  @Title  修改登录密码
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *member) UpdatePwd(ctx context.Context, in input.AdminMemberUpdatePwdInp) (err error) {
var memberInfo entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if gmd5.MustEncryptString(in.OldPassword+memberInfo.Salt) != memberInfo.PasswordHash {
err = gerror.New("原密码不正确")
return err
}
_, err = dao.AdminMember.Ctx(ctx).
Where("id", in.Id).
Data(g.Map{
"password_hash": gmd5.MustEncryptString(in.NewPassword + memberInfo.Salt),
"updated_at": gtime.Now(),
}).
Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return
}
//
//  @Title  重置密码
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *member) ResetPwd(ctx context.Context, in input.AdminMemberResetPwdInp) (err error) {
var memberInfo entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
_, err = dao.AdminMember.Ctx(ctx).
Where("id", in.Id).
Data(g.Map{
"password_hash": gmd5.MustEncryptString(in.Password + memberInfo.Salt),
"updated_at": gtime.Now(),
}).
Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return
}
//
//  @Title  菜单名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *member) EmailUnique(ctx context.Context, in input.AdminMemberEmailUniqueInp) (*input.AdminMemberEmailUniqueModel, error) {
var res input.AdminMemberEmailUniqueModel
isUnique, err := dao.AdminMember.IsUniqueEmail(ctx, in.Id, in.Email)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.IsUnique = isUnique
return &res, nil
}
//
//  @Title  手机号是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *member) MobileUnique(ctx context.Context, in input.AdminMemberMobileUniqueInp) (*input.AdminMemberMobileUniqueModel, error) {
var res input.AdminMemberMobileUniqueModel
isUnique, err := dao.AdminMember.IsUniqueMobile(ctx, in.Id, in.Mobile)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.IsUnique = isUnique
return &res, nil
}
//
//  @Title  菜单名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *member) NameUnique(ctx context.Context, in input.AdminMemberNameUniqueInp) (*input.AdminMemberNameUniqueModel, error) {
var res input.AdminMemberNameUniqueModel
isUnique, err := dao.AdminMember.IsUniqueName(ctx, in.Id, in.Username)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.IsUnique = isUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *member) Delete(ctx context.Context, in input.AdminMemberDeleteInp) error {
exist, err := dao.AdminMember.Ctx(ctx).Where("member_id", in.Id).One()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !exist.IsEmpty() {
return gerror.New("请先解除该部门下所有已关联用户关联关系!")
}
_, err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *member) Edit(ctx context.Context, in input.AdminMemberEditInp) (err error) {
if in.Username == "" {
err = gerror.New("帐号不能为空")
return err
}
uniqueName, err := dao.AdminMember.IsUniqueName(ctx, in.Id, in.Username)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueName {
err = gerror.New("帐号已存在")
return err
}
if in.Mobile != "" {
uniqueMobile, err := dao.AdminMember.IsUniqueMobile(ctx, in.Id, in.Mobile)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueMobile {
err = gerror.New("手机号已存在")
return err
}
}
if in.Email != "" {
uniqueEmail, err := dao.AdminMember.IsUniqueMobile(ctx, in.Id, in.Email)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueEmail {
err = gerror.New("邮箱已存在")
return err
}
}
// 修改
in.UpdatedAt = gtime.Now()
if in.Id > 0 {
_, err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Data(in).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
// 更新岗位
err = MemberPost.UpdatePostIds(ctx, in.Id, in.PostIds)
if err != nil {
return err
}
return nil
}
// 新增
in.CreatedAt = gtime.Now()
// 新增用户时的额外属性
var data input.AdminMemberAddInp
data.AdminMemberEditInp = in
data.Salt = grand.S(6)
data.PasswordHash = gmd5.MustEncryptString(data.Password + data.Salt)
g.Log().Print(ctx, "data.Salt:", data)
insert, err := dao.AdminMember.Ctx(ctx).Data(data).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
// 更新岗位
id, err := insert.LastInsertId()
if err != nil {
return err
}
err = MemberPost.UpdatePostIds(ctx, id, in.PostIds)
if err != nil {
return err
}
return nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataMaxSortRes
//  @Return  error
//
func (service *member) MaxSort(ctx context.Context, in input.AdminMemberMaxSortInp) (*input.AdminMemberMaxSortModel, error) {
var res input.AdminMemberMaxSortModel
if in.Id > 0 {
if err := dao.AdminMember.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
}
res.Sort = res.Sort + 10
return &res, nil
}
//
//  @Title  获取指定字典类型信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeViewRes
//  @Return  error
//
func (service *member) View(ctx context.Context, in input.AdminMemberViewInp) (res *input.AdminMemberViewModel, err error) {
if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return res, nil
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *member) List(ctx context.Context, in input.AdminMemberListInp) (list []*input.AdminMemberListModel, totalCount int, err error) {
var authorization = com.Jwt.GetAuthorization(com.Context.Get(ctx).Request)
// TODO 获取jwtToken
jwtToken := consts.RedisJwtToken + gmd5.MustEncryptString(authorization)
g.Log().Print(ctx, "jwtToken:", jwtToken)
mod := dao.AdminMember.Ctx(ctx)
if in.Realname != "" {
mod = mod.WhereLike("realname", "%"+in.Realname+"%")
}
if in.Username != "" {
mod = mod.WhereLike("username", "%"+in.Username+"%")
}
if in.Mobile > 0 {
mod = mod.Where("mobile", in.Mobile)
}
if in.Status > 0 {
mod = mod.Where("status", in.Status)
}
if in.DeptId > 0 {
mod = mod.Where("dept_id", in.DeptId)
}
// 日期范围
if in.StartTime != "" {
mod = mod.WhereGTE("created_at", in.StartTime)
}
if in.EndTime != "" {
mod = mod.WhereLTE("created_at", in.EndTime)
}
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
// TODO  重写树入参
for i := 0; i < len(list); i++ {
// TODO  部门
deptName, err := dao.AdminDept.Ctx(ctx).
Fields("name").
Where("id", list[i].DeptId).
Value()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
list[i].DeptName = deptName.String()
// TODO  角色
roleName, err := dao.AdminRole.Ctx(ctx).
Fields("name").
Where("id", list[i].Role).
Value()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
list[i].RoleName = roleName.String()
}
return list, totalCount, err
}
// //
//  @Title  获取登录用户信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *member) LoginMemberInfo(ctx context.Context, req *adminForm.MemberInfoReq) (res *adminForm.MemberInfoRes, err error) {
var (
defaultPortalConfig adminForm.PortalConfig
defaultPortalConfigs []*adminForm.PortalConfig
configContent adminForm.PortalConfigContent
configContents []*adminForm.PortalConfigContent
configContentOptions []*adminForm.PortalConfigContentOptions
Options adminForm.PortalConfigContentOptions
)
g.Log().Print(ctx, "测试")
// TODO  配置内容选项
Options.TitleRequired = true
Options.Refresh = 1
configContentOptions = append(configContentOptions, &Options)
// TODO  配置内容
configContent.Options = configContentOptions
configContent.Id = 1
configContent.X = 0
configContent.Y = 0
configContent.W = 3
configContent.H = 262
configContent.I = 1
configContent.Key = "kuaijierukou"
configContent.IsShowTitle = "N"
configContent.IsAllowDrag = false
configContent.Name = "快捷入口"
configContent.Type = "smallPage"
configContent.Url = "dashboard/portal/CommonUse"
configContent.Moved = true
configContents = append(configContents, &configContent)
// TODO  默认配置
defaultPortalConfig.Id = "4ae60dd1debe462096698e1da993317a"
defaultPortalConfig.Name = "首页"
defaultPortalConfig.Code = "6c297eb4651940edbb45c87c75be00d7"
defaultPortalConfig.ApplicationRange = "U"
defaultPortalConfig.IsDefault = "Y"
defaultPortalConfig.ResourceId = "1"
defaultPortalConfig.SystemDefinedId = "app1"
defaultPortalConfig.PortalConfigContent = gconv.String(configContents)
defaultPortalConfigs = append(defaultPortalConfigs, &defaultPortalConfig)
member := com.Context.Get(ctx).User
noticeList, err := Notice.WhereAll(ctx, dto.AdminNotice{
Status: consts.StatusEnabled,
})
if err != nil {
noticeList = nil
}
res = &adminForm.MemberInfoRes{
LincenseInfo: consts.VersionApp,
Permissions: []string{"*:*:*"},
Roles: []string{"admin"},
User: *member,
DefaultPortalConfig: defaultPortalConfigs,
UserPortalConfig: defaultPortalConfigs,
SysNoticeList: noticeList,
}
return
}
//
//  @Title  提交登录
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *member) Login(ctx context.Context, in input.AdminMemberLoginSignInp) (res *input.AdminMemberLoginSignModel, err error) {
var member *entity.AdminMember
err = dao.AdminMember.Ctx(ctx).Where("username", in.Username).Scan(&member)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
if member == nil {
err = gerror.New(consts.ErrorNotData)
return
}
if member.Salt == "" {
err = gerror.New("用户信息错误")
return
}
if member.PasswordHash != gmd5.MustEncryptString(in.Password+member.Salt) {
err = gerror.New("用户密码不正确")
return
}
// 默认设备
if in.Device != consts.AppAdmin && in.Device != consts.AppApi {
in.Device = consts.AppAdmin
}
// TODO  生成token
jwtExpires, err := g.Cfg().Get(ctx, "jwt.expires", 1)
if err != nil {
err := gerror.New(err.Error())
return nil, err
}
// TODO  有效期
expires := jwtExpires.Int64()
// TODO  过期时间戳
exp := gconv.Int64(gtime.Timestamp()) + expires
var identity *model.Identity
identity = &model.Identity{
Id: member.Id,
Username: member.Username,
Realname: member.Realname,
Avatar: member.Avatar,
Email: member.Email,
Mobile: member.Mobile,
VisitCount: member.VisitCount,
LastTime: member.LastTime,
LastIp: member.LastIp,
Role: member.Role,
Exp: exp,
Expires: expires,
App: consts.AppAdmin,
}
token, err := com.Jwt.GenerateLoginToken(ctx, identity, false)
if err != nil {
err = gerror.New(err.Error())
return
}
// TODO  更新登录信息
authKey := gmd5.MustEncryptString(gconv.String(token))
_, err = dao.AdminMember.Ctx(ctx).Data(dto.AdminMember{
AuthKey: gmd5.MustEncryptString(authKey),
VisitCount: member.VisitCount + 1,
LastTime: gtime.Timestamp(),
LastIp: com.Context.Get(ctx).Request.GetClientIp(),
}).Where(dto.AdminMember{
Id: member.Id,
}).Update()
if err != nil {
err = gerror.New(err.Error())
return
}
res = &input.AdminMemberLoginSignModel{
Identity: *identity,
Token: gconv.String(token),
}
return res, nil
}
//
//  @Title  获取角色下的会员列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *member) RoleMemberList(ctx context.Context, in input.AdminRoleMemberListInp) (list []*input.AdminMemberListModel, totalCount int, err error) {
mod := dao.AdminMember.Ctx(ctx)
if in.Role > 0 {
mod = mod.Where("role", in.Role)
}
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
return list, totalCount, err
}

View File

@ -1,533 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminService
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/model"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao"
"github.com/bufanyun/hotgo/app/service/internal/dto"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
var Menu = new(menu)
type menu struct{}
//
//  @Title  查询角色菜单列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.MenuSearchListRes
//  @Return  error
//
func (service *menu) RoleList(ctx context.Context, in input.MenuRoleListInp) (*input.MenuRoleListModel, error) {
var (
mod = dao.AdminRoleMenu.Ctx(ctx)
roleMenu []*entity.AdminRoleMenu
lst []*model.LabelTreeMenu
res input.MenuRoleListModel
err error
checkedKeys []int64
)
// TODO  获取选中菜单ID
if in.RoleId > 0 {
mod = mod.Where("role_id", in.RoleId)
}
err = mod.Fields().Scan(&roleMenu)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
for i := 0; i < len(roleMenu); i++ {
checkedKeys = append(checkedKeys, roleMenu[i].MenuId)
}
res.CheckedKeys = checkedKeys
// TODO  获取菜单树
lst, err = dao.AdminMenu.GenLabelTreeList(ctx, 0)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
_ = gconv.Structs(lst, &res.Menus)
return &res, nil
}
//
//  @Title  查询菜单列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.MenuSearchListRes
//  @Return  error
//
func (service *menu) SearchList(ctx context.Context, req *adminForm.MenuSearchListReq) (*adminForm.MenuSearchListRes, error) {
var (
mod = dao.AdminMenu.Ctx(ctx)
lst []*model.TreeMenu
res adminForm.MenuSearchListRes
searchResult []*entity.AdminMenu
id int64
ids []int64
err error
)
if req.Name != "" {
mod = mod.WhereLike("name", "%"+req.Name+"%")
}
if req.Status > 0 {
mod = mod.Where("status", req.Status)
}
if req.Name != "" || req.Status > 0 {
err = mod.Scan(&searchResult)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
for i := 0; i < len(searchResult); i++ {
id, err = dao.AdminMenu.TopPid(ctx, searchResult[i])
ids = append(ids, id)
}
}
lst, err = dao.AdminMenu.GenTreeList(ctx, 0, ids)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
_ = gconv.Structs(lst, &res)
return &res, nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataMaxSortRes
//  @Return  error
//
func (service *menu) MaxSort(ctx context.Context, req *adminForm.MenuMaxSortReq) (*adminForm.MenuMaxSortRes, error) {
var (
res adminForm.MenuMaxSortRes
err error
)
if req.Id > 0 {
if err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
}
res.Sort = res.Sort + 10
return &res, nil
}
//
//  @Title  菜单名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *menu) NameUnique(ctx context.Context, req *adminForm.MenuNameUniqueReq) (*adminForm.MenuNameUniqueRes, error) {
var (
res adminForm.MenuNameUniqueRes
err error
)
res.IsUnique, err = dao.AdminMenu.IsUniqueName(ctx, req.Id, req.Name)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  菜单编码是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *menu) CodeUnique(ctx context.Context, req *adminForm.MenuCodeUniqueReq) (*adminForm.MenuCodeUniqueRes, error) {
var (
res adminForm.MenuCodeUniqueRes
err error
)
res.IsUnique, err = dao.AdminMenu.IsUniqueCode(ctx, req.Id, req.Code)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *menu) Delete(ctx context.Context, req *adminForm.MenuDeleteReq) error {
exist, err := dao.AdminMenu.Ctx(ctx).Where("pid", req.Id).One()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !exist.IsEmpty() {
return gerror.New("请先删除该菜单下的所有菜单!")
}
_, err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *menu) Edit(ctx context.Context, req *adminForm.MenuEditReq) (err error) {
var (
pidData *dto.AdminMenu
uniqueName bool
uniqueCode bool
)
if req.Name == "" {
err = gerror.New("菜单名称不能为空")
return err
}
if req.Path == "" {
err = gerror.New("菜单路径不能为空")
return err
}
if req.Code == "" {
err = gerror.New("菜单编码不能为空")
return err
}
uniqueName, err = dao.AdminMenu.IsUniqueName(ctx, req.Id, req.Name)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueName {
err = gerror.New("菜单名称已存在")
return err
}
uniqueCode, err = dao.AdminMenu.IsUniqueCode(ctx, req.Id, req.Code)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueCode {
err = gerror.New("菜单编码已存在")
return err
}
// TODO 维护菜单等级
if req.Pid == 0 {
req.Level = 1
} else {
if err = dao.AdminMenu.Ctx(ctx).Where("id", req.Pid).Scan(&pidData); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if pidData == nil {
return gerror.New("上级菜单信息错误")
}
req.Level = gconv.Int(pidData.Level) + 1
}
// 修改
req.UpdatedAt = gtime.Now()
if req.Id > 0 {
if req.Pid == req.Id {
return gerror.New("上级菜单不能是当前菜单")
}
_, err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Data(req).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
// 新增
req.CreatedAt = gtime.Now()
_, err = dao.AdminMenu.Ctx(ctx).Data(req).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  获取信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeViewRes
//  @Return  error
//
func (service *menu) View(ctx context.Context, req *adminForm.MenuViewReq) (res *adminForm.MenuViewRes, err error) {
//var (
// res adminForm.MenuViewRes
//)
if err = dao.AdminMenu.Ctx(ctx).Where("id", req.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return res, nil
}
//
//  @Title  获取菜单列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *menu) List(ctx context.Context, req *adminForm.MenuListReq) (*adminForm.MenuListRes, error) {
var (
m = dao.AdminMenu.Ctx(ctx)
list []*entity.AdminMenu
res adminForm.MenuListRes
totalCount int
err error
)
if req.Pid == 0 {
m = m.Where("level", 1)
} else {
m = m.Where("pid", req.Pid)
}
totalCount, err = m.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
err = m.Page(req.Page, req.Limit).Scan(&list)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.List = list
res.Page = req.Page
res.Limit = req.Limit
res.TotalCount = totalCount
return &res, nil
}
type RelationTree struct {
adminForm.RoleDynamicBase
Children []*RelationTree `json:"children"`
}
//
//  @Title  获取菜单列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   member_id
//
func (service *menu) GetMenuList(ctx context.Context, member_id int64) (lists *adminForm.RoleDynamicRes, err error) {
var (
results []*entity.AdminMenu
models []*RelationTree
recursion []*adminForm.RoleDynamicBase
finalResponse adminForm.RoleDynamicRes
)
err = dao.AdminMenu.Ctx(ctx).Order("sort asc,id desc").Scan(&results)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
for i := 0; i < len(results); i++ {
// 元数据
var (
meta adminForm.RoleDynamicMeta
rec adminForm.RoleDynamicBase
)
meta.Title = results[i].Name
meta.Icon = results[i].Icon
meta.NoCache = gconv.Bool(results[i].IsCache)
meta.Remark = results[i].Remark
rec.Id = results[i].Id
rec.Pid = results[i].Pid
rec.IsFrame = results[i].IsFrame
rec.Name = results[i].Name
rec.Code = results[i].Code
rec.Path = results[i].Path
rec.Hidden = results[i].IsVisible == "1"
rec.Redirect = service.getRedirect(results[i])
rec.Component = service.getComponent(results[i])
rec.AlwaysShow = true
rec.Meta = &meta
recursion = append(recursion, &rec)
}
_ = gconv.Structs(recursion, &models)
childIds := service.getChildIds(ctx, models, 0)
_ = gconv.Structs(childIds, &finalResponse)
return &finalResponse, nil
}
//
//  @Title  获取菜单的组件配置
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   model
//  @Return  string
//
func (service *menu) getComponent(mod *entity.AdminMenu) string {
if mod.Type == "M" {
return "Layout"
}
if mod.Type == "C" {
return mod.Component
}
return mod.Component
}
//
//  @Title  获取菜单是否重定向
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   model
//  @Return  string
//
func (service *menu) getRedirect(model *entity.AdminMenu) string {
if model.Type == "M" {
return "noRedirect"
}
return ""
}
//
//  @Title  将菜单转为父子关系菜单
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   lists
//  @Param   pid
//  @Return  []*RelationTree
//
func (service *menu) getChildIds(ctx context.Context, lists []*RelationTree, pid int64) []*RelationTree {
var (
count = len(lists)
newLists []*RelationTree
)
if count == 0 {
return nil
}
for i := 0; i < len(lists); i++ {
if lists[i].Id > 0 && lists[i].Pid == pid {
var row *RelationTree
if err := gconv.Structs(lists[i], &row); err != nil {
panic(err)
}
row.Children = service.getChildIds(ctx, lists, row.Id)
newLists = append(newLists, row)
}
}
return newLists
}
//
//  @Title  根据条件查询一行的数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   where
//  @Return  *entity.AdminMenu
//
func (service *menu) WhereScan(ctx context.Context, where dto.AdminMenu) *entity.AdminMenu {
var (
mod *entity.AdminMenu
err error
)
if err = dao.AdminMenu.Ctx(ctx).Where(where).Scan(&mod); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil
}
return mod
}

View File

@ -1,263 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminService
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao"
"github.com/bufanyun/hotgo/app/service/internal/dto"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
var Notice = new(notice)
type notice struct{}
//
//  @Title  菜单名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *notice) NameUnique(ctx context.Context, in input.AdminNoticeNameUniqueInp) (*input.AdminNoticeNameUniqueModel, error) {
var res input.AdminNoticeNameUniqueModel
isUnique, err := dao.AdminNotice.IsUniqueTitle(ctx, in.Id, in.Title)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.IsUnique = isUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *notice) Delete(ctx context.Context, in input.AdminNoticeDeleteInp) error {
_, err := dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *notice) Edit(ctx context.Context, in input.AdminNoticeEditInp) (err error) {
if in.Title == "" {
err = gerror.New("名称不能为空")
return err
}
uniqueName, err := dao.AdminNotice.IsUniqueTitle(ctx, in.Id, in.Title)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueName {
err = gerror.New("名称已存在")
return err
}
// 修改
in.UpdatedAt = gtime.Now()
if in.Id > 0 {
_, err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Data(in).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
// 新增
in.CreatedAt = gtime.Now()
_, err = dao.AdminNotice.Ctx(ctx).Data(in).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataMaxSortRes
//  @Return  error
//
func (service *notice) MaxSort(ctx context.Context, in input.AdminNoticeMaxSortInp) (*input.AdminNoticeMaxSortModel, error) {
var res input.AdminNoticeMaxSortModel
if in.Id > 0 {
if err := dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
}
res.Sort = res.Sort + 10
return &res, nil
}
//
//  @Title  获取指定字典类型信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeViewRes
//  @Return  error
//
func (service *notice) View(ctx context.Context, in input.AdminNoticeViewInp) (res *input.AdminNoticeViewModel, err error) {
if err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return res, nil
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *notice) List(ctx context.Context, in input.AdminNoticeListInp) (list []*input.AdminNoticeListModel, totalCount int, err error) {
mod := dao.AdminNotice.Ctx(ctx)
if in.Realname != "" {
mod = mod.WhereLike("realname", "%"+in.Realname+"%")
}
if in.Username != "" {
mod = mod.WhereLike("username", "%"+in.Username+"%")
}
if in.Mobile > 0 {
mod = mod.Where("mobile", in.Mobile)
}
if in.Status > 0 {
mod = mod.Where("status", in.Status)
}
if in.DeptId > 0 {
mod = mod.Where("dept_id", in.DeptId)
}
// 日期范围
if in.StartTime != "" {
mod = mod.WhereGTE("created_at", in.StartTime)
}
if in.EndTime != "" {
mod = mod.WhereLTE("created_at", in.EndTime)
}
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
//// TODO  重写树入参
//for i := 0; i < len(list); i++ {
//}
return list, totalCount, err
}
//
//  @Title  根据条件查询所有数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   where
//  @Return  []*entity.AdminNotice
//  @Return  error
//
func (service *notice) WhereAll(ctx context.Context, where dto.AdminNotice) ([]*entity.AdminNotice, error) {
var (
model []*entity.AdminNotice
err error
result gdb.Result
)
result, err = dao.AdminNotice.Ctx(ctx).Where(where).All()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
err = gconv.Scan(result, &model)
if err != nil {
err = gerror.Wrap(err, consts.ErrorRotaPointer)
return nil, err
}
return model, nil
}
//
//  @Title  根据条件查询一行的数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   where
//  @Return  *entity.AdminMenu
//
func (service *notice) WhereScan(ctx context.Context, where dto.AdminNotice) *entity.AdminNotice {
var (
model *entity.AdminNotice
err error
)
if err = dao.AdminMenu.Ctx(ctx).Where(where).Scan(&model); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil
}
return model
}

View File

@ -1,165 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package adminService
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/internal/dao"
"github.com/bufanyun/hotgo/app/service/internal/dto"
"github.com/bufanyun/hotgo/app/utils"
)
var Role = new(role)
type role struct{}
//
//  @Title  验证权限
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   member_id
//  @Param   path
//  @Return  bool
//
func (service *role) Verify(ctx context.Context, member_id int, path string) bool {
var (
err error
)
if utils.Auth.IsExceptAuth(ctx, path) {
return true
}
menu := Menu.WhereScan(ctx, dto.AdminMenu{
Path: path,
Status: consts.StatusEnabled,
})
if menu == nil {
err = gerror.New(consts.ErrorNotData)
return false
}
g.Log().Print(ctx, "menu:", menu)
g.Log().Print(ctx, "err:", err)
return true
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *role) List(ctx context.Context, in input.AdminRoleListInp) (list []*input.AdminRoleListModel, totalCount int, err error) {
mod := dao.AdminRole.Ctx(ctx)
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
err = mod.Page(in.Page, in.Limit).Order("id asc").Scan(&list)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
return list, totalCount, err
}
//
//  @Title  获取指定角色的名称
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   RoleId
//  @Return  name
//  @Return  err
//
func (service *role) GetName(ctx context.Context, RoleId int64) (name string, err error) {
roleName, err := dao.AdminRole.Ctx(ctx).
Fields("name").
Where("id", RoleId).
Order("id desc").
Value()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return name, err
}
return roleName.String(), nil
}
//
//  @Title  获取指定会员的岗位列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *role) GetMemberList(ctx context.Context, RoleId int64) (list []*input.AdminRoleListModel, err error) {
err = dao.AdminRole.Ctx(ctx).
Where("id", RoleId).
Order("id desc").
Scan(&list)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, err
}
return list, err
}
//
//  @Title  更改角色菜单权限
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  err
//
func (service *role) EditRoleMenu(ctx context.Context, reqInfo *adminForm.RoleMenuEditReq) error {
return dao.AdminRoleMenu.Transaction(ctx, func(ctx context.Context, tx *gdb.TX) (err error) {
_, err = dao.AdminRoleMenu.Ctx(ctx).Where("role_id", reqInfo.RoleId).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
addMap := make(g.List, 0, len(reqInfo.MenuIds))
for _, v := range reqInfo.MenuIds {
addMap = append(addMap, g.Map{
"role_id": reqInfo.RoleId,
"menu_id": v,
})
}
_, err = dao.AdminRoleMenu.Ctx(ctx).Data(addMap).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
})
}

View File

@ -1,23 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package apiService
import (
"context"
"github.com/gogf/gf/v2/frame/g"
)
var Member = new(member)
type member struct {}
func (service *member) Test() (ctx context.Context) {
g.Log().Print(ctx, "apiService--WithMember--test...")
//g.Log().Print(ctx, "api调用" , service.App.Admin.Member.Test())
return
}

View File

@ -1,24 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"github.com/bufanyun/hotgo/app/service/internal/dao/internal"
)
// adminMenuOldDao is the data access object for table hg_admin_menu_old.
// You can define custom methods on it to extend its functionality as you wish.
type adminMenuOldDao struct {
*internal.AdminMenuOldDao
}
var (
// AdminMenuOld is globally public accessible object for table hg_admin_menu_old operations.
AdminMenuOld = adminMenuOldDao{
internal.NewAdminMenuOldDao(),
}
)
// Fill with you ideas below.

View File

@ -1,58 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao/internal"
"github.com/gogf/gf/v2/errors/gerror"
)
// adminNoticeDao is the data access object for table hg_admin_notice.
// You can define custom methods on it to extend its functionality as you wish.
type adminNoticeDao struct {
*internal.AdminNoticeDao
}
var (
// AdminNotice is globally public accessible object for table hg_admin_notice operations.
AdminNotice = adminNoticeDao{
internal.NewAdminNoticeDao(),
}
)
// Fill with you ideas below.
//
//  @Title  判断名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   id
//  @Param   name
//  @Return  bool
//  @Return  error
//
func (dao *adminNoticeDao) IsUniqueTitle(ctx context.Context, id int64, title string) (bool, error) {
var data *entity.AdminNotice
m := dao.Ctx(ctx).Where("title", title)
if id > 0 {
m = m.WhereNot("id", id)
}
if err := m.Scan(&data); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return false, err
}
if data == nil {
return true, nil
}
return false, nil
}

View File

@ -1,24 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"github.com/bufanyun/hotgo/app/service/internal/dao/internal"
)
// adminRoleDao is the data access object for table hg_admin_role.
// You can define custom methods on it to extend its functionality as you wish.
type adminRoleDao struct {
*internal.AdminRoleDao
}
var (
// AdminRole is globally public accessible object for table hg_admin_role operations.
AdminRole = adminRoleDao{
internal.NewAdminRoleDao(),
}
)
// Fill with you ideas below.

View File

@ -1,108 +0,0 @@
// ==========================================================================
// 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"
)
// AdminMenuOldDao is the data access object for table hg_admin_menu_old.
type AdminMenuOldDao 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 AdminMenuOldColumns // columns contains all the column names of Table for convenient usage.
}
// AdminMenuOldColumns defines and stores column names for table hg_admin_menu_old.
type AdminMenuOldColumns struct {
Id string // 菜单ID
Pid string // 父菜单ID
Name string // 菜单名称
Icon string // 菜单图标
Type string // 菜单类型M目录 C菜单 F按钮
Perms string // 权限标识
Path string // 路由地址
Component string // 组件路径
Query string // 路由参数
IsFrame string // 是否为外链0是 1否
IsCache string // 是否缓存0缓存 1不缓存
IsVisible string // 菜单状态0显示 1隐藏
Remark string // 备注
Level string // 级别
Tree string // 树
Sort string // 排序
Status string // 菜单状态
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
}
// adminMenuOldColumns holds the columns for table hg_admin_menu_old.
var adminMenuOldColumns = AdminMenuOldColumns{
Id: "id",
Pid: "pid",
Name: "name",
Icon: "icon",
Type: "type",
Perms: "perms",
Path: "path",
Component: "component",
Query: "query",
IsFrame: "is_frame",
IsCache: "is_cache",
IsVisible: "is_visible",
Remark: "remark",
Level: "level",
Tree: "tree",
Sort: "sort",
Status: "status",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
}
// NewAdminMenuOldDao creates and returns a new DAO object for table data access.
func NewAdminMenuOldDao() *AdminMenuOldDao {
return &AdminMenuOldDao{
group: "default",
table: "hg_admin_menu_old",
columns: adminMenuOldColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *AdminMenuOldDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *AdminMenuOldDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *AdminMenuOldDao) Columns() AdminMenuOldColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *AdminMenuOldDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *AdminMenuOldDao) 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 *AdminMenuOldDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -1,58 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao/internal"
"github.com/gogf/gf/v2/errors/gerror"
)
// sysConfigDao is the data access object for table hg_sys_config.
// You can define custom methods on it to extend its functionality as you wish.
type sysConfigDao struct {
*internal.SysConfigDao
}
var (
// SysConfig is globally public accessible object for table hg_sys_config operations.
SysConfig = sysConfigDao{
internal.NewSysConfigDao(),
}
)
//
//  @Title  判断名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   id
//  @Param   name
//  @Return  bool
//  @Return  error
//
func (dao *sysConfigDao) IsUniqueName(ctx context.Context, id int64, name string) (bool, error) {
var data *entity.SysConfig
m := dao.Ctx(ctx).Where("name", name)
if id > 0 {
m = m.WhereNot("id", id)
}
if err := m.Scan(&data); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return false, err
}
if data == nil {
return true, nil
}
return false, nil
}
// Fill with you ideas below.

View File

@ -1,62 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao/internal"
"github.com/gogf/gf/v2/errors/gerror"
)
// sysDictDataDao is the data access object for table hg_sys_dict_data.
// You can define custom methods on it to extend its functionality as you wish.
type sysDictDataDao struct {
*internal.SysDictDataDao
}
var (
// SysDictData is globally public accessible object for table hg_sys_dict_data operations.
SysDictData = sysDictDataDao{
internal.NewSysDictDataDao(),
}
)
//
//  @Title  判断字典类型是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   id
//  @Param   dictType
//  @Return  bool
//  @Return  error
//
func (dao *sysDictDataDao) IsUnique(ctx context.Context, id int64, dictType string, dictValue string) (bool, error) {
var (
data *entity.SysDictData
err error
)
m := dao.Ctx(ctx).Where("type", dictType).Where("value", dictValue)
if id > 0 {
m = m.WhereNot("id", id)
}
if err = m.Scan(&data); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return false, err
}
if data == nil {
return true, nil
}
return false, nil
}
// Fill with you ideas below.

View File

@ -1,62 +0,0 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao/internal"
"github.com/gogf/gf/v2/errors/gerror"
)
// sysDictTypeDao is the data access object for table hg_sys_dict_type.
// You can define custom methods on it to extend its functionality as you wish.
type sysDictTypeDao struct {
*internal.SysDictTypeDao
}
var (
// SysDictType is globally public accessible object for table hg_sys_dict_type operations.
SysDictType = sysDictTypeDao{
internal.NewSysDictTypeDao(),
}
)
//
//  @Title  判断字典类型是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   id
//  @Param   dictType
//  @Return  bool
//  @Return  error
//
func (dao *sysDictTypeDao) IsUnique(ctx context.Context, id int64, dictType string) (bool, error) {
var (
data *entity.SysDictType
err error
)
m := dao.Ctx(ctx).Where("type", dictType)
if id > 0 {
m = m.WhereNot("id", id)
}
if err = m.Scan(&data); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return false, err
}
if data == nil {
return true, nil
}
return false, nil
}
// Fill with you ideas below.

View File

@ -1,35 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package dto
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// AdminMenu is the golang structure of table hg_admin_menu for DAO operations like Where/Data.
type AdminMenu struct {
g.Meta `orm:"table:hg_admin_menu, dto:true"`
Id interface{} // 菜单ID
Pid interface{} // 父菜单ID
Name interface{} // 菜单名称
Code interface{} // 菜单编码
Icon interface{} // 菜单图标
Type interface{} // 菜单类型M目录 C菜单 F按钮
Perms interface{} // 权限标识
Path interface{} // 路由地址
Component interface{} // 组件路径
Query interface{} // 路由参数
IsFrame interface{} // 是否内嵌
IsCache interface{} // 是否不缓存
IsVisible interface{} // 是否隐藏
Remark interface{} // 备注
Level interface{} // 级别
Tree interface{} // 树
Sort interface{} // 排序
Status interface{} // 菜单状态
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
}

View File

@ -1,34 +0,0 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package dto
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// AdminMenuOld is the golang structure of table hg_admin_menu_old for DAO operations like Where/Data.
type AdminMenuOld struct {
g.Meta `orm:"table:hg_admin_menu_old, dto:true"`
Id interface{} // 菜单ID
Pid interface{} // 父菜单ID
Name interface{} // 菜单名称
Icon interface{} // 菜单图标
Type interface{} // 菜单类型M目录 C菜单 F按钮
Perms interface{} // 权限标识
Path interface{} // 路由地址
Component interface{} // 组件路径
Query interface{} // 路由参数
IsFrame interface{} // 是否为外链0是 1否
IsCache interface{} // 是否缓存0缓存 1不缓存
IsVisible interface{} // 菜单状态0显示 1隐藏
Remark interface{} // 备注
Level interface{} // 级别
Tree interface{} // 树
Sort interface{} // 排序
Status interface{} // 菜单状态
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
}

View File

@ -1,233 +0,0 @@
package sysService
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/input"
"github.com/bufanyun/hotgo/app/service/internal/dao"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
)
var Config = new(config)
type config struct{}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataMaxSortRes
//  @Return  error
//
func (service *config) GetValue(ctx context.Context, in input.SysConfigGetValueInp) (*input.SysConfigGetValueModel, error) {
var res input.SysConfigGetValueModel
if err := dao.SysConfig.Ctx(ctx).
Fields("value").
Where("key", in.Key).
Order("id desc").
Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  菜单名称是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *config) NameUnique(ctx context.Context, in input.SysConfigNameUniqueInp) (*input.SysConfigNameUniqueModel, error) {
var res input.SysConfigNameUniqueModel
isUnique, err := dao.SysConfig.IsUniqueName(ctx, in.Id, in.Name)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.IsUnique = isUnique
return &res, nil
}
//
//  @Title  删除
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *config) Delete(ctx context.Context, in input.SysConfigDeleteInp) error {
exist, err := dao.SysConfig.Ctx(ctx).Where("Member_id", in.Id).One()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !exist.IsEmpty() {
return gerror.New("请先解除该部门下所有已关联用户关联关系!")
}
_, err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  修改/新增
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *config) Edit(ctx context.Context, in input.SysConfigEditInp) (err error) {
if in.Name == "" {
err = gerror.New("名称不能为空")
return err
}
uniqueName, err := dao.SysConfig.IsUniqueName(ctx, in.Id, in.Name)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !uniqueName {
err = gerror.New("名称已存在")
return err
}
// 修改
in.UpdatedAt = gtime.Now()
if in.Id > 0 {
_, err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Data(in).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
// 新增
in.CreatedAt = gtime.Now()
_, err = dao.SysConfig.Ctx(ctx).Data(in).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataMaxSortRes
//  @Return  error
//
func (service *config) MaxSort(ctx context.Context, in input.SysConfigMaxSortInp) (*input.SysConfigMaxSortModel, error) {
var res input.SysConfigMaxSortModel
if in.Id > 0 {
if err := dao.SysConfig.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
}
res.Sort = res.Sort + 10
return &res, nil
}
//
//  @Title  获取指定字典类型信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeViewRes
//  @Return  error
//
func (service *config) View(ctx context.Context, in input.SysConfigViewInp) (res *input.SysConfigViewModel, err error) {
if err = dao.SysConfig.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return res, nil
}
//
//  @Title  获取列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *config) List(ctx context.Context, in input.SysConfigListInp) (list []*input.SysConfigListModel, totalCount int, err error) {
mod := dao.SysConfig.Ctx(ctx)
if in.Realname != "" {
mod = mod.WhereLike("realname", "%"+in.Realname+"%")
}
if in.Username != "" {
mod = mod.WhereLike("username", "%"+in.Username+"%")
}
if in.Mobile > 0 {
mod = mod.Where("mobile", in.Mobile)
}
if in.Status > 0 {
mod = mod.Where("status", in.Status)
}
if in.DeptId > 0 {
mod = mod.Where("dept_id", in.DeptId)
}
// 日期范围
if in.StartTime != "" {
mod = mod.WhereGTE("created_at", in.StartTime)
}
if in.EndTime != "" {
mod = mod.WhereLTE("created_at", in.EndTime)
}
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
err = mod.Page(in.Page, in.Limit).Order("id desc").Scan(&list)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
//// TODO  重写树入参
//for i := 0; i < len(list); i++ {
//}
return list, totalCount, err
}

View File

@ -1,505 +0,0 @@
//
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package sysService
import (
"context"
"github.com/bufanyun/hotgo/app/com"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/form/adminForm"
"github.com/bufanyun/hotgo/app/model"
"github.com/bufanyun/hotgo/app/model/entity"
"github.com/bufanyun/hotgo/app/service/internal/dao"
"github.com/bufanyun/hotgo/app/utils"
"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/gtime"
"github.com/gogf/gf/v2/util/gconv"
"time"
)
var Dict = new(dict)
type dict struct{}
//
//  @Title  数据键值是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *dict) DataUnique(ctx context.Context, req *adminForm.DictDataUniqueReq) (*adminForm.DictDataUniqueRes, error) {
var (
res adminForm.DictDataUniqueRes
err error
)
res.IsUnique, err = dao.SysDictData.IsUnique(ctx, req.Id, req.Type, req.Value)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  查询字典数据最大排序
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataMaxSortRes
//  @Return  error
//
func (service *dict) DataMaxSort(ctx context.Context, req *adminForm.DictDataMaxSortReq) (*adminForm.DictDataMaxSortRes, error) {
var (
m = dao.SysDictData.Ctx(ctx).Where("type", req.Type).Order("sort desc")
res adminForm.DictDataMaxSortRes
err error
)
if err = m.Scan(&res); err != nil && err.Error() != "sql: no rows in result set" {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.Sort = res.Sort + 10
return &res, nil
}
//
//  @Title  删除字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *dict) DataDelete(ctx context.Context, req *adminForm.DictDataDeleteReq) error {
var (
m = dao.SysDictData.Ctx(ctx).Where("id", req.Id)
err error
)
_, err = m.Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  修改/新增字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *dict) DataEdit(ctx context.Context, req *adminForm.DictDataEditReq) error {
var (
m = dao.SysDictData.Ctx(ctx)
isUnique bool
err error
)
if req.Label == "" {
err = gerror.New("字典标签不能为空")
return err
}
if req.Type == "" {
err = gerror.New("字典类型不能为空")
return err
}
if req.Value == "" {
err = gerror.New("字典键值不能为空")
return err
}
isUnique, err = dao.SysDictData.IsUnique(ctx, req.Id, req.Type, req.Value)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !isUnique {
err = gerror.New("字典键值已存在")
return err
}
req.UpdatedAt = gtime.Now()
// 修改
if req.Id > 0 {
_, err = m.Where("id", req.Id).Data(req).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
req.CreatedAt = gtime.Now()
// 新增
_, err = m.Data(req).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  获取指定字典数据信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeViewRes
//  @Return  error
//
func (service *dict) DataView(ctx context.Context, req *adminForm.DictDataViewReq) (*adminForm.DictDataViewRes, error) {
var (
m = dao.SysDictData.Ctx(ctx).Where("id", req.Id)
res adminForm.DictDataViewRes
err error
)
if err = m.Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  获取指定字典类型的属性数据
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictAttributeRes
//  @Return  error
//
func (service *dict) Attribute(ctx context.Context, req *adminForm.DictAttributeReq) (*adminForm.DictAttributeRes, error) {
var (
m = dao.SysDictData.Ctx(ctx).Where("type", req.Type).Order("sort asc,id desc")
res adminForm.DictAttributeRes
err error
)
if err = m.Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  获取字典数据列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *dict) DataList(ctx context.Context, req *adminForm.DictDataListReq) (*adminForm.DictDataListRes, error) {
var (
m = dao.SysDictData.Ctx(ctx).Where("type", req.Type)
list []*entity.SysDictData
res adminForm.DictDataListRes
totalCount int
err error
)
totalCount, err = m.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
if err = m.Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.List = list
res.Page = req.Page
res.Limit = req.Limit
res.TotalCount = totalCount
return &res, nil
}
//
//  @Title  导出字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictDataListRes
//  @Return  error
//
func (service *dict) TypeExport(ctx context.Context, req *adminForm.DictTypeExportReq) error {
// 导出格式
type exportImage struct {
Id int64 `json:"id" `
Name string `json:"name" `
Type string `json:"type" `
Remark string `json:"remark" `
Status string `json:"status" `
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
var (
list []exportImage
titleList = []string{"ID", "字典名称", "字典类型", "备注", "状态", "创建时间", "更新时间"}
fileName = "字典类型导出-" + com.Context.Get(ctx).ReqId + ".xlsx"
sheetName = "HotGo"
err error
)
if err = dao.SysDictType.Ctx(ctx).Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
// TODO 格式化格式
for i := 0; i < len(list); i++ {
if list[i].Status == consts.StatusEnabled {
list[i].Status = "启用"
} else if list[i].Status == consts.StatusDisable {
list[i].Status = "禁用"
} else if list[i].Status == consts.StatusDelete {
list[i].Status = "已删除"
}
}
// TODO 强转类型
writer := com.Context.Get(ctx).Request.Response.Writer
w, _ := interface{}(writer).(*ghttp.ResponseWriter)
g.Log().Print(ctx, "gconv.Interfaces(list):", gconv.Interfaces(list))
if err = utils.Excel.ExportByStruct(w, titleList, gconv.Interfaces(list), fileName, sheetName); err != nil {
err = gerror.Wrap(err, "ExportByStruct:")
return err
}
// TODO 加入到上下文
com.Context.SetResponse(ctx, &model.Response{
Code: consts.CodeOK,
Message: "导出成功",
Timestamp: time.Now().Unix(),
ReqId: com.Context.Get(ctx).ReqId,
})
return nil
}
//
//  @Title  删除字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *dict) TypeDelete(ctx context.Context, req *adminForm.DictTypeDeleteReq) error {
var (
m = dao.SysDictType.Ctx(ctx).Where("id", req.Id)
err error
)
_, err = m.Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  修改/新增字典类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  error
//
func (service *dict) TypeEdit(ctx context.Context, req *adminForm.DictTypeEditReq) error {
var (
m = dao.SysDictType.Ctx(ctx)
isUnique bool
err error
)
if req.Name == "" {
err = gerror.New("字典名称不能为空")
return err
}
if req.Type == "" {
err = gerror.New("字典类型不能为空")
return err
}
isUnique, err = dao.SysDictType.IsUnique(ctx, req.Id, req.Type)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if !isUnique {
err = gerror.New("字典类型已存在")
return err
}
req.UpdatedAt = gtime.Now()
// 修改
if req.Id > 0 {
_, err = m.Where("id", req.Id).Data(req).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
req.CreatedAt = gtime.Now()
// 新增
_, err = m.Where("id", req.Id).Data(req).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
//
//  @Title  类型是否唯一
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeUniqueRes
//  @Return  error
//
func (service *dict) TypeUnique(ctx context.Context, req *adminForm.DictTypeUniqueReq) (*adminForm.DictTypeUniqueRes, error) {
var (
res adminForm.DictTypeUniqueRes
err error
)
res.IsUnique, err = dao.SysDictType.IsUnique(ctx, req.Id, req.Type)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  获取指定字典类型信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  *adminForm.DictTypeViewRes
//  @Return  error
//
func (service *dict) TypeView(ctx context.Context, req *adminForm.DictTypeViewReq) (*adminForm.DictTypeViewRes, error) {
var (
m = dao.SysDictType.Ctx(ctx).Where("id", req.Id)
res adminForm.DictTypeViewRes
err error
)
if err = m.Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return &res, nil
}
//
//  @Title  获取字典类型列表
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   req
//  @Return  res
//  @Return  err
//
func (service *dict) TypeList(ctx context.Context, req *adminForm.DictTypeListReq) (*adminForm.DictTypeListRes, error) {
var (
m = dao.SysDictType.Ctx(ctx)
list []*entity.SysDictType
res adminForm.DictTypeListRes
totalCount int
err error
)
if req.Name != "" {
m = m.WhereLike("name", "%"+req.Name+"%")
}
if req.Type != "" {
m = m.Where("type", req.Type)
}
// 日期范围
if req.StartTime != "" {
m = m.WhereGTE("created_at", req.StartTime)
}
if req.EndTime != "" {
m = m.WhereLTE("created_at", req.EndTime)
}
// 状态
if req.Status > 0 {
m = m.Where("status", req.Status)
}
totalCount, err = m.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
if err = m.Page(req.Page, req.Limit).Order("sort asc,id desc").Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.List = list
res.Page = req.Page
res.Limit = req.Limit
res.TotalCount = totalCount
return &res, nil
}

View File

@ -1,29 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package sysService
import (
"context"
"github.com/bufanyun/hotgo/app/com"
)
var Provinces = new(provinces)
type provinces struct{}
//
//  @Title  获取地区中的省市编码
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   location
//
func (service *provinces) GetLocationCode(ctx context.Context, location com.IpLocationData) {
return
}

View File

@ -1,65 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package utils
import (
"context"
"github.com/gogf/gf/v2/frame/g"
)
// 权限认证类
var Auth = new(auth)
type auth struct{}
//
//  @Title  是否是不需要验证权限的路由地址
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   path
//  @Return  bool
//
func (util *auth) IsExceptAuth(ctx context.Context, path string) bool {
var pathList []string
except, _ := g.Cfg().Get(ctx, "router.admin.exceptAuth")
pathList = except.Strings()
for i := 0; i < len(pathList); i++ {
if Charset.IsExists(pathList[i], path) {
return true
}
}
return false
}
//
//  @Title  是否是不需要登录的路由地址
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//  @Param   path
//  @Return  bool
//
func (util *auth) IsExceptLogin(ctx context.Context, path string) bool {
var pathList []string
except, _ := g.Cfg().Get(ctx, "router.admin.exceptLogin")
pathList = except.Strings()
for i := 0; i < len(pathList); i++ {
if Charset.IsExists(pathList[i], path) {
return true
}
}
return false
}

View File

@ -1,121 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package utils
import (
"crypto/md5"
"crypto/rand"
"fmt"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
r "math/rand"
"time"
)
// 字符类
var Charset = new(charset)
type charset struct{}
//
//  @Title  获取map的所有key字串符类型
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   m
//  @Return  []string
//
func (util *charset) GetMapKeysByString(m map[string]string) []string {
// 数组默认长度为map长度,后面append时,不需要重新申请内存和拷贝,效率很高
j := 0
keys := make([]string, len(m))
for k := range m {
keys[j] = k
j++
}
return keys
}
//
//  @Title  生成md5
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   str
//  @Return  string
//
func (util *charset) Md5ToString(str string) string {
md5str := fmt.Sprintf("%x", md5.Sum([]byte(str)))
return md5str
}
//
//  @Title  生成随机字串符
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   n
//  @Param   alphabets
//  @Return  []byte
//
func (util *charset) RandomCreateBytes(n int, alphabets ...byte) []byte {
if len(alphabets) == 0 {
alphabets = []byte(`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`)
}
var bytes = make([]byte, n)
var randBy bool
r.Seed(time.Now().UnixNano())
if num, err := rand.Read(bytes); num != n || err != nil {
randBy = true
}
for i, b := range bytes {
if randBy {
bytes[i] = alphabets[r.Intn(len(alphabets))]
} else {
bytes[i] = alphabets[b%byte(len(alphabets))]
}
}
return bytes
}
//
//  @Title  格式化错误的堆栈信息
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   err
//  @Return  []string
//
func (util *charset) GetStack(err error) []string {
stackList := gstr.Split(gerror.Stack(err), "\n")
for i := 0; i < len(stackList); i++ {
stackList[i] = gstr.Replace(stackList[i], "\t", "--> ")
}
return stackList
}
//
//  @Title  判断字符或切片字符是否存在指定字符
//  @Description
//  @Author  Ms <133814250@qq.com>
//  @Param   elems
//  @Param   search
//  @Return  bool
//
func (util *charset) IsExists(elems interface{}, search string) bool {
switch elems.(type) {
case []string:
elem := gconv.Strings(elems)
for i := 0; i < len(elem); i++ {
if gconv.String(elem[i]) == search {
return true
}
}
default:
return gconv.String(elems) == search
}
return false
}

View File

@ -1,6 +0,0 @@
package utils
// 过滤类
var Filter = new(filter)
type filter struct{}

View File

@ -1,30 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package utils
import (
"net"
)
// 验证类
var Validate = new(validate)
type validate struct{}
//
//  @Title  是否为ipv4
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   ip
//  @Return  bool
//
func (util *validate) IsIp(ip string) bool {
if net.ParseIP(ip) != nil {
return true
}
return false
}

View File

@ -1,42 +0,0 @@
//
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package boot
import (
"context"
"github.com/bufanyun/hotgo/app/consts"
"github.com/bufanyun/hotgo/app/factory/queue"
"github.com/bufanyun/hotgo/app/service/sysService"
)
//
//  @Title  消息队列监听
//  @Description 
//  @Author  Ms <133814250@qq.com>
//  @Param   ctx
//
func QueueListen(ctx context.Context) {
consumer, err := queue.InstanceConsumer()
if err != nil {
queue.FatalLog(ctx, "InstanceConsumer异常", err)
return
}
// 全局日志
if listenErr := consumer.ListenReceiveMsgDo(consts.QueueLogTopic, func(mqMsg queue.MqMsg) {
// 自定义消费回调
err := sysService.Log.QueueJob(ctx, mqMsg)
// 记录消费日志
queue.ConsumerLog(ctx, consts.QueueLogTopic, mqMsg, err)
}); listenErr != nil {
queue.FatalLog(ctx, "主题:"+consts.QueueLogTopic+" 监听失败", listenErr)
}
}

View File

@ -1 +0,0 @@
config.yaml

View File

@ -1,139 +0,0 @@
# hotgo配置
hotgo:
debug: true # debug开关开启后接口出现错误时会输出堆栈信息默认为true
ipMethod: "cz88" # IP归属地解析方法可选cz88|whois默认为cz88
log: # 全局请求日志
switch: true # 日志开关默认为true
queue: true # 是否启用队列启用时需要配置队列信息默认为true
module: ["admin", "api"] # 需要记录的模块
skipCode: [] # 不记录的状态码,如: ["0", "-1"]
# 路由配置
router:
# 后台
admin:
# 前缀
prefix: "/admin"
# 不需要验证登录的路由地址
exceptLogin: [
"/login/captcha", # 登录验证码
"/login/sign", # 登录
"/login/logout", # 退出
]
# 不需要验证权限的路由地址
exceptAuth: [
"/member/info", # 登录用户信息
"/role/dynamic", # 获取动态路由
]
# 接口
api:
# 前缀
prefix: "/api"
# 不需要验证登录的路由地址
exceptPath: []
# HTTP Server.
server:
address: ":8299"
serverRoot: "resource/public"
openapiPath: "/openApi.json"
swaggerPath: "/doc"
DumpRouterMap: false
logPath: "./runtime/log/server"
ErrorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true
ErrorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true
errorLogPattern: "error/{Y-m-d}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log"
accessLogEnabled: true # 是否记录访问日志。默认为false
accessLogPattern: "access/{Y-m-d}.log" # 访问日志文件格式。默认为"access-{Ymd}.log"
serverAgent: "HG HTTP Server"
# Global logging.
logger:
level: "all"
stdout: true
headerPrint: false
ctxKeys: []
path: "./runtime/log/logger" # 日志文件路径。默认为空,表示关闭,仅输出到终端
file: "{Y-m-d}.log" # 日志文件格式。默认为"{Y-m-d}.log"
exception: # 系统异常日志
path: "./runtime/log/exception"
level: "all"
file: "{Y-m-d}.log"
queue: # 消息队列日志
path: "./runtime/log/queue"
level: "all"
file: "{Y-m-d}.log"
#JWT
jwt:
version: "1.0" # 版本号
expires: "864000" # 有效期,单位:秒
sign: "hotgo" # 秘钥,考虑安全问题请修改默认值
multiPort: true # 是否允许多端登录默认为true
#消息队列
queue:
switch: false # 队列开关默认为false
driver: "redis" # 队列驱动可选redis|rocketmq|kafka
retry: 2 # 重试次数
multiComsumer: true # 是否支持创建多个消费者
groupName: "hotgo" # mq群组名称
redis:
address: "127.0.0.1:6379" # redis服务地址默认为127.0.0.1:6379
db: 0 # 指定redis库
pass: "hg123456" # redis密码
timeout: 0 # 队列超时时间(s) 0为永不超时当队列一直没有被消费到达超时时间则队列会被销毁
rocketmq:
address: "127.0.0.1:9876" # brocker地址+端口
logLevel: "all" # 系统日志级别可选all|close|debug|info|warn|error|fatal
kafka:
address: "127.0.0.1:9092" # kafka地址+端口
version: "2.0.0.0" # kafka专属配置默认2.0.0.0
randClient: true # 开启随机生成clientID可以实现启动多实例同时一起消费相同topic加速消费能力的特性默认为true
# Redis数据库配置
redis:
default:
address: "127.0.0.1:6379"
db: "1"
pass: "hg123456."
idleTimeout: "20"
# cache:
# address: "127.0.0.1:6379"
# db: "1"
# pass: "hg123456."
# idleTimeout: "20"
# Database.
database:
logger:
level: "all"
stdout: true
default:
link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo"
debug: true
Prefix: "hg_"
# CLI.
gfcli:
build:
name: "hg"
gen:
dao:
- link: "mysql:hotgo:hg123456.@tcp(127.0.0.1:3306)/hotgo"
path: "./app"
# tables: "" #指定当前数据库中需要执行代码生成的数据表。如果为空,表示数据库的所有表都会生成。
# tablesEx: "" #指定当前数据库中需要排除代码生成的数据表。
removePrefix: "hg_"
descriptionTag: true
noModelComment: true
jsonCase: "Snake"

View File

@ -1,23 +0,0 @@
module github.com/bufanyun/hotgo
go 1.15
require (
github.com/Shopify/sarama v1.30.1
github.com/apache/rocketmq-client-go/v2 v2.1.0
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
github.com/bufanyun/pool v0.2.1
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gogf/gf/v2 v2.0.4
github.com/gomodule/redigo v2.0.0+incompatible
github.com/google/btree v1.0.1 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/mojocn/base64Captcha v1.3.5
github.com/pkg/errors v0.9.1 // indirect
github.com/xuri/excelize/v2 v2.5.0
go.opentelemetry.io/otel/trace v1.0.0
go.uber.org/atomic v1.6.0 // indirect
)

View File

@ -1,308 +0,0 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Shopify/sarama v1.30.1 h1:z47lP/5PBw2UVKf1lvfS5uWXaJws6ggk9PLnKEHtZiQ=
github.com/Shopify/sarama v1.30.1/go.mod h1:hGgx05L/DiW8XYBXeJdKIN6V2QUy2H6JqME5VT1NLRw=
github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae h1:ePgznFqEG1v3AjMklnK8H7BSc++FDSo7xfK9K7Af+0Y=
github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0=
github.com/apache/rocketmq-client-go/v2 v2.1.0 h1:3eABKfxc1WmS2lLTTbKMe1gZfZV6u1Sx9orFnOfABV0=
github.com/apache/rocketmq-client-go/v2 v2.1.0/go.mod h1:oEZKFDvS7sz/RWU0839+dQBupazyBV7WX5cP6nrio0Q=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
github.com/bufanyun/pool v0.2.1 h1:rW6TVJt+vS71d1uBI9sCMUjS39AWZFsUww+2XOh+338=
github.com/bufanyun/pool v0.2.1/go.mod h1:uZsjaA/H4agFQ1E0KWj4bnzRUVGmieM54pJiIKPTrAI=
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/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/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
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/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q=
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
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 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
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/v2 v2.0.4 h1:m5F/f2lX+etXhI6rAQCR6szQoHE1ulAYlIvH0UXa2wM=
github.com/gogf/gf/v2 v2.0.4/go.mod h1:apktt6TleWtCIwpz63vBqUnw8MX8gWKoZyxgDpXFtgM=
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.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
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 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
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.4/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 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/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/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA=
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794 h1:dWJxw+KQOMeVcoyxqG9I5fppPld1hh1FG8ngv0fKNsQ=
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794/go.mod h1:IwrOeG3O3K9vVXmcVvc9T0XLabw67QePi5pKQt5U+Kw=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
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/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 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
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 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI=
github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 h1:N8Bg45zpk/UcpNGnfJt2y/3lRWASHNTUET8owPYCgYI=
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/gjson v1.2.1 h1:j0efZLrZUvNerEf6xqoi0NjWMK5YlLrR7Guo/dxY174=
github.com/tidwall/gjson v1.2.1/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA=
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65 h1:rQ229MBgvW68s1/g6f1/63TgYwYxfF4E+bi/KC19P8g=
github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o=
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.5.0 h1:nDDVfX0qaDuGjAvb+5zTd0Bxxoqa1Ffv9B4kiE23PTM=
github.com/xuri/excelize/v2 v2.5.0/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y=
go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
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/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 h1:kETrAMYZq6WVGPa8IIixL0CaEcIUNi+1WX7grUoi3y8=
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
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-20200114155413-6afb5195e5aa/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/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.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
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 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
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.3/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 h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
stathat.com/c/consistent v1.0.0 h1:ezyc51EGcRPJUxfHGSgJjWzJdj3NiMU9pNfLNGiXV0c=
stathat.com/c/consistent v1.0.0/go.mod h1:QkzMWzcbB+yQBL2AttO6sgsQS/JSTapcDISJalmCDS0=

View File

@ -1,17 +0,0 @@
package main
import (
"github.com/bufanyun/hotgo/boot"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
var ctx = gctx.New()
if err := boot.Main.RunWithError(ctx); err != nil {
g.Log().Fatal(ctx, gerror.Stack(err))
}
}

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More