mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-02-02 18:28:41 +08:00
tt
This commit is contained in:
parent
9bd05abb2c
commit
8f3d679a57
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
1
hotgo-server/.gitattributes
vendored
Normal file
1
hotgo-server/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
* linguist-language=GO
|
20
hotgo-server/.gitignore
vendored
Normal file
20
hotgo-server/.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
.DS_Store
|
||||
.buildpath
|
||||
.hgignore.swp
|
||||
.project
|
||||
.orig
|
||||
.swp
|
||||
.idea/
|
||||
.settings/
|
||||
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
|
21
hotgo-server/LICENSE
Normal file
21
hotgo-server/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
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.
|
1
hotgo-server/README.MD
Normal file
1
hotgo-server/README.MD
Normal file
@ -0,0 +1 @@
|
||||
测试
|
31
hotgo-server/app/com/cache_com.go
Normal file
31
hotgo-server/app/com/cache_com.go
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// @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/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcache"
|
||||
)
|
||||
|
||||
type cache struct {
|
||||
}
|
||||
|
||||
var (
|
||||
Cache = new(cache)
|
||||
)
|
||||
|
||||
func (component *cache) New() *gcache.Cache {
|
||||
c := gcache.New()
|
||||
|
||||
//redis
|
||||
adapter := gcache.NewAdapterRedis(g.Redis())
|
||||
|
||||
//内存
|
||||
//adapter := gcache.NewAdapterMemory()
|
||||
c.SetAdapter(adapter)
|
||||
return c
|
||||
}
|
62
hotgo-server/app/com/captcha_com.go
Normal file
62
hotgo-server/app/com/captcha_com.go
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// @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/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
)
|
||||
|
||||
var Captcha = new(captcha)
|
||||
|
||||
type captcha struct{}
|
||||
|
||||
//
|
||||
// @Title 获取字母数字混合验证码
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Return idKeyC
|
||||
// @Return base64stringC
|
||||
//
|
||||
func (component *captcha) GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string) {
|
||||
driver := &base64Captcha.DriverString{
|
||||
Height: 80,
|
||||
Width: 240,
|
||||
//NoiseCount: 50,
|
||||
//ShowLineOptions: 20,
|
||||
Length: 4,
|
||||
Source: "abcdefghjkmnpqrstuvwxyz23456789",
|
||||
Fonts: []string{"chromohv.ttf"},
|
||||
}
|
||||
driver = driver.ConvertFonts()
|
||||
store := base64Captcha.DefaultMemStore
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
idKeyC, base64stringC, err := c.Generate()
|
||||
if err != nil {
|
||||
g.Log().Error(ctx,err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 验证输入的验证码是否正确
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param id
|
||||
// @Param answer
|
||||
// @Return bool
|
||||
//
|
||||
func (component *captcha) VerifyString(id, answer string) bool {
|
||||
driver := new(base64Captcha.DriverString)
|
||||
store := base64Captcha.DefaultMemStore
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
answer = gstr.ToLower(answer)
|
||||
return c.Verify(id, answer, true)
|
||||
}
|
107
hotgo-server/app/com/context_com.go
Normal file
107
hotgo-server/app/com/context_com.go
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// @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"
|
||||
)
|
||||
|
||||
type comContext struct{}
|
||||
|
||||
var Context = new(comContext)
|
||||
|
||||
//
|
||||
// @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
|
||||
}
|
254
hotgo-server/app/com/ip_com.go
Normal file
254
hotgo-server/app/com/ip_com.go
Normal file
@ -0,0 +1,254 @@
|
||||
//
|
||||
// @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/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"
|
||||
"time"
|
||||
)
|
||||
|
||||
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_common_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_common_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_common_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)
|
||||
}
|
161
hotgo-server/app/com/jwt_com.go
Normal file
161
hotgo-server/app/com/jwt_com.go
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// @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"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
83
hotgo-server/app/com/redis_com.go
Normal file
83
hotgo-server/app/com/redis_com.go
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// @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
|
||||
}
|
121
hotgo-server/app/com/response_com.go
Normal file
121
hotgo-server/app/com/response_com.go
Normal file
@ -0,0 +1,121 @@
|
||||
//
|
||||
// @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")
|
||||
}
|
14
hotgo-server/app/consts/app_consts.go
Normal file
14
hotgo-server/app/consts/app_consts.go
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// 应用类型
|
||||
const (
|
||||
AppAdmin = "admin"
|
||||
AppApi = "api"
|
||||
AppDefault = "default"
|
||||
)
|
31
hotgo-server/app/consts/code_consts.go
Normal file
31
hotgo-server/app/consts/code_consts.go
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// 全局状态码
|
||||
const (
|
||||
CodeNil = -1 // No error code specified.
|
||||
CodeOK = 0 // It is OK.
|
||||
CodeInternalError = 50 // An error occurred internally.
|
||||
CodeValidationFailed = 51 // Data validation failed.
|
||||
CodeDbOperationError = 52 // Database operation error.
|
||||
CodeInvalidParameter = 53 // The given parameter for current operation is invalid.
|
||||
CodeMissingParameter = 54 // Parameter for current operation is missing.
|
||||
CodeInvalidOperation = 55 // The function cannot be used like this.
|
||||
CodeInvalidConfiguration = 56 // The configuration is invalid for current operation.
|
||||
CodeMissingConfiguration = 57 // The configuration is missing for current operation.
|
||||
CodeNotImplemented = 58 // The operation is not implemented yet.
|
||||
CodeNotSupported = 59 // The operation is not supported yet.
|
||||
CodeOperationFailed = 60 // I tried, but I cannot give you what you want.
|
||||
CodeNotAuthorized = 61 // Not Authorized.
|
||||
CodeSecurityReason = 62 // Security Reason.
|
||||
CodeServerBusy = 63 // Server is busy, please try again later.
|
||||
CodeUnknown = 64 // Unknown error.
|
||||
CodeNotFound = 65 // Resource does not exist.
|
||||
CodeInvalidRequest = 66 // Invalid request.
|
||||
CodeBusinessValidationFailed = 300 // Business validation failed.
|
||||
)
|
12
hotgo-server/app/consts/context_consts.go
Normal file
12
hotgo-server/app/consts/context_consts.go
Normal file
@ -0,0 +1,12 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// 上下文
|
||||
const (
|
||||
ContextKey = "HotGoContext"
|
||||
)
|
8
hotgo-server/app/consts/debris_consts.go
Normal file
8
hotgo-server/app/consts/debris_consts.go
Normal file
@ -0,0 +1,8 @@
|
||||
package consts
|
||||
|
||||
// 碎片
|
||||
const (
|
||||
|
||||
// 默认分页
|
||||
DebrisPageSize = 10
|
||||
)
|
14
hotgo-server/app/consts/error_consts.go
Normal file
14
hotgo-server/app/consts/error_consts.go
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// 错误解释
|
||||
const (
|
||||
ErrorORM = "sql执行异常"
|
||||
ErrorNotData = "数据不存在"
|
||||
ErrorRotaPointer = "指针转换异常"
|
||||
)
|
15
hotgo-server/app/consts/openapi_consts.go
Normal file
15
hotgo-server/app/consts/openapi_consts.go
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// 开放API
|
||||
const (
|
||||
OpenAPITitle = `HotGo`
|
||||
OpenAPIDescription = `这是一个使用HotGo的简单演示HTTP服务器项目。 `
|
||||
OpenAPIName = `HotGo`
|
||||
OpenAPIURL = `http://hotgo.bufanyun.cn`
|
||||
)
|
14
hotgo-server/app/consts/queue_consts.go
Normal file
14
hotgo-server/app/consts/queue_consts.go
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// 消息队列
|
||||
const (
|
||||
QueueName = `queue:`
|
||||
QueueLogPath = "queue" // 需要在config中配置queue的log
|
||||
QueueLogTopic = `request-log`
|
||||
)
|
13
hotgo-server/app/consts/redis_consts.go
Normal file
13
hotgo-server/app/consts/redis_consts.go
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// redis
|
||||
const (
|
||||
RedisJwtToken = "jwtToken:" // JWT-token
|
||||
RedisJwtUserBind = "jwtUserBind:" // JWT-用户身份绑定
|
||||
)
|
14
hotgo-server/app/consts/status_consts.go
Normal file
14
hotgo-server/app/consts/status_consts.go
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
//
|
||||
const (
|
||||
StatusEnabled = "1" // 启用
|
||||
StatusDisable = "2" // 禁用
|
||||
StatusDelete = "3" //已删除
|
||||
)
|
12
hotgo-server/app/consts/version_consts.go
Normal file
12
hotgo-server/app/consts/version_consts.go
Normal file
@ -0,0 +1,12 @@
|
||||
//
|
||||
// @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 consts
|
||||
|
||||
// 应用版本
|
||||
const (
|
||||
VersionApp = "1.0.0"
|
||||
)
|
172
hotgo-server/app/controller/adminController/config_controller.go
Normal file
172
hotgo-server/app/controller/adminController/config_controller.go
Normal file
@ -0,0 +1,172 @@
|
||||
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
|
||||
}
|
176
hotgo-server/app/controller/adminController/dept_controller.go
Normal file
176
hotgo-server/app/controller/adminController/dept_controller.go
Normal file
@ -0,0 +1,176 @@
|
||||
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
|
||||
}
|
252
hotgo-server/app/controller/adminController/dict_controller.go
Normal file
252
hotgo-server/app/controller/adminController/dict_controller.go
Normal file
@ -0,0 +1,252 @@
|
||||
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
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
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
|
||||
}
|
104
hotgo-server/app/controller/adminController/login_controller.go
Normal file
104
hotgo-server/app/controller/adminController/login_controller.go
Normal file
@ -0,0 +1,104 @@
|
||||
//
|
||||
// @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
|
||||
}
|
371
hotgo-server/app/controller/adminController/member_controller.go
Normal file
371
hotgo-server/app/controller/adminController/member_controller.go
Normal file
@ -0,0 +1,371 @@
|
||||
//
|
||||
// @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)
|
||||
}
|
188
hotgo-server/app/controller/adminController/menu_controller.go
Normal file
188
hotgo-server/app/controller/adminController/menu_controller.go
Normal file
@ -0,0 +1,188 @@
|
||||
//
|
||||
// @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
|
||||
}
|
151
hotgo-server/app/controller/adminController/notice_controller.go
Normal file
151
hotgo-server/app/controller/adminController/notice_controller.go
Normal file
@ -0,0 +1,151 @@
|
||||
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
|
||||
}
|
170
hotgo-server/app/controller/adminController/post_controller.go
Normal file
170
hotgo-server/app/controller/adminController/post_controller.go
Normal file
@ -0,0 +1,170 @@
|
||||
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
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
//
|
||||
// @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/util/gconv"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
95
hotgo-server/app/controller/apiController/base_controller.go
Normal file
95
hotgo-server/app/controller/apiController/base_controller.go
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// @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
|
||||
}
|
29
hotgo-server/app/controller/apiController/dict_controller.go
Normal file
29
hotgo-server/app/controller/apiController/dict_controller.go
Normal file
@ -0,0 +1,29 @@
|
||||
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
|
||||
}
|
95
hotgo-server/app/controller/apiController/log_controller.go
Normal file
95
hotgo-server/app/controller/apiController/log_controller.go
Normal file
@ -0,0 +1,95 @@
|
||||
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
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
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
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
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
|
||||
}
|
246
hotgo-server/app/factory/queue/kafkamq.go
Normal file
246
hotgo-server/app/factory/queue/kafkamq.go
Normal file
@ -0,0 +1,246 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/Shopify/sarama"
|
||||
"github.com/bufanyun/hotgo/app/utils"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type KafkaMq struct {
|
||||
endPoints []string
|
||||
Partitions int32
|
||||
producerIns sarama.AsyncProducer
|
||||
consumerIns sarama.ConsumerGroup
|
||||
}
|
||||
|
||||
type KafkaConfig struct {
|
||||
ClientId string
|
||||
Brokers []string
|
||||
GroupID string
|
||||
Partitions int32
|
||||
Replication int16
|
||||
Version string
|
||||
UserName string
|
||||
Password string
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// SendMsg 按字符串类型生产数据
|
||||
func (r *KafkaMq) SendMsg(topic string, body string) (mqMsg MqMsg, err error) {
|
||||
return r.SendByteMsg(topic, []byte(body))
|
||||
}
|
||||
|
||||
// SendByteMsg 生产数据
|
||||
func (r *KafkaMq) SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error) {
|
||||
msg := &sarama.ProducerMessage{
|
||||
Topic: topic,
|
||||
Value: sarama.ByteEncoder(body),
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
if r.producerIns == nil {
|
||||
return mqMsg, gerror.New("queue kafka producerIns is nil")
|
||||
}
|
||||
|
||||
r.producerIns.Input() <- msg
|
||||
ctx, cancle := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancle()
|
||||
|
||||
select {
|
||||
case info := <-r.producerIns.Successes():
|
||||
return MqMsg{
|
||||
RunType: SendMsg,
|
||||
Topic: info.Topic,
|
||||
Offset: info.Offset,
|
||||
Partition: info.Partition,
|
||||
Timestamp: info.Timestamp,
|
||||
}, nil
|
||||
case fail := <-r.producerIns.Errors():
|
||||
if nil != fail {
|
||||
return mqMsg, fail.Err
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return mqMsg, gerror.New("send mqMst timeout")
|
||||
}
|
||||
|
||||
return mqMsg, nil
|
||||
}
|
||||
|
||||
// ListenReceiveMsgDo 消费数据
|
||||
func (r *KafkaMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error) {
|
||||
if r.consumerIns == nil {
|
||||
return gerror.New("queue kafka consumer not register")
|
||||
}
|
||||
|
||||
consumer := Consumer{
|
||||
ready: make(chan bool),
|
||||
receiveDoFun: receiveDo,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
go func() {
|
||||
|
||||
for {
|
||||
if err := r.consumerIns.Consume(ctx, []string{topic}, &consumer); err != nil {
|
||||
FatalLog(ctx, "kafka Error from consumer", err)
|
||||
}
|
||||
|
||||
if ctx.Err() != nil {
|
||||
Log(ctx, fmt.Sprint("kafka consoumer stop : %v", ctx.Err()))
|
||||
return
|
||||
}
|
||||
consumer.ready = make(chan bool)
|
||||
}
|
||||
}()
|
||||
|
||||
<-consumer.ready // Await till the consumer has been set up
|
||||
Log(ctx, "kafka consumer up and running!...")
|
||||
|
||||
utils.Signal.AppDefer(func() {
|
||||
Log(ctx, "kafka consumer close...")
|
||||
cancel()
|
||||
if err = r.consumerIns.Close(); err != nil {
|
||||
FatalLog(ctx, "kafka Error closing client", err)
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RegisterRedisMqConsumerMust 注册消费者
|
||||
func RegisterKafkaMqConsumerMust(connOpt KafkaConfig) (client MqConsumer) {
|
||||
mqIns := &KafkaMq{}
|
||||
|
||||
kfkVersion, _ := sarama.ParseKafkaVersion(connOpt.Version)
|
||||
if validateVersion(kfkVersion) == false {
|
||||
kfkVersion = sarama.V2_4_0_0
|
||||
}
|
||||
|
||||
brokers := connOpt.Brokers
|
||||
config := sarama.NewConfig()
|
||||
config.Consumer.Return.Errors = true
|
||||
config.Version = kfkVersion
|
||||
if connOpt.UserName != "" {
|
||||
config.Net.SASL.Enable = true
|
||||
config.Net.SASL.User = connOpt.UserName
|
||||
config.Net.SASL.Password = connOpt.Password
|
||||
}
|
||||
|
||||
// 默认按随机方式消费
|
||||
config.Consumer.Group.Rebalance.Strategy = sarama.BalanceStrategyRange
|
||||
config.Consumer.Offsets.Initial = sarama.OffsetNewest
|
||||
config.Consumer.Offsets.AutoCommit.Interval = 10 * time.Millisecond
|
||||
config.ClientID = connOpt.ClientId
|
||||
|
||||
consumerClient, err := sarama.NewConsumerGroup(brokers, connOpt.GroupID, config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mqIns.consumerIns = consumerClient
|
||||
return mqIns
|
||||
}
|
||||
|
||||
// RegisterKafkaProducerMust 注册并启动生产者接口实现
|
||||
func RegisterKafkaProducerMust(connOpt KafkaConfig) (client MqProducer) {
|
||||
mqIns := &KafkaMq{}
|
||||
|
||||
connOpt.ClientId = "HOTGO-Producer"
|
||||
RegisterKafkaProducer(connOpt, mqIns) //这里如果使用go程需要处理chan同步问题
|
||||
|
||||
return mqIns
|
||||
}
|
||||
|
||||
// RegisterKafkaProducerAsync 注册同步类型实例
|
||||
func RegisterKafkaProducer(connOpt KafkaConfig, mqIns *KafkaMq) {
|
||||
kfkVersion, _ := sarama.ParseKafkaVersion(connOpt.Version)
|
||||
if validateVersion(kfkVersion) == false {
|
||||
kfkVersion = sarama.V2_4_0_0
|
||||
}
|
||||
|
||||
brokers := connOpt.Brokers
|
||||
config := sarama.NewConfig()
|
||||
// 等待服务器所有副本都保存成功后的响应
|
||||
config.Producer.RequiredAcks = sarama.WaitForAll
|
||||
// 随机向partition发送消息
|
||||
config.Producer.Partitioner = sarama.NewRandomPartitioner
|
||||
// 是否等待成功和失败后的响应,只有上面的RequireAcks设置不是NoReponse这里才有用.
|
||||
config.Producer.Return.Successes = true
|
||||
|
||||
config.Producer.Return.Errors = true
|
||||
config.Producer.Compression = sarama.CompressionNone
|
||||
config.ClientID = connOpt.ClientId
|
||||
|
||||
config.Version = kfkVersion
|
||||
if connOpt.UserName != "" {
|
||||
config.Net.SASL.Enable = true
|
||||
config.Net.SASL.User = connOpt.UserName
|
||||
config.Net.SASL.Password = connOpt.Password
|
||||
}
|
||||
|
||||
var err error
|
||||
mqIns.producerIns, err = sarama.NewAsyncProducer(brokers, config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
utils.Signal.AppDefer(func() {
|
||||
Log(ctx, "kafka producer AsyncClose...")
|
||||
mqIns.producerIns.AsyncClose()
|
||||
})
|
||||
}
|
||||
|
||||
// validateVersion 验证版本是否有效
|
||||
func validateVersion(version sarama.KafkaVersion) bool {
|
||||
for _, item := range sarama.SupportedVersions {
|
||||
if version.String() == item.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Consumer struct {
|
||||
ready chan bool
|
||||
receiveDoFun func(mqMsg MqMsg)
|
||||
}
|
||||
|
||||
// Setup is run at the beginning of a new session, before ConsumeClaim
|
||||
func (consumer *Consumer) Setup(sarama.ConsumerGroupSession) error {
|
||||
// Mark the consumer as ready
|
||||
close(consumer.ready)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Cleanup is run at the end of a session, once all ConsumeClaim goroutines have exited
|
||||
func (consumer *Consumer) Cleanup(sarama.ConsumerGroupSession) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ConsumeClaim must start a consumer loop of ConsumerGroupClaim's Messages().
|
||||
func (consumer *Consumer) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
|
||||
|
||||
// NOTE:
|
||||
// Do not move the code below to a goroutine.
|
||||
// The `ConsumeClaim` itself is called within a goroutine, see:
|
||||
// https://github.com/Shopify/sarama/blob/master/consumer_group.go#L27-L29
|
||||
// `ConsumeClaim` 方法已经是 goroutine 调用 不要在该方法内进行 goroutine
|
||||
for message := range claim.Messages() {
|
||||
consumer.receiveDoFun(MqMsg{
|
||||
RunType: ReceiveMsg,
|
||||
Topic: message.Topic,
|
||||
Body: message.Value,
|
||||
Offset: message.Offset,
|
||||
Timestamp: message.Timestamp,
|
||||
Partition: message.Partition,
|
||||
})
|
||||
session.MarkMessage(message, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
63
hotgo-server/app/factory/queue/list.go
Normal file
63
hotgo-server/app/factory/queue/list.go
Normal file
@ -0,0 +1,63 @@
|
||||
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()
|
||||
}
|
39
hotgo-server/app/factory/queue/logger.go
Normal file
39
hotgo-server/app/factory/queue/logger.go
Normal file
@ -0,0 +1,39 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
|
||||
// 消费日志
|
||||
func ConsumerLog(ctx context.Context, topic string, mqMsg MqMsg, err error) {
|
||||
|
||||
if err != nil {
|
||||
g.Log(consts.QueueLogPath).Error(ctx, "消费 ["+topic+"] 失败", mqMsg, err)
|
||||
} else {
|
||||
g.Log(consts.QueueLogPath).Print(ctx, "消费 ["+topic+"] 成功", mqMsg.MsgId)
|
||||
}
|
||||
}
|
||||
|
||||
// 生产日志
|
||||
func ProducerLog(ctx context.Context, topic string, data interface{}, err error) {
|
||||
|
||||
if err != nil {
|
||||
g.Log(consts.QueueLogPath).Error(ctx, "生产 ["+topic+"] 失败", gconv.String(data))
|
||||
} else {
|
||||
g.Log(consts.QueueLogPath).Print(ctx, "生产 ["+topic+"] 成功", gconv.String(data))
|
||||
}
|
||||
}
|
||||
|
||||
// 致命日志
|
||||
func FatalLog(ctx context.Context, text string, err error) {
|
||||
g.Log(consts.QueueLogPath).Fatal(ctx, text+":", err)
|
||||
}
|
||||
|
||||
// 通用
|
||||
func Log(ctx context.Context, text string) {
|
||||
g.Log(consts.QueueLogPath).Print(ctx, text)
|
||||
}
|
248
hotgo-server/app/factory/queue/main.go
Normal file
248
hotgo-server/app/factory/queue/main.go
Normal file
@ -0,0 +1,248 @@
|
||||
//
|
||||
// @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)
|
||||
}
|
133
hotgo-server/app/factory/queue/queue_test.go
Normal file
133
hotgo-server/app/factory/queue/queue_test.go
Normal file
@ -0,0 +1,133 @@
|
||||
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")
|
||||
}
|
||||
|
||||
}
|
284
hotgo-server/app/factory/queue/redismq.go
Normal file
284
hotgo-server/app/factory/queue/redismq.go
Normal file
@ -0,0 +1,284 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/bufanyun/hotgo/app/utils"
|
||||
"github.com/bufanyun/pool"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RedisMq struct {
|
||||
poolName string
|
||||
groupName string
|
||||
retry int
|
||||
timeout int
|
||||
}
|
||||
|
||||
type PoolOption struct {
|
||||
InitCap int
|
||||
MaxCap int
|
||||
IdleTimeout int
|
||||
}
|
||||
|
||||
type RedisOption struct {
|
||||
Addr string
|
||||
Passwd string
|
||||
DBnum int
|
||||
Timeout int
|
||||
}
|
||||
|
||||
var redisPoolMap map[string]pool.Pool
|
||||
|
||||
func init() {
|
||||
redisPoolMap = make(map[string]pool.Pool)
|
||||
|
||||
}
|
||||
|
||||
// SendMsg 按字符串类型生产数据
|
||||
func (r *RedisMq) SendMsg(topic string, body string) (mqMsg MqMsg, err error) {
|
||||
return r.SendByteMsg(topic, []byte(body))
|
||||
}
|
||||
|
||||
// SendByteMsg 生产数据
|
||||
func (r *RedisMq) SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error) {
|
||||
if r.poolName == "" {
|
||||
return mqMsg, gerror.New("RedisMq producer not register")
|
||||
}
|
||||
if topic == "" {
|
||||
return mqMsg, gerror.New("RedisMq topic is empty")
|
||||
}
|
||||
|
||||
msgId := getRandMsgId()
|
||||
rdx, put, err := getRedis(r.poolName, r.retry)
|
||||
defer put()
|
||||
|
||||
if err != nil {
|
||||
return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者获取redis实例失败:", err))
|
||||
}
|
||||
|
||||
mqMsg = MqMsg{
|
||||
RunType: SendMsg,
|
||||
Topic: topic,
|
||||
MsgId: msgId,
|
||||
Body: body,
|
||||
}
|
||||
mqMsgJson, err := json.Marshal(mqMsg)
|
||||
if err != nil {
|
||||
return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者解析json消息失败:", err))
|
||||
}
|
||||
|
||||
queueName := r.genQueueName(r.groupName, topic)
|
||||
|
||||
_, err = redis.Int64(rdx.Do("LPUSH", queueName, mqMsgJson))
|
||||
if err != nil {
|
||||
return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者添加消息失败:", err))
|
||||
}
|
||||
|
||||
if r.timeout > 0 {
|
||||
_, err = rdx.Do("EXPIRE", queueName, r.timeout)
|
||||
if err != nil {
|
||||
return mqMsg, gerror.New(fmt.Sprint("queue redis 生产者设置过期时间失败:", err))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListenReceiveMsgDo 消费数据
|
||||
func (r *RedisMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error) {
|
||||
if r.poolName == "" {
|
||||
return gerror.New("RedisMq producer not register")
|
||||
}
|
||||
if topic == "" {
|
||||
return gerror.New("RedisMq topic is empty")
|
||||
}
|
||||
|
||||
queueName := r.genQueueName(r.groupName, topic)
|
||||
|
||||
go func() {
|
||||
for range time.Tick(1000 * time.Millisecond) {
|
||||
mqMsgList := r.loopReadQueue(queueName)
|
||||
for _, mqMsg := range mqMsgList {
|
||||
receiveDo(mqMsg)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 生成队列名称
|
||||
func (r *RedisMq) genQueueName(groupName string, topic string) string {
|
||||
return fmt.Sprintf(consts.QueueName+"%s-%s", groupName, topic)
|
||||
}
|
||||
|
||||
func (r *RedisMq) loopReadQueue(queueName string) (mqMsgList []MqMsg) {
|
||||
rdx, put, err := getRedis(r.poolName, r.retry)
|
||||
defer put()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
infoByte, err := redis.Bytes(rdx.Do("RPOP", queueName))
|
||||
if err != nil || len(infoByte) == 0 {
|
||||
break
|
||||
}
|
||||
var mqMsg MqMsg
|
||||
json.Unmarshal(infoByte, &mqMsg)
|
||||
if mqMsg.MsgId != "" {
|
||||
mqMsgList = append(mqMsgList, mqMsg)
|
||||
}
|
||||
|
||||
}
|
||||
return mqMsgList
|
||||
}
|
||||
|
||||
func RegisterRedisMqProducerMust(connOpt RedisOption, poolOpt PoolOption, groupName string, retry int) (client MqProducer) {
|
||||
var err error
|
||||
client, err = RegisterRedisMq(connOpt, poolOpt, groupName, retry)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// RegisterRedisMqConsumerMust 注册消费者
|
||||
func RegisterRedisMqConsumerMust(connOpt RedisOption, poolOpt PoolOption, groupName string) (client MqConsumer) {
|
||||
var err error
|
||||
client, err = RegisterRedisMq(connOpt, poolOpt, groupName, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// RegisterRedisMq 注册redismq实例
|
||||
func RegisterRedisMq(connOpt RedisOption, poolOpt PoolOption, groupName string, retry int) (mqIns *RedisMq, err error) {
|
||||
poolName, err := registerRedis(connOpt.Addr, connOpt.Passwd, connOpt.DBnum, poolOpt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if retry <= 0 {
|
||||
retry = 0
|
||||
}
|
||||
|
||||
mqIns = &RedisMq{
|
||||
poolName: poolName,
|
||||
groupName: groupName,
|
||||
retry: retry,
|
||||
timeout: connOpt.Timeout,
|
||||
}
|
||||
|
||||
return mqIns, nil
|
||||
}
|
||||
|
||||
// RegisterRedis 注册一个redis配置
|
||||
func registerRedis(host, pass string, dbnum int, opt PoolOption) (poolName string, err error) {
|
||||
poolName = utils.Charset.Md5ToString(fmt.Sprintf("%s-%s-%d", host, pass, dbnum))
|
||||
if _, ok := redisPoolMap[poolName]; ok {
|
||||
return poolName, nil
|
||||
}
|
||||
|
||||
connRedis := func() (interface{}, error) {
|
||||
conn, err := redis.Dial("tcp", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if pass != "" {
|
||||
_, err := conn.Do("AUTH", pass)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if dbnum > 0 {
|
||||
_, err := conn.Do("SELECT", dbnum)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// closeRedis 关闭连接
|
||||
closeRedis := func(v interface{}) error {
|
||||
return v.(redis.Conn).Close()
|
||||
}
|
||||
|
||||
// pingRedis 检测连接连通性
|
||||
pingRedis := func(v interface{}) error {
|
||||
conn := v.(redis.Conn)
|
||||
|
||||
val, err := redis.String(conn.Do("PING"))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val != "PONG" {
|
||||
return gerror.New("queue redis ping is error ping => " + val)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
p, err := pool.NewChannelPool(&pool.Config{
|
||||
InitialCap: opt.InitCap,
|
||||
MaxCap: opt.MaxCap,
|
||||
Factory: connRedis,
|
||||
Close: closeRedis,
|
||||
Ping: pingRedis,
|
||||
IdleTimeout: time.Duration(opt.IdleTimeout) * time.Second,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return poolName, err
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
redisPoolMap[poolName] = p
|
||||
|
||||
return poolName, nil
|
||||
}
|
||||
|
||||
// getRedis 获取一个redis db连接
|
||||
func getRedis(poolName string, retry int) (db redis.Conn, put func(), err error) {
|
||||
put = func() {}
|
||||
if _, ok := redisPoolMap[poolName]; ok == false {
|
||||
return nil, put, gerror.New("db connect is nil")
|
||||
}
|
||||
redisPool := redisPoolMap[poolName]
|
||||
|
||||
conn, err := redisPool.Get()
|
||||
for i := 0; i < retry; i++ {
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
conn, err = redisPool.Get()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, put, err
|
||||
}
|
||||
put = func() {
|
||||
redisPool.Put(conn)
|
||||
}
|
||||
|
||||
db = conn.(redis.Conn)
|
||||
return db, put, nil
|
||||
}
|
||||
|
||||
func getRandMsgId() (msgId string) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
radium := rand.Intn(999) + 1
|
||||
timeCode := time.Now().UnixNano()
|
||||
|
||||
msgId = fmt.Sprintf("%d%.4d", timeCode, radium)
|
||||
return msgId
|
||||
}
|
165
hotgo-server/app/factory/queue/rocketmq.go
Normal file
165
hotgo-server/app/factory/queue/rocketmq.go
Normal file
@ -0,0 +1,165 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/apache/rocketmq-client-go/v2"
|
||||
"github.com/apache/rocketmq-client-go/v2/consumer"
|
||||
"github.com/apache/rocketmq-client-go/v2/primitive"
|
||||
"github.com/apache/rocketmq-client-go/v2/producer"
|
||||
"github.com/apache/rocketmq-client-go/v2/rlog"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type RocketMq struct {
|
||||
endPoints []string
|
||||
producerIns rocketmq.Producer
|
||||
consumerIns rocketmq.PushConsumer
|
||||
}
|
||||
|
||||
// 重写日志
|
||||
func rewriteLog() {
|
||||
level, _ := g.Cfg().Get(ctx, "queue.rocketmq.logLevel", "debug")
|
||||
rlog.SetLogger(&RocketMqLogger{Flag: "[rocket_mq]", LevelLog: level.String()})
|
||||
}
|
||||
|
||||
// RegisterRocketProducerMust 注册并启动生产者接口实现
|
||||
func RegisterRocketProducerMust(endPoints []string, groupName string, retry int) (client MqProducer) {
|
||||
rewriteLog()
|
||||
var err error
|
||||
client, err = RegisterRocketMqProducer(endPoints, groupName, retry)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// RegisterRocketConsumerMust 注册消费者
|
||||
func RegisterRocketConsumerMust(endPoints []string, groupName string) (client MqConsumer) {
|
||||
rewriteLog()
|
||||
var err error
|
||||
client, err = RegisterRocketMqConsumer(endPoints, groupName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// SendMsg 按字符串类型生产数据
|
||||
func (r *RocketMq) SendMsg(topic string, body string) (mqMsg MqMsg, err error) {
|
||||
return r.SendByteMsg(topic, []byte(body))
|
||||
}
|
||||
|
||||
// SendByteMsg 生产数据
|
||||
func (r *RocketMq) SendByteMsg(topic string, body []byte) (mqMsg MqMsg, err error) {
|
||||
if r.producerIns == nil {
|
||||
return mqMsg, errors.New("RocketMq producer not register")
|
||||
}
|
||||
|
||||
result, err := r.producerIns.SendSync(context.Background(), &primitive.Message{
|
||||
Topic: topic,
|
||||
Body: body,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if result.Status != primitive.SendOK {
|
||||
return mqMsg, errors.New(fmt.Sprintf("RocketMq producer send msg error status:%v", result.Status))
|
||||
}
|
||||
|
||||
mqMsg = MqMsg{
|
||||
RunType: SendMsg,
|
||||
Topic: topic,
|
||||
MsgId: result.MsgID,
|
||||
Body: body,
|
||||
}
|
||||
return mqMsg, nil
|
||||
}
|
||||
|
||||
// ListenReceiveMsgDo 消费数据
|
||||
func (r *RocketMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg)) (err error) {
|
||||
if r.consumerIns == nil {
|
||||
return errors.New("RocketMq consumer not register")
|
||||
}
|
||||
|
||||
err = r.consumerIns.Subscribe(topic, consumer.MessageSelector{}, func(ctx context.Context,
|
||||
msgs ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
|
||||
for _, item := range msgs {
|
||||
go receiveDo(MqMsg{
|
||||
RunType: ReceiveMsg,
|
||||
Topic: item.Topic,
|
||||
MsgId: item.MsgId,
|
||||
Body: item.Body,
|
||||
})
|
||||
}
|
||||
return consumer.ConsumeSuccess, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = r.consumerIns.Start()
|
||||
if err != nil {
|
||||
r.consumerIns.Unsubscribe(topic)
|
||||
return err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RegisterRocketMqProducer 注册rocketmq生产者
|
||||
func RegisterRocketMqProducer(endPoints []string, groupName string, retry int) (mqIns *RocketMq, err error) {
|
||||
addr, err := primitive.NewNamesrvAddr(endPoints...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mqIns = &RocketMq{
|
||||
endPoints: endPoints,
|
||||
}
|
||||
|
||||
if retry <= 0 {
|
||||
retry = 0
|
||||
}
|
||||
|
||||
mqIns.producerIns, err = rocketmq.NewProducer(
|
||||
producer.WithNameServer(addr),
|
||||
producer.WithRetry(retry),
|
||||
producer.WithGroupName(groupName),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = mqIns.producerIns.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mqIns, nil
|
||||
}
|
||||
|
||||
// RegisterRocketMqConsumer 注册rocketmq消费者
|
||||
func RegisterRocketMqConsumer(endPoints []string, groupName string) (mqIns *RocketMq, err error) {
|
||||
addr, err := primitive.NewNamesrvAddr(endPoints...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mqIns = &RocketMq{
|
||||
endPoints: endPoints,
|
||||
}
|
||||
mqIns.consumerIns, err = rocketmq.NewPushConsumer(
|
||||
consumer.WithNameServer(addr),
|
||||
consumer.WithConsumerModel(consumer.Clustering),
|
||||
consumer.WithGroupName(groupName),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mqIns, nil
|
||||
}
|
83
hotgo-server/app/factory/queue/rocketmq_rewrite_logger.go
Normal file
83
hotgo-server/app/factory/queue/rocketmq_rewrite_logger.go
Normal file
@ -0,0 +1,83 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type RocketMqLogger struct {
|
||||
Flag string
|
||||
LevelLog string
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) Debug(msg string, fields map[string]interface{}) {
|
||||
if l.LevelLog == "close" {
|
||||
return
|
||||
}
|
||||
if msg == "" && len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if l.LevelLog == "debug" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [debug] ", msg))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) Level(level string) {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [level] ", level))
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) OutputPath(path string) (err error) {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [path] ", path))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) Info(msg string, fields map[string]interface{}) {
|
||||
if l.LevelLog == "close" {
|
||||
return
|
||||
}
|
||||
if msg == "" && len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if l.LevelLog == "info" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [info] ", msg))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) Warning(msg string, fields map[string]interface{}) {
|
||||
if l.LevelLog == "close" {
|
||||
return
|
||||
}
|
||||
if msg == "" && len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if l.LevelLog == "warn" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [warn] ", msg))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) Error(msg string, fields map[string]interface{}) {
|
||||
if l.LevelLog == "close" {
|
||||
return
|
||||
}
|
||||
if msg == "" && len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
if l.LevelLog == "error" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [error] ", msg))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) Fatal(msg string, fields map[string]interface{}) {
|
||||
if l.LevelLog == "close" {
|
||||
return
|
||||
}
|
||||
if msg == "" && len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if l.LevelLog == "fatal" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [fatal] ", msg))
|
||||
}
|
||||
}
|
73
hotgo-server/app/form/adminForm/config_form.go
Normal file
73
hotgo-server/app/form/adminForm/config_form.go
Normal file
@ -0,0 +1,73 @@
|
||||
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 {
|
||||
Key string `json:"key" v:"required#配置键不能为空" description:"配置键"`
|
||||
g.Meta `path:"/config/get_value" method:"get" tags:"配置" summary:"获取指定配置键的值"`
|
||||
}
|
||||
type ConfigGetValueRes struct {
|
||||
Value string `json:"value" description:"配置值"`
|
||||
}
|
||||
|
||||
// 名称是否唯一
|
||||
type ConfigNameUniqueReq struct {
|
||||
Name string `json:"name" v:"required#配置名称不能为空" description:"配置名称"`
|
||||
Id int64 `json:"id" description:"配置ID"`
|
||||
g.Meta `path:"/config/name_unique" method:"get" tags:"配置" summary:"配置名称是否唯一"`
|
||||
}
|
||||
type ConfigNameUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 查询列表
|
||||
type ConfigListReq struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
form.StatusReq
|
||||
Name string `json:"name" description:"配置名称"`
|
||||
g.Meta `path:"/config/list" method:"get" tags:"配置" summary:"获取配置列表"`
|
||||
}
|
||||
|
||||
type ConfigListRes struct {
|
||||
List []*input.SysConfigListModel `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 获取指定信息
|
||||
type ConfigViewReq struct {
|
||||
Id string `json:"id" v:"required#配置ID不能为空" description:"配置ID"`
|
||||
g.Meta `path:"/config/view" method:"get" tags:"配置" summary:"获取指定信息"`
|
||||
}
|
||||
type ConfigViewRes struct {
|
||||
*input.SysConfigViewModel
|
||||
}
|
||||
|
||||
// 修改/新增
|
||||
type ConfigEditReq struct {
|
||||
entity.SysConfig
|
||||
g.Meta `path:"/config/edit" method:"post" tags:"配置" summary:"修改/新增配置"`
|
||||
}
|
||||
type ConfigEditRes struct{}
|
||||
|
||||
// 删除
|
||||
type ConfigDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#配置ID不能为空" description:"配置ID"`
|
||||
g.Meta `path:"/config/delete" method:"post" tags:"配置" summary:"删除配置"`
|
||||
}
|
||||
type ConfigDeleteRes struct{}
|
||||
|
||||
// 最大排序
|
||||
type ConfigMaxSortReq struct {
|
||||
Id int64 `json:"id" description:"配置ID"`
|
||||
g.Meta `path:"/config/max_sort" method:"get" tags:"配置" summary:"配置最大排序"`
|
||||
}
|
||||
type ConfigMaxSortRes struct {
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
}
|
65
hotgo-server/app/form/adminForm/dept_form.go
Normal file
65
hotgo-server/app/form/adminForm/dept_form.go
Normal file
@ -0,0 +1,65 @@
|
||||
package adminForm
|
||||
|
||||
import (
|
||||
"github.com/bufanyun/hotgo/app/form/input"
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// 名称是否唯一
|
||||
type DeptNameUniqueReq struct {
|
||||
Name string `json:"name" v:"required#部门名称不能为空" description:"部门名称"`
|
||||
Id int64 `json:"id" description:"部门ID"`
|
||||
g.Meta `path:"/dept/name_unique" method:"get" tags:"部门" summary:"部门名称是否唯一"`
|
||||
}
|
||||
type DeptNameUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 查询列表树
|
||||
type DeptListTreeReq struct {
|
||||
Id int64 `json:"id" description:"部门ID"`
|
||||
g.Meta `path:"/dept/list_tree" method:"get" tags:"部门" summary:"获取部门列表树"`
|
||||
}
|
||||
|
||||
type DeptListTreeRes []*input.AdminDeptListTreeModel
|
||||
|
||||
// 查询列表
|
||||
type DeptListReq struct {
|
||||
Name string `json:"name" description:"部门名称"`
|
||||
g.Meta `path:"/dept/list" method:"get" tags:"部门" summary:"获取部门列表"`
|
||||
}
|
||||
|
||||
type DeptListRes []*input.AdminDeptListModel
|
||||
|
||||
// 获取指定信息
|
||||
type DeptViewReq struct {
|
||||
Id int64 `json:"id" v:"required#部门ID不能为空" description:"部门ID"`
|
||||
g.Meta `path:"/dept/view" method:"get" tags:"部门" summary:"获取指定信息"`
|
||||
}
|
||||
type DeptViewRes struct {
|
||||
*input.AdminDeptViewModel
|
||||
}
|
||||
|
||||
// 修改/新增字典数据
|
||||
type DeptEditReq struct {
|
||||
entity.AdminDept
|
||||
g.Meta `path:"/dept/edit" method:"post" tags:"部门" summary:"修改/新增部门"`
|
||||
}
|
||||
type DeptEditRes struct{}
|
||||
|
||||
// 删除字典类型
|
||||
type DeptDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#部门ID不能为空" description:"部门ID"`
|
||||
g.Meta `path:"/dept/delete" method:"post" tags:"部门" summary:"删除部门"`
|
||||
}
|
||||
type DeptDeleteRes struct{}
|
||||
|
||||
// 最大排序
|
||||
type DeptMaxSortReq struct {
|
||||
Id int64 `json:"id" description:"部门ID"`
|
||||
g.Meta `path:"/dept/max_sort" method:"get" tags:"部门" summary:"部门最大排序"`
|
||||
}
|
||||
type DeptMaxSortRes struct {
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
}
|
136
hotgo-server/app/form/adminForm/dict_form.go
Normal file
136
hotgo-server/app/form/adminForm/dict_form.go
Normal file
@ -0,0 +1,136 @@
|
||||
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 {
|
||||
Value string `json:"value" v:"required#数据键值不能为空" description:"数据键值"`
|
||||
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"`
|
||||
Id int64 `json:"id" description:"字典数据ID"`
|
||||
g.Meta `path:"/dict_data/unique" method:"get" tags:"字典" summary:"数据键值是否唯一"`
|
||||
}
|
||||
type DictDataUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 查询字典数据最大排序
|
||||
type DictDataMaxSortReq struct {
|
||||
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"`
|
||||
g.Meta `path:"/dict_data/max_sort" method:"get" tags:"字典" summary:"查询字典数据最大排序"`
|
||||
}
|
||||
type DictDataMaxSortRes struct {
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
}
|
||||
|
||||
// 修改/新增字典数据
|
||||
type DictDataEditReq struct {
|
||||
entity.SysDictData
|
||||
g.Meta `path:"/dict_data/edit" method:"post" tags:"字典" summary:"修改/新增字典数据"`
|
||||
}
|
||||
type DictDataEditRes struct{}
|
||||
|
||||
// 删除字典类型
|
||||
type DictDataDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#字典数据ID不能为空" description:"字典数据ID"`
|
||||
g.Meta `path:"/dict_data/delete" method:"post" tags:"字典" summary:"删除字典数据"`
|
||||
}
|
||||
type DictDataDeleteRes struct{}
|
||||
|
||||
// 获取指定字典数据信息
|
||||
type DictDataViewReq struct {
|
||||
Id string `json:"id" v:"required#字典数据ID不能为空" description:"字典数据ID"`
|
||||
g.Meta `path:"/dict_data/view" method:"get" tags:"字典" summary:"获取指定字典数据信息"`
|
||||
}
|
||||
type DictDataViewRes struct {
|
||||
*entity.SysDictData
|
||||
}
|
||||
|
||||
// 获取字典数据列表
|
||||
type DictDataListReq struct {
|
||||
form.PageReq
|
||||
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"`
|
||||
g.Meta `path:"/dict_data/list" method:"get" tags:"字典" summary:"获取字典数据列表"`
|
||||
}
|
||||
type DictDataListRes struct {
|
||||
List []*entity.SysDictData `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 获取指定字典类型的属性数据
|
||||
type DictAttributeReq struct {
|
||||
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"`
|
||||
g.Meta `path:"/dict/attribute" method:"get" tags:"字典" summary:"获取指定字典类型的属性数据"`
|
||||
}
|
||||
type DictAttributeRes []*entity.SysDictData
|
||||
|
||||
/************************ 字典类型 *****************/
|
||||
|
||||
// 修改/新增字典类型
|
||||
type DictTypeExportReq struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
form.StatusReq
|
||||
Name string `json:"name" description:"字典名称"`
|
||||
Type string `json:"type" description:"字典类型"`
|
||||
g.Meta `path:"/dict_type/export" method:"get" tags:"字典" summary:"导出字典类型"`
|
||||
}
|
||||
type DictTypeExportRes struct{}
|
||||
|
||||
// 刷新字典缓存
|
||||
type DictTypeRefreshCacheReq struct {
|
||||
g.Meta `path:"/dict_type/refresh_cache" method:"get" tags:"字典" summary:"刷新字典缓存"`
|
||||
}
|
||||
type DictTypeRefreshCacheRes struct{}
|
||||
|
||||
// 获取字典类型列表
|
||||
type DictTypeListReq struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
form.StatusReq
|
||||
Name string `json:"name" description:"字典名称"`
|
||||
Type string `json:"type" description:"字典类型"`
|
||||
g.Meta `path:"/dict_type/list" method:"get" tags:"字典" summary:"获取字典类型列表"`
|
||||
}
|
||||
type DictTypeListRes struct {
|
||||
List []*entity.SysDictType `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 修改/新增字典类型
|
||||
type DictTypeEditReq struct {
|
||||
entity.SysDictType
|
||||
g.Meta `path:"/dict_type/edit" method:"post" tags:"字典" summary:"修改/新增字典类型"`
|
||||
}
|
||||
type DictTypeEditRes struct{}
|
||||
|
||||
// 删除字典类型
|
||||
type DictTypeDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#字典类型ID不能为空" description:"字典类型ID"`
|
||||
g.Meta `path:"/dict_type/delete" method:"post" tags:"字典" summary:"删除字典类型"`
|
||||
}
|
||||
type DictTypeDeleteRes struct{}
|
||||
|
||||
// 获取指定字典类型信息
|
||||
type DictTypeViewReq struct {
|
||||
Id string `json:"id" v:"required#字典类型ID不能为空" description:"字典类型ID"`
|
||||
g.Meta `path:"/dict_type/view" method:"get" tags:"字典" summary:"获取指定字典类型信息"`
|
||||
}
|
||||
type DictTypeViewRes struct {
|
||||
*entity.SysDictType
|
||||
}
|
||||
|
||||
// 类型是否唯一
|
||||
type DictTypeUniqueReq struct {
|
||||
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"`
|
||||
Id int64 `json:"id" description:"字典类型ID"`
|
||||
g.Meta `path:"/dict_type/unique" method:"get" tags:"字典" summary:"类型是否唯一"`
|
||||
}
|
||||
type DictTypeUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
47
hotgo-server/app/form/adminForm/log_form.go
Normal file
47
hotgo-server/app/form/adminForm/log_form.go
Normal file
@ -0,0 +1,47 @@
|
||||
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 {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
Module string `json:"module" description:"应用端口"`
|
||||
MemberId int `json:"member_id" description:"用户ID"`
|
||||
TakeUpTime int `json:"take_up_time" description:"请求耗时"`
|
||||
Method string `json:"method" description:"请求方式"`
|
||||
Url string `json:"url" description:"请求路径"`
|
||||
Ip string `json:"ip" description:"访问IP"`
|
||||
ErrorCode string `json:"error_code" description:"状态码"`
|
||||
g.Meta `path:"/log/export" method:"get" tags:"日志" summary:"导出日志"`
|
||||
}
|
||||
type LogExportRes struct{}
|
||||
|
||||
// 获取菜单列表
|
||||
type LogListReq struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
Module string `json:"module" description:"应用端口"`
|
||||
MemberId int `json:"member_id" description:"用户ID"`
|
||||
TakeUpTime int `json:"take_up_time" description:"请求耗时"`
|
||||
Method string `json:"method" description:"请求方式"`
|
||||
Url string `json:"url" description:"请求路径"`
|
||||
Ip string `json:"ip" description:"访问IP"`
|
||||
ErrorCode string `json:"error_code" description:"状态码"`
|
||||
g.Meta `path:"/log/list" method:"get" tags:"日志" summary:"获取日志列表"`
|
||||
}
|
||||
|
||||
type LogListRes struct {
|
||||
List []*input.LogListModel `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
41
hotgo-server/app/form/adminForm/login_form.go
Normal file
41
hotgo-server/app/form/adminForm/login_form.go
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// @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" v:"" description:"验证码ID"`
|
||||
Base64 string `json:"base64" v:"" description:"验证码"`
|
||||
}
|
||||
|
||||
// 提交登录
|
||||
type LoginReq struct {
|
||||
g.Meta `path:"/login/sign" method:"post" tags:"登录" summary:"提交登录"`
|
||||
Username string `json:"username" v:"required#用户名不能为空" description:"用户名"`
|
||||
Password string `json:"password" v:"required#密码不能为空" description:"密码"`
|
||||
Cid string `json:"cid" v:"required#验证码ID不能为空" description:"验证码ID"`
|
||||
Code string `json:"code" v:"required#验证码不能为空" description:"验证码"`
|
||||
Device string `json:"device" description:"登录设备"`
|
||||
}
|
||||
type LoginRes struct {
|
||||
model.Identity
|
||||
Token string `json:"token" v:"" description:"登录token"`
|
||||
}
|
212
hotgo-server/app/form/adminForm/member_form.go
Normal file
212
hotgo-server/app/form/adminForm/member_form.go
Normal file
@ -0,0 +1,212 @@
|
||||
//
|
||||
// @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"
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// 更新会员资料
|
||||
type MemberUpdateProfileReq struct {
|
||||
Mobile int `json:"mobile" description:"手机号"`
|
||||
Email string `json:"email" description:"邮箱"`
|
||||
Realname string `json:"realname" description:"真实姓名"`
|
||||
g.Meta `path:"/member/update_profile" method:"post" tags:"会员" summary:"更新会员资料"`
|
||||
}
|
||||
type MemberUpdateProfileRes struct{}
|
||||
|
||||
// 修改登录密码
|
||||
type MemberUpdatePwdReq struct {
|
||||
OldPassword string `json:"oldPassword" v:"required#原密码不能为空" description:"原密码"`
|
||||
NewPassword string `json:"newPassword" v:"required|length:6,16#新密码不能为空#新密码需在6~16之间" description:"新密码"`
|
||||
g.Meta `path:"/member/update_pwd" method:"post" tags:"会员" summary:"重置密码"`
|
||||
}
|
||||
type MemberUpdatePwdRes struct{}
|
||||
|
||||
// 获取登录用户的基本信息
|
||||
type MemberProfileReq struct {
|
||||
g.Meta `path:"/member/profile" method:"get" tags:"会员" summary:"获取登录用户的基本信息"`
|
||||
}
|
||||
type MemberProfileRes struct {
|
||||
PostGroup string `json:"postGroup" description:"岗位名称"`
|
||||
RoleGroup string `json:"roleGroup" description:"角色名称"`
|
||||
User *input.AdminMemberViewModel `json:"user" description:"用户基本信息"`
|
||||
SysDept *input.AdminDeptViewModel `json:"sysDept" description:"部门信息"`
|
||||
SysRoles []*input.AdminRoleListModel `json:"sysRoles" description:"角色列表"`
|
||||
PostIds int64 `json:"postIds" description:"当前岗位"`
|
||||
RoleIds int64 `json:"roleIds" description:"当前角色"`
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
type MemberResetPwdReq struct {
|
||||
Password string `json:"password" v:"required#密码不能为空" description:"密码"`
|
||||
Id int64 `json:"id" description:"会员ID"`
|
||||
g.Meta `path:"/member/reset_pwd" method:"post" tags:"会员" summary:"重置密码"`
|
||||
}
|
||||
type MemberResetPwdRes struct{}
|
||||
|
||||
// 邮箱是否唯一
|
||||
type MemberEmailUniqueReq struct {
|
||||
Email string `json:"email" v:"required#邮箱不能为空" description:"邮箱"`
|
||||
Id int64 `json:"id" description:"会员ID"`
|
||||
g.Meta `path:"/member/email_unique" method:"get" tags:"会员" summary:"邮箱是否唯一"`
|
||||
}
|
||||
type MemberEmailUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 手机号是否唯一
|
||||
type MemberMobileUniqueReq struct {
|
||||
Mobile string `json:"mobile" v:"required#手机号不能为空" description:"手机号"`
|
||||
Id int64 `json:"id" description:"会员ID"`
|
||||
g.Meta `path:"/member/mobile_unique" method:"get" tags:"会员" summary:"手机号是否唯一"`
|
||||
}
|
||||
type MemberMobileUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 名称是否唯一
|
||||
type MemberNameUniqueReq struct {
|
||||
Username string `json:"username" v:"required#会员名称不能为空" description:"会员名称"`
|
||||
Id int64 `json:"id" description:"会员ID"`
|
||||
g.Meta `path:"/member/name_unique" method:"get" tags:"会员" summary:"会员名称是否唯一"`
|
||||
}
|
||||
type MemberNameUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 查询列表
|
||||
type MemberListReq struct {
|
||||
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:"岗位编码"`
|
||||
g.Meta `path:"/member/list" method:"get" tags:"会员" summary:"获取会员列表"`
|
||||
}
|
||||
|
||||
type MemberListRes struct {
|
||||
List []*input.AdminMemberListModel `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 获取指定信息
|
||||
type MemberViewReq struct {
|
||||
Id int64 `json:"id" description:"会员ID"` // v:"required#会员ID不能为空"
|
||||
g.Meta `path:"/member/view" method:"get" tags:"会员" summary:"获取指定信息"`
|
||||
}
|
||||
type MemberViewRes struct {
|
||||
*input.AdminMemberViewModel
|
||||
Posts []*input.AdminPostListModel `json:"posts" description:"可选岗位"`
|
||||
PostIds []int64 `json:"postIds" description:"当前岗位"`
|
||||
Roles []*input.AdminRoleListModel `json:"roles" description:"可选角色"`
|
||||
RoleIds []int64 `json:"roleIds" description:"当前角色"`
|
||||
DeptName string `json:"dept_name" description:"部门名称"`
|
||||
}
|
||||
|
||||
// 修改/新增
|
||||
type MemberEditReq struct {
|
||||
input.AdminMemberEditInp
|
||||
g.Meta `path:"/member/edit" method:"post" tags:"会员" summary:"修改/新增会员"`
|
||||
}
|
||||
type MemberEditRes struct{}
|
||||
|
||||
// 删除
|
||||
type MemberDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#会员ID不能为空" description:"会员ID"`
|
||||
g.Meta `path:"/member/delete" method:"post" tags:"会员" summary:"删除会员"`
|
||||
}
|
||||
type MemberDeleteRes struct{}
|
||||
|
||||
// 最大排序
|
||||
type MemberMaxSortReq struct {
|
||||
Id int64 `json:"id" description:"会员ID"`
|
||||
g.Meta `path:"/member/max_sort" method:"get" tags:"会员" summary:"会员最大排序"`
|
||||
}
|
||||
type MemberMaxSortRes struct {
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
}
|
||||
|
||||
// 获取登录用户信息
|
||||
type MemberInfoReq struct {
|
||||
g.Meta `path:"/member/info" method:"get" tags:"会员" summary:"获取登录用户信息" description:"获取管理后台的登录用户信息"`
|
||||
}
|
||||
|
||||
type PortalConfigContentOptions struct {
|
||||
TitleRequired bool `json:"titleRequired" titleRequired:""`
|
||||
MoreUrl string `json:"moreUrl" description:"模块地址"`
|
||||
Refresh int `json:"refresh" description:"刷新"`
|
||||
}
|
||||
|
||||
type PortalConfigContent struct {
|
||||
Id int `json:"id" description:"内容ID"`
|
||||
X int `json:"x" description:""`
|
||||
Y int `json:"y" description:""`
|
||||
W int `json:"w" description:"宽"`
|
||||
H int `json:"h" description:"高"`
|
||||
I int `json:"i" description:""`
|
||||
Key string `json:"key" description:""`
|
||||
IsShowTitle string `json:"isShowTitle" description:""`
|
||||
IsAllowDrag bool `json:"isAllowDrag" description:""`
|
||||
Name string `json:"name" description:""`
|
||||
Type string `json:"type" description:""`
|
||||
Url string `json:"url" description:""`
|
||||
Options []*PortalConfigContentOptions `json:"options" description:""`
|
||||
Moved bool `json:"moved" description:""`
|
||||
}
|
||||
|
||||
type PortalConfig struct {
|
||||
CreateByName string `json:"createByName" description:"创建者名称"`
|
||||
CreateDeptName string `json:"createDeptName" description:"创建部门名称"`
|
||||
ImportErrInfo string `json:"importErrInfo" description:"导出错误信息"`
|
||||
Id string `json:"id" description:"用户ID"`
|
||||
SearchValue string `json:"searchValue" description:"搜索内容"`
|
||||
CreateBy string `json:"createBy" description:"创建者名称"`
|
||||
CreateDept string `json:"createDept" description:"创建部门名称"`
|
||||
CreateTime *gtime.Time `json:"createTime" description:"创建时间"`
|
||||
UpdateBy string `json:"updateBy" description:"更新者名称"`
|
||||
UpdateTime *gtime.Time `json:"updateTime" description:"更新时间"`
|
||||
UpdateIp string `json:"updateIp" description:"更新iP"`
|
||||
Remark string `json:"remark" description:"备注"`
|
||||
Version string `json:"version" description:"版本号"`
|
||||
DelFlag string `json:"delFlag" description:"删除标签"`
|
||||
HandleType string `json:"handleType" description:""`
|
||||
Params string `json:"params" description:""`
|
||||
Name string `json:"name" description:"配置名称"`
|
||||
Code string `json:"code" description:"配置代码"`
|
||||
ApplicationRange string `json:"applicationRange" description:""`
|
||||
IsDefault string `json:"isDefault" description:"是否默认"`
|
||||
ResourceId string `json:"resourceId" description:""`
|
||||
ResourceName string `json:"resourceName" description:""`
|
||||
SystemDefinedId string `json:"systemDefinedId" description:""`
|
||||
Sort string `json:"sort" description:"排序"`
|
||||
SaveType string `json:"saveType" description:""`
|
||||
Status string `json:"status" description:"状态"`
|
||||
RecordLog string `json:"recordLog" description:""`
|
||||
PortalConfigContent string `json:"content" description:"配置内容"`
|
||||
}
|
||||
|
||||
type MemberInfoRes struct {
|
||||
DefaultPortalConfig []*PortalConfig `json:"defaultPortalConfig" description:"默认用户配置"`
|
||||
LincenseInfo string `json:"lincenseInfo" description:"应用版本号"`
|
||||
Permissions []string `json:"permissions"description:"权限"`
|
||||
Roles []string `json:"roles" description:"角色"`
|
||||
SysNoticeList []*entity.AdminNotice `json:"sysNoticeList" description:"系统公告"`
|
||||
UserPortalConfig []*PortalConfig `json:"userPortalConfig" description:"用户配置"`
|
||||
User model.Identity `json:"user" description:"用户信息"`
|
||||
}
|
92
hotgo-server/app/form/adminForm/menu_form.go
Normal file
92
hotgo-server/app/form/adminForm/menu_form.go
Normal file
@ -0,0 +1,92 @@
|
||||
package adminForm
|
||||
|
||||
import (
|
||||
"github.com/bufanyun/hotgo/app/form"
|
||||
"github.com/bufanyun/hotgo/app/model"
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// 菜单最大排序
|
||||
type MenuMaxSortReq struct {
|
||||
Id int64 `json:"id" description:"菜单ID"`
|
||||
g.Meta `path:"/menu/max_sort" method:"get" tags:"菜单" summary:"菜单最大排序"`
|
||||
}
|
||||
type MenuMaxSortRes struct {
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
}
|
||||
|
||||
// 菜单编码是否唯一
|
||||
type MenuCodeUniqueReq struct {
|
||||
Code string `json:"code" v:"required#菜单编码不能为空" description:"菜单编码"`
|
||||
Id int64 `json:"id" description:"菜单ID"`
|
||||
g.Meta `path:"/menu/code_unique" method:"get" tags:"菜单" summary:"菜单编码是否唯一"`
|
||||
}
|
||||
type MenuCodeUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 菜单名称是否唯一
|
||||
type MenuNameUniqueReq struct {
|
||||
Name string `json:"name" v:"required#菜单名称不能为空" description:"菜单名称"`
|
||||
Id int64 `json:"id" description:"菜单ID"`
|
||||
g.Meta `path:"/menu/name_unique" method:"get" tags:"菜单" summary:"菜单名称是否唯一"`
|
||||
}
|
||||
type MenuNameUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 修改/新增字典数据
|
||||
type MenuEditReq struct {
|
||||
entity.AdminMenu
|
||||
g.Meta `path:"/menu/edit" method:"post" tags:"菜单" summary:"修改/新增菜单"`
|
||||
}
|
||||
type MenuEditRes struct{}
|
||||
|
||||
// 删除字典类型
|
||||
type MenuDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#菜单ID不能为空" description:"菜单ID"`
|
||||
g.Meta `path:"/menu/delete" method:"post" tags:"菜单" summary:"删除菜单"`
|
||||
}
|
||||
type MenuDeleteRes struct{}
|
||||
|
||||
// 获取指定字典数据信息
|
||||
type MenuViewReq struct {
|
||||
Id string `json:"id" v:"required#菜单ID不能为空" description:"菜单ID"`
|
||||
g.Meta `path:"/menu/view" method:"get" tags:"菜单" summary:"获取指定菜单信息"`
|
||||
}
|
||||
type MenuViewRes struct {
|
||||
*entity.AdminMenu
|
||||
}
|
||||
|
||||
// 获取菜单列表
|
||||
type MenuListReq struct {
|
||||
form.PageReq
|
||||
Pid int64 `json:"pid" description:"父ID"`
|
||||
g.Meta `path:"/menu/list" method:"get" tags:"菜单" summary:"获取菜单列表"`
|
||||
}
|
||||
|
||||
type MenuListRes struct {
|
||||
List []*entity.AdminMenu `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 查询菜单列表
|
||||
type MenuSearchListReq struct {
|
||||
Name string `json:"name" description:"菜单名称"`
|
||||
form.StatusReq
|
||||
g.Meta `path:"/menu/search_list" method:"get" tags:"菜单" summary:"获取菜单列表"`
|
||||
}
|
||||
|
||||
type MenuSearchListRes []*model.TreeMenu
|
||||
|
||||
// 查询角色菜单列表
|
||||
type MenuRoleListReq struct {
|
||||
RoleId string `json:"role_id" description:"角色ID"`
|
||||
g.Meta `path:"/menu/role_list" method:"get" tags:"菜单" summary:"查询角色菜单列表"`
|
||||
}
|
||||
|
||||
type MenuRoleListRes struct {
|
||||
Menus []*model.LabelTreeMenu `json:"menus" description:"菜单列表"`
|
||||
CheckedKeys []int64 `json:"checkedKeys" description:"选择的菜单ID"`
|
||||
}
|
64
hotgo-server/app/form/adminForm/notice_form.go
Normal file
64
hotgo-server/app/form/adminForm/notice_form.go
Normal file
@ -0,0 +1,64 @@
|
||||
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 {
|
||||
Title string `json:"name" v:"required#公告名称不能为空" description:"公告名称"`
|
||||
Id int64 `json:"id" description:"公告ID"`
|
||||
g.Meta `path:"/notice/name_unique" method:"get" tags:"公告" summary:"公告名称是否唯一"`
|
||||
}
|
||||
type NoticeNameUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 查询列表
|
||||
type NoticeListReq struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
form.StatusReq
|
||||
Name string `json:"name" description:"公告名称"`
|
||||
g.Meta `path:"/notice/list" method:"get" tags:"公告" summary:"获取公告列表"`
|
||||
}
|
||||
|
||||
type NoticeListRes struct {
|
||||
List []*input.AdminNoticeListModel `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 获取指定信息
|
||||
type NoticeViewReq struct {
|
||||
Id string `json:"id" v:"required#公告ID不能为空" description:"公告ID"`
|
||||
g.Meta `path:"/notice/view" method:"get" tags:"公告" summary:"获取指定信息"`
|
||||
}
|
||||
type NoticeViewRes struct {
|
||||
*input.AdminNoticeViewModel
|
||||
}
|
||||
|
||||
// 修改/新增
|
||||
type NoticeEditReq struct {
|
||||
entity.AdminNotice
|
||||
g.Meta `path:"/notice/edit" method:"post" tags:"公告" summary:"修改/新增公告"`
|
||||
}
|
||||
type NoticeEditRes struct{}
|
||||
|
||||
// 删除
|
||||
type NoticeDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#公告ID不能为空" description:"公告ID"`
|
||||
g.Meta `path:"/notice/delete" method:"post" tags:"公告" summary:"删除公告"`
|
||||
}
|
||||
type NoticeDeleteRes struct{}
|
||||
|
||||
// 最大排序
|
||||
type NoticeMaxSortReq struct {
|
||||
Id int64 `json:"id" description:"公告ID"`
|
||||
g.Meta `path:"/notice/max_sort" method:"get" tags:"公告" summary:"公告最大排序"`
|
||||
}
|
||||
type NoticeMaxSortRes struct {
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
}
|
75
hotgo-server/app/form/adminForm/post_form.go
Normal file
75
hotgo-server/app/form/adminForm/post_form.go
Normal file
@ -0,0 +1,75 @@
|
||||
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 PostEditReq struct {
|
||||
entity.AdminPost
|
||||
g.Meta `path:"/post/edit" method:"post" tags:"岗位" summary:"修改/新增岗位"`
|
||||
}
|
||||
type PostEditRes struct{}
|
||||
|
||||
// 删除字典类型
|
||||
type PostDeleteReq struct {
|
||||
Id interface{} `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"`
|
||||
g.Meta `path:"/post/delete" method:"post" tags:"岗位" summary:"删除岗位"`
|
||||
}
|
||||
type PostDeleteRes struct{}
|
||||
|
||||
// 最大排序
|
||||
type PostMaxSortReq struct {
|
||||
Id int64 `json:"id" description:"岗位ID"`
|
||||
g.Meta `path:"/post/max_sort" method:"get" tags:"岗位" summary:"岗位最大排序"`
|
||||
}
|
||||
type PostMaxSortRes struct {
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
}
|
||||
|
||||
// 获取列表
|
||||
type PostListReq struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
form.StatusReq
|
||||
Name string `json:"name" description:"岗位名称"`
|
||||
Code string `json:"code" description:"岗位编码"`
|
||||
g.Meta `path:"/post/list" method:"get" tags:"岗位" summary:"获取岗位列表"`
|
||||
}
|
||||
|
||||
type PostListRes struct {
|
||||
List []*input.AdminPostListModel `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 获取指定信息
|
||||
type PostViewReq struct {
|
||||
Id string `json:"id" v:"required#岗位ID不能为空" description:"岗位ID"`
|
||||
g.Meta `path:"/post/view" method:"get" tags:"岗位" summary:"获取指定信息"`
|
||||
}
|
||||
type PostViewRes struct {
|
||||
*input.AdminPostViewModel
|
||||
}
|
||||
|
||||
// 编码是否唯一
|
||||
type PostCodeUniqueReq struct {
|
||||
Code string `json:"code" v:"required#岗位编码不能为空" description:"岗位编码"`
|
||||
Id int64 `json:"id" description:"岗位ID"`
|
||||
g.Meta `path:"/post/code_unique" method:"get" tags:"岗位" summary:"岗位编码是否唯一"`
|
||||
}
|
||||
type PostCodeUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
||||
|
||||
// 名称是否唯一
|
||||
type PostNameUniqueReq struct {
|
||||
Name string `json:"name" v:"required#岗位名称不能为空" description:"岗位名称"`
|
||||
Id int64 `json:"id" description:"岗位ID"`
|
||||
g.Meta `path:"/post/name_unique" method:"get" tags:"岗位" summary:"岗位名称是否唯一"`
|
||||
}
|
||||
type PostNameUniqueRes struct {
|
||||
IsUnique bool `json:"is_unique" description:"是否唯一"`
|
||||
}
|
89
hotgo-server/app/form/adminForm/role_form.go
Normal file
89
hotgo-server/app/form/adminForm/role_form.go
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// @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 RoleMemberListReq struct {
|
||||
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:"岗位编码"`
|
||||
g.Meta `path:"/role/member_list" method:"get" tags:"角色" summary:"获取角色下的会员列表"`
|
||||
}
|
||||
|
||||
type RoleMemberListRes struct {
|
||||
List []*input.AdminMemberListModel `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
||||
|
||||
// 查询列表
|
||||
type RoleListReq struct {
|
||||
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:"岗位编码"`
|
||||
g.Meta `path:"/role/list" method:"get" tags:"角色" summary:"获取角色列表"`
|
||||
}
|
||||
|
||||
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
|
34
hotgo-server/app/form/apiForm/base_form.go
Normal file
34
hotgo-server/app/form/apiForm/base_form.go
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// @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#语言不能为空" description:"语言"`
|
||||
}
|
||||
type BaseLangRes struct {
|
||||
}
|
||||
|
||||
// 获取登录验证码
|
||||
type IpLocationReq struct {
|
||||
g.Meta `path:"/base/ip_location" method:"get" tags:"基础" summary:"获取IP归属地信息"`
|
||||
Ip string `json:"ip" v:"required#ip不能为空" description:"ipv4地址"`
|
||||
}
|
||||
type IpLocationRes struct {
|
||||
com.IpLocationData
|
||||
}
|
||||
|
||||
type ExportReq struct {
|
||||
g.Meta `path:"/base/export" method:"get" tags:"字典" summary:"导出字典类型"`
|
||||
}
|
||||
type ExportRes struct{}
|
13
hotgo-server/app/form/apiForm/dict_form.go
Normal file
13
hotgo-server/app/form/apiForm/dict_form.go
Normal file
@ -0,0 +1,13 @@
|
||||
package apiForm
|
||||
|
||||
import (
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// 获取指定字典类型的属性数据
|
||||
type DictAttributeReq struct {
|
||||
Type string `json:"type" example:"sys_common_status" v:"required#字典类型不能为空" description:"字典类型"`
|
||||
g.Meta `path:"/dict/attribute" method:"get" tags:"字典" summary:"获取指定字典类型的属性数据"`
|
||||
}
|
||||
type DictAttributeRes []*entity.SysDictData
|
47
hotgo-server/app/form/apiForm/log_form.go
Normal file
47
hotgo-server/app/form/apiForm/log_form.go
Normal file
@ -0,0 +1,47 @@
|
||||
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 {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
Module string `json:"module" description:"应用端口"`
|
||||
MemberId int `json:"member_id" description:"用户ID"`
|
||||
TakeUpTime int `json:"take_up_time" description:"请求耗时"`
|
||||
Method string `json:"method" description:"请求方式"`
|
||||
Url string `json:"url" description:"请求路径"`
|
||||
Ip string `json:"ip" description:"访问IP"`
|
||||
ErrorCode string `json:"error_code" description:"状态码"`
|
||||
g.Meta `path:"/log/export" method:"get" tags:"日志" summary:"导出日志"`
|
||||
}
|
||||
type LogExportRes struct{}
|
||||
|
||||
// 获取菜单列表
|
||||
type LogListReq struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
Module string `json:"module" description:"应用端口"`
|
||||
MemberId int `json:"member_id" description:"用户ID"`
|
||||
TakeUpTime int `json:"take_up_time" description:"请求耗时"`
|
||||
Method string `json:"method" description:"请求方式"`
|
||||
Url string `json:"url" description:"请求路径"`
|
||||
Ip string `json:"ip" description:"访问IP"`
|
||||
ErrorCode string `json:"error_code" description:"状态码"`
|
||||
g.Meta `path:"/log/list" method:"get" tags:"日志" summary:"获取日志列表"`
|
||||
}
|
||||
|
||||
type LogListRes struct {
|
||||
List []*input.LogListModel `json:"list" description:"数据列表"`
|
||||
form.PageRes
|
||||
}
|
37
hotgo-server/app/form/apiForm/login_form.go
Normal file
37
hotgo-server/app/form/apiForm/login_form.go
Normal file
@ -0,0 +1,37 @@
|
||||
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" description:"是否验证码"`
|
||||
Message string `json:"message" description:"消息"`
|
||||
Result string `json:"result" description:"响应"`
|
||||
// Sessionid string `json:"sessionid" description:"sessionid"`
|
||||
}
|
||||
|
||||
// 提交登录
|
||||
type LoginReq struct {
|
||||
g.Meta `path:"/login/sign" method:"post" tags:"登录" summary:"提交登录"`
|
||||
Username string `json:"username" v:"required#用户名不能为空" description:"用户名"`
|
||||
Password string `json:"password" v:"required#密码不能为空" description:"密码"`
|
||||
Cid string `json:"cid" v:"required#验证码ID不能为空" description:"验证码ID"`
|
||||
Code string `json:"code" v:"required#验证码不能为空" description:"验证码"`
|
||||
Device string `json:"device" description:"登录设备"`
|
||||
}
|
||||
type LoginRes struct {
|
||||
model.Identity
|
||||
Token string `json:"token" v:"" description:"登录token"`
|
||||
}
|
20
hotgo-server/app/form/apiForm/member_form.go
Normal file
20
hotgo-server/app/form/apiForm/member_form.go
Normal file
@ -0,0 +1,20 @@
|
||||
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" description:"岗位名称"`
|
||||
RoleGroup string `json:"roleGroup" description:"角色名称"`
|
||||
User *input.AdminMemberViewModel `json:"user" description:"用户基本信息"`
|
||||
SysDept *input.AdminDeptViewModel `json:"sysDept" description:"部门信息"`
|
||||
SysRoles []*input.AdminRoleListModel `json:"sysRoles" description:"角色列表"`
|
||||
PostIds int64 `json:"postIds" description:"当前岗位"`
|
||||
RoleIds int64 `json:"roleIds" description:"当前角色"`
|
||||
}
|
28
hotgo-server/app/form/common.go
Normal file
28
hotgo-server/app/form/common.go
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// @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" description:"当前页码"`
|
||||
Limit int `json:"limit" example:"1" d:"10" v:"min:1|max:100#|每页数量最小值不能低于1|最大值不能大于100" description:"每页数量"`
|
||||
}
|
||||
type PageRes struct {
|
||||
PageReq
|
||||
TotalCount int `json:"total_count" example:"0" description:"全部数据量"`
|
||||
}
|
||||
|
||||
// 时间查询
|
||||
type RangeDateReq struct {
|
||||
StartTime string `json:"start_time" v:"date#开始日期格式不正确" description:"开始日期"`
|
||||
EndTime string `json:"end_time" v:"date#结束日期格式不正确" description:"结束日期"`
|
||||
}
|
||||
|
||||
// 状态查询
|
||||
type StatusReq struct {
|
||||
Status int `json:"status" v:"in:0,1,2,3#状态可选范围:0~3" description:"状态"`
|
||||
}
|
75
hotgo-server/app/form/input/admin_dept_input.go
Normal file
75
hotgo-server/app/form/input/admin_dept_input.go
Normal file
@ -0,0 +1,75 @@
|
||||
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
|
171
hotgo-server/app/form/input/admin_member_input.go
Normal file
171
hotgo-server/app/form/input/admin_member_input.go
Normal file
@ -0,0 +1,171 @@
|
||||
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"`
|
||||
}
|
64
hotgo-server/app/form/input/admin_notice_input.go
Normal file
64
hotgo-server/app/form/input/admin_notice_input.go
Normal file
@ -0,0 +1,64 @@
|
||||
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"`
|
||||
}
|
68
hotgo-server/app/form/input/admin_post_input.go
Normal file
68
hotgo-server/app/form/input/admin_post_input.go
Normal file
@ -0,0 +1,68 @@
|
||||
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{}
|
44
hotgo-server/app/form/input/admin_role_input.go
Normal file
44
hotgo-server/app/form/input/admin_role_input.go
Normal file
@ -0,0 +1,44 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"github.com/bufanyun/hotgo/app/form"
|
||||
"github.com/bufanyun/hotgo/app/model"
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
)
|
||||
|
||||
// 获取列表
|
||||
type AdminRoleListInp struct {
|
||||
Page int
|
||||
Limit int
|
||||
}
|
||||
|
||||
type AdminRoleListModel struct {
|
||||
entity.AdminRole
|
||||
}
|
||||
|
||||
// 查询列表
|
||||
type AdminRoleMemberListInp struct {
|
||||
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 AdminRoleMemberListModel []*AdminMemberListModel
|
||||
|
||||
// 查询角色菜单列表
|
||||
type MenuRoleListInp struct {
|
||||
RoleId int64
|
||||
}
|
||||
type MenuRoleListModel struct {
|
||||
Menus []*model.LabelTreeMenu `json:"menus" description:"菜单列表"`
|
||||
CheckedKeys []int64 `json:"checkedKeys" description:"选择的菜单ID"`
|
||||
}
|
72
hotgo-server/app/form/input/sys_config_input.go
Normal file
72
hotgo-server/app/form/input/sys_config_input.go
Normal file
@ -0,0 +1,72 @@
|
||||
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"`
|
||||
}
|
26
hotgo-server/app/form/input/sys_log_input.go
Normal file
26
hotgo-server/app/form/input/sys_log_input.go
Normal file
@ -0,0 +1,26 @@
|
||||
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"`
|
||||
}
|
45
hotgo-server/app/hook/hook.go
Normal file
45
hotgo-server/app/hook/hook.go
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// @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()
|
||||
)
|
||||
|
||||
com.Context.SetTakeUpTime(ctx, gtime.TimestampMilli()-r.EnterTime)
|
||||
|
||||
go sysService.Log.AutoLog(ctx)
|
||||
}
|
20
hotgo-server/app/interfaces/queue_producer_interface.go
Normal file
20
hotgo-server/app/interfaces/queue_producer_interface.go
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// @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
|
||||
}
|
127
hotgo-server/app/middleware/admin_auth.go
Normal file
127
hotgo-server/app/middleware/admin_auth.go
Normal file
@ -0,0 +1,127 @@
|
||||
//
|
||||
// @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()
|
||||
}
|
127
hotgo-server/app/middleware/api_auth.go
Normal file
127
hotgo-server/app/middleware/api_auth.go
Normal file
@ -0,0 +1,127 @@
|
||||
//
|
||||
// @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()
|
||||
}
|
74
hotgo-server/app/middleware/handler_response.go
Normal file
74
hotgo-server/app/middleware/handler_response.go
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// @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/utils"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
//
|
||||
// @Title 全局响应中间件
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param r
|
||||
//
|
||||
func (s *sMiddleware) HandlerResponse(r *ghttp.Request) {
|
||||
r.Middleware.Next()
|
||||
|
||||
var (
|
||||
ctx = r.Context()
|
||||
comResponse = com.Context.Get(ctx).ComResponse
|
||||
code = gcode.CodeOK.Code()
|
||||
message = "操作成功"
|
||||
data interface{}
|
||||
err error
|
||||
)
|
||||
|
||||
if err := r.GetError(); err != nil {
|
||||
g.Log().Print(ctx, err)
|
||||
// 记录到自定义错误日志文件
|
||||
//g.Log("exception").Error(err)
|
||||
////返回固定的友好信息
|
||||
//r.Response.ClearBuffer()
|
||||
//r.Response.Writeln("服务器居然开小差了,请稍后再试吧!")
|
||||
}
|
||||
|
||||
// TODO 已存在响应内容,且是comResponse返回的时,中断运行
|
||||
if r.Response.BufferLength() > 0 && comResponse != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = r.GetError(); err != nil {
|
||||
// TODO 记录到自定义错误日志文件
|
||||
g.Log("exception").Print(r.Context(), "exception:", err)
|
||||
|
||||
code = consts.CodeInternalError
|
||||
message = "服务器居然开小差了,请稍后再试吧!"
|
||||
|
||||
// TODO 是否输出错误到页面
|
||||
if debug, _ := g.Cfg().Get(ctx, "hotgo.debug", true); debug.Bool() {
|
||||
data = utils.Charset.GetStack(err)
|
||||
}
|
||||
|
||||
} else if data, err = r.GetHandlerResponse(); err != nil {
|
||||
errCode := gerror.Code(err)
|
||||
if errCode == gcode.CodeNil {
|
||||
errCode = gcode.CodeInternalError
|
||||
}
|
||||
code = errCode.Code()
|
||||
message = err.Error()
|
||||
}
|
||||
|
||||
// TODO 返回固定的友好信息
|
||||
com.Response.RJson(r, code, message, data)
|
||||
}
|
64
hotgo-server/app/middleware/middleware.go
Normal file
64
hotgo-server/app/middleware/middleware.go
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// @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()
|
||||
}
|
40
hotgo-server/app/model/context.go
Normal file
40
hotgo-server/app/model/context.go
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// @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
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// Context 请求上下文结构
|
||||
type Context struct {
|
||||
ReqId string // 上下文ID
|
||||
Module string // 应用模块
|
||||
TakeUpTime int64 // 请求耗时 ms
|
||||
Request *ghttp.Request // 当前Request管理对象
|
||||
User *Identity // 上下文用户信息
|
||||
ComResponse *Response // 组件响应
|
||||
Data g.Map // 自定KV变量,业务模块根据需要设置,不固定
|
||||
}
|
||||
|
||||
// 通用身份模型
|
||||
type Identity struct {
|
||||
Id int64 `json:"id" description:"会员ID"`
|
||||
Username string `json:"username" description:"用户名"`
|
||||
Realname string `json:"realname" description:"昵称"`
|
||||
Avatar string `json:"avatar" description:"头像"`
|
||||
Email string `json:"email" description:"邮箱"`
|
||||
Mobile string `json:"mobile" description:"手机号码"`
|
||||
VisitCount uint `json:"visit_count" description:"访问次数"`
|
||||
LastTime int `json:"last_time" description:"最后一次登录时间"`
|
||||
LastIp string `json:"last_ip" description:"最后一次登录ip"`
|
||||
Role int64 `json:"role" description:"权限"`
|
||||
Exp int64 `json:"exp" description:"登录有效期截止时间戳"`
|
||||
Expires int64 `json:"expires" description:"登录有效期"`
|
||||
App string `json:"app" description:"登录应用"`
|
||||
}
|
26
hotgo-server/app/model/entity/admin_dept.go
Normal file
26
hotgo-server/app/model/entity/admin_dept.go
Normal file
@ -0,0 +1,26 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
42
hotgo-server/app/model/entity/admin_member.go
Normal file
42
hotgo-server/app/model/entity/admin_member.go
Normal file
@ -0,0 +1,42 @@
|
||||
// =================================================================================
|
||||
// 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:"修改时间"`
|
||||
}
|
11
hotgo-server/app/model/entity/admin_member_post.go
Normal file
11
hotgo-server/app/model/entity/admin_member_post.go
Normal file
@ -0,0 +1,11 @@
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
// AdminMemberPost is the golang structure for table admin_member_post.
|
||||
type AdminMemberPost struct {
|
||||
MemberId int64 `json:"member_id" description:"用户ID"`
|
||||
PostId int64 `json:"post_id" description:"岗位ID"`
|
||||
}
|
11
hotgo-server/app/model/entity/admin_member_role.go
Normal file
11
hotgo-server/app/model/entity/admin_member_role.go
Normal file
@ -0,0 +1,11 @@
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
// AdminMemberRole is the golang structure for table admin_member_role.
|
||||
type AdminMemberRole struct {
|
||||
MemberId int64 `json:"member_id" description:"用户ID"`
|
||||
RoleId int64 `json:"role_id" description:"角色ID"`
|
||||
}
|
33
hotgo-server/app/model/entity/admin_menu.go
Normal file
33
hotgo-server/app/model/entity/admin_menu.go
Normal file
@ -0,0 +1,33 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
32
hotgo-server/app/model/entity/admin_menu_old.go
Normal file
32
hotgo-server/app/model/entity/admin_menu_old.go
Normal file
@ -0,0 +1,32 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
21
hotgo-server/app/model/entity/admin_notice.go
Normal file
21
hotgo-server/app/model/entity/admin_notice.go
Normal file
@ -0,0 +1,21 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
21
hotgo-server/app/model/entity/admin_post.go
Normal file
21
hotgo-server/app/model/entity/admin_post.go
Normal file
@ -0,0 +1,21 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
24
hotgo-server/app/model/entity/admin_role.go
Normal file
24
hotgo-server/app/model/entity/admin_role.go
Normal file
@ -0,0 +1,24 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
11
hotgo-server/app/model/entity/admin_role_dept.go
Normal file
11
hotgo-server/app/model/entity/admin_role_dept.go
Normal file
@ -0,0 +1,11 @@
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
// AdminRoleDept is the golang structure for table admin_role_dept.
|
||||
type AdminRoleDept struct {
|
||||
RoleId int64 `json:"role_id" description:"角色ID"`
|
||||
DeptId int64 `json:"dept_id" description:"部门ID"`
|
||||
}
|
11
hotgo-server/app/model/entity/admin_role_menu.go
Normal file
11
hotgo-server/app/model/entity/admin_role_menu.go
Normal file
@ -0,0 +1,11 @@
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
// AdminRoleMenu is the golang structure for table admin_role_menu.
|
||||
type AdminRoleMenu struct {
|
||||
RoleId int64 `json:"role_id" description:"角色ID"`
|
||||
MenuId int64 `json:"menu_id" description:"菜单ID"`
|
||||
}
|
22
hotgo-server/app/model/entity/sys_config.go
Normal file
22
hotgo-server/app/model/entity/sys_config.go
Normal file
@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
24
hotgo-server/app/model/entity/sys_dict_data.go
Normal file
24
hotgo-server/app/model/entity/sys_dict_data.go
Normal file
@ -0,0 +1,24 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
21
hotgo-server/app/model/entity/sys_dict_type.go
Normal file
21
hotgo-server/app/model/entity/sys_dict_type.go
Normal file
@ -0,0 +1,21 @@
|
||||
// =================================================================================
|
||||
// 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:"更新时间"`
|
||||
}
|
36
hotgo-server/app/model/entity/sys_log.go
Normal file
36
hotgo-server/app/model/entity/sys_log.go
Normal file
@ -0,0 +1,36 @@
|
||||
// =================================================================================
|
||||
// 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:"修改时间"`
|
||||
}
|
21
hotgo-server/app/model/entity/sys_provinces.go
Normal file
21
hotgo-server/app/model/entity/sys_provinces.go
Normal file
@ -0,0 +1,21 @@
|
||||
// =================================================================================
|
||||
// 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:"排序"`
|
||||
}
|
17
hotgo-server/app/model/response.go
Normal file
17
hotgo-server/app/model/response.go
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// @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"`
|
||||
}
|
23
hotgo-server/app/model/tree.go
Normal file
23
hotgo-server/app/model/tree.go
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// @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
|
||||
|
||||
import "github.com/bufanyun/hotgo/app/model/entity"
|
||||
|
||||
// 菜单树
|
||||
type TreeMenu struct {
|
||||
entity.AdminMenu
|
||||
Children []*TreeMenu `json:"children"`
|
||||
}
|
||||
|
||||
// 菜单kl树
|
||||
type LabelTreeMenu struct {
|
||||
entity.AdminMenu
|
||||
Key int64 `json:"key" description:"键名"`
|
||||
Label string `json:"label" description:"键标签"`
|
||||
Children []*LabelTreeMenu `json:"children"`
|
||||
}
|
358
hotgo-server/app/service/adminService/dept_service.go
Normal file
358
hotgo-server/app/service/adminService/dept_service.go
Normal file
@ -0,0 +1,358 @@
|
||||
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
|
||||
}
|
67
hotgo-server/app/service/adminService/member_post_service.go
Normal file
67
hotgo-server/app/service/adminService/member_post_service.go
Normal file
@ -0,0 +1,67 @@
|
||||
package adminService
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"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/frame/g"
|
||||
)
|
||||
|
||||
var MemberPost = new(memberPost)
|
||||
|
||||
type memberPost struct{}
|
||||
|
||||
func (service *memberPost) UpdatePostIds(ctx context.Context, member_id int64, post_ids []int64) (err error) {
|
||||
_, err = dao.AdminMemberPost.Ctx(ctx).
|
||||
Where("member_id", member_id).
|
||||
Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, "删除失败")
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(post_ids); i++ {
|
||||
_, err = dao.AdminMemberPost.Ctx(ctx).
|
||||
Insert(entity.AdminMemberPost{
|
||||
MemberId: member_id,
|
||||
PostId: post_ids[i],
|
||||
})
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, "插入会员岗位失败")
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取指定会员的岗位ids
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param member_id
|
||||
// @Return post_ids
|
||||
// @Return err
|
||||
//
|
||||
func (service *memberPost) GetMemberByIds(ctx context.Context, member_id int64) (post_ids []int64, err error) {
|
||||
|
||||
var list []*entity.AdminMemberPost
|
||||
err = dao.AdminMemberPost.Ctx(ctx).
|
||||
Fields("post_id").
|
||||
Where("member_id", member_id).
|
||||
Scan(&list)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return post_ids, err
|
||||
}
|
||||
|
||||
for i := 0; i < len(list); i++ {
|
||||
post_ids = append(post_ids, list[i].PostId)
|
||||
}
|
||||
|
||||
g.Log().Print(ctx, "post_ids:", post_ids)
|
||||
return post_ids, nil
|
||||
}
|
657
hotgo-server/app/service/adminService/member_service.go
Normal file
657
hotgo-server/app/service/adminService/member_service.go
Normal file
@ -0,0 +1,657 @@
|
||||
//
|
||||
// @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
|
||||
}
|
533
hotgo-server/app/service/adminService/menu_service.go
Normal file
533
hotgo-server/app/service/adminService/menu_service.go
Normal file
@ -0,0 +1,533 @@
|
||||
//
|
||||
// @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
|
||||
}
|
263
hotgo-server/app/service/adminService/notice_service.go
Normal file
263
hotgo-server/app/service/adminService/notice_service.go
Normal file
@ -0,0 +1,263 @@
|
||||
//
|
||||
// @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
|
||||
}
|
274
hotgo-server/app/service/adminService/post_service.go
Normal file
274
hotgo-server/app/service/adminService/post_service.go
Normal file
@ -0,0 +1,274 @@
|
||||
//
|
||||
// @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/service/internal/dao"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
var Post = new(post)
|
||||
|
||||
type post struct{}
|
||||
|
||||
//
|
||||
// @Title 删除
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param req
|
||||
// @Return error
|
||||
//
|
||||
func (service *post) Delete(ctx context.Context, in input.AdminPostDeleteInp) error {
|
||||
|
||||
exist, err := dao.AdminMemberPost.Ctx(ctx).Where("post_id", in.Id).One()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !exist.IsEmpty() {
|
||||
return gerror.New("请先解除该岗位下所有已关联用户关联关系!")
|
||||
}
|
||||
_, err = dao.AdminPost.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 *post) Edit(ctx context.Context, in input.AdminPostEditInp) (err error) {
|
||||
|
||||
if in.Name == "" {
|
||||
err = gerror.New("名称不能为空")
|
||||
return err
|
||||
}
|
||||
if in.Code == "" {
|
||||
err = gerror.New("编码不能为空")
|
||||
return err
|
||||
}
|
||||
|
||||
uniqueName, err := dao.AdminPost.IsUniqueName(ctx, in.Id, in.Name)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !uniqueName {
|
||||
err = gerror.New("名称已存在")
|
||||
return err
|
||||
}
|
||||
|
||||
uniqueCode, err := dao.AdminPost.IsUniqueCode(ctx, in.Id, in.Code)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !uniqueCode {
|
||||
err = gerror.New("编码已存在")
|
||||
return err
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
if in.Id > 0 {
|
||||
_, err = dao.AdminPost.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.AdminPost.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 *post) MaxSort(ctx context.Context, in input.AdminPostMaxSortInp) (*input.AdminPostMaxSortModel, error) {
|
||||
var res input.AdminPostMaxSortModel
|
||||
|
||||
if in.Id > 0 {
|
||||
if err := dao.AdminMenu.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.DictTypeUniqueRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *post) NameUnique(ctx context.Context, in input.AdminPostNameUniqueInp) (*input.AdminPostNameUniqueModel, error) {
|
||||
|
||||
var res input.AdminPostNameUniqueModel
|
||||
isUnique, err := dao.AdminPost.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 *adminForm.DictTypeUniqueRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *post) CodeUnique(ctx context.Context, in input.AdminPostCodeUniqueInp) (*input.AdminPostCodeUniqueModel, error) {
|
||||
|
||||
var res input.AdminPostCodeUniqueModel
|
||||
isUnique, err := dao.AdminPost.IsUniqueCode(ctx, in.Id, in.Code)
|
||||
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.DictTypeViewRes
|
||||
// @Return error
|
||||
//
|
||||
func (service *post) View(ctx context.Context, in input.AdminPostViewInp) (res *input.AdminPostViewModel, err error) {
|
||||
|
||||
if err = dao.AdminPost.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 *post) List(ctx context.Context, in input.AdminPostListInp) (list []*input.AdminPostListModel, totalCount int, err error) {
|
||||
|
||||
mod := dao.AdminPost.Ctx(ctx)
|
||||
|
||||
// 访问路径
|
||||
if in.Name != "" {
|
||||
mod = mod.WhereLike("name", "%"+in.Name+"%")
|
||||
}
|
||||
|
||||
// 模块
|
||||
if in.Code != "" {
|
||||
mod = mod.Where("code", in.Code)
|
||||
}
|
||||
|
||||
// 请求方式
|
||||
if in.Status > 0 {
|
||||
mod = mod.Where("status", in.Status)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取指定用户的第一岗位
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param RoleId
|
||||
// @Return name
|
||||
// @Return err
|
||||
//
|
||||
func (service *post) GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error) {
|
||||
|
||||
// TODO 默认取第一岗位
|
||||
postId, err := dao.AdminMemberPost.Ctx(ctx).
|
||||
Fields("post_id").
|
||||
Where("member_id", memberId).
|
||||
Limit(1).
|
||||
Value()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return name, err
|
||||
}
|
||||
|
||||
val, err := dao.AdminPost.Ctx(ctx).
|
||||
Fields("name").
|
||||
Where("id", postId.Int()).
|
||||
Order("id desc").
|
||||
Value()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return name, err
|
||||
}
|
||||
|
||||
return val.String(), nil
|
||||
}
|
130
hotgo-server/app/service/adminService/role_service.go
Normal file
130
hotgo-server/app/service/adminService/role_service.go
Normal file
@ -0,0 +1,130 @@
|
||||
//
|
||||
// @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/service/internal/dao"
|
||||
"github.com/bufanyun/hotgo/app/service/internal/dto"
|
||||
"github.com/bufanyun/hotgo/app/utils"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user