v2_2
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
type CommonHandler interface {
|
||||
CaptchaHandler() CaptchaHandler
|
||||
UploadHandler() UploadHandler
|
||||
}
|
||||
|
||||
type commonHandler struct {
|
||||
@@ -29,3 +30,7 @@ func NewCommonHandler(conf *config.Config, render tpl.Renderer, biz commonv1.Com
|
||||
func (h *commonHandler) CaptchaHandler() CaptchaHandler {
|
||||
return NewCaptchaHandler(&h.conf.Captcha, h.render, h.biz.CaptchaBiz())
|
||||
}
|
||||
|
||||
func (h *commonHandler) UploadHandler() UploadHandler {
|
||||
return NewUploadHandler(h.render)
|
||||
}
|
||||
|
||||
111
internal/erpserver/handler/common/upload.go
Normal file
111
internal/erpserver/handler/common/upload.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
|
||||
fileutil "management/internal/pkg/file"
|
||||
"management/internal/pkg/tpl"
|
||||
)
|
||||
|
||||
type UploadHandler interface {
|
||||
Img(w http.ResponseWriter, r *http.Request)
|
||||
File(w http.ResponseWriter, r *http.Request)
|
||||
MutilFiles(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type uploadHandler struct {
|
||||
render tpl.Renderer
|
||||
}
|
||||
|
||||
var _ UploadHandler = (*uploadHandler)(nil)
|
||||
|
||||
func NewUploadHandler(render tpl.Renderer) *uploadHandler {
|
||||
return &uploadHandler{
|
||||
render: render,
|
||||
}
|
||||
}
|
||||
|
||||
const maxImageSize = 100 << 20 // 100 MB
|
||||
|
||||
func (h *uploadHandler) Img(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
_, fh, err := r.FormFile("files")
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
path, err := fileutil.UploadFile(fh, fileutil.IMG)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSON(w, tpl.Response{Success: true, Message: "ok", Data: path})
|
||||
}
|
||||
|
||||
func (h *uploadHandler) File(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
_, fh, err := r.FormFile("files")
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
path, err := fileutil.UploadFile(fh, fileutil.ALL)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSON(w, tpl.Response{Success: true, Message: "ok", Data: path})
|
||||
}
|
||||
|
||||
type UploadFileRes struct {
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
func (h *uploadHandler) MutilFiles(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
err := r.ParseMultipartForm(int64(maxImageSize))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
files := r.MultipartForm.File["files"]
|
||||
|
||||
var res []UploadFileRes
|
||||
c := make(chan UploadFileRes, 2)
|
||||
defer close(c)
|
||||
|
||||
for i, file := range files {
|
||||
go func(item *multipart.FileHeader, key int) {
|
||||
ufr := UploadFileRes{Name: item.Filename}
|
||||
|
||||
filePath, err := fileutil.UploadFile(item, fileutil.ALL)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ufr.Path = filePath
|
||||
c <- ufr
|
||||
}(file, i)
|
||||
}
|
||||
|
||||
for {
|
||||
v, ok := <-c
|
||||
if ok {
|
||||
res = append(res, v)
|
||||
}
|
||||
if len(files) == len(res) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
h.render.JSON(w, tpl.Response{Success: true, Message: "ok", Data: res})
|
||||
}
|
||||
58
internal/erpserver/handler/system/audit.go
Normal file
58
internal/erpserver/handler/system/audit.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/biz"
|
||||
"management/internal/pkg/convertor"
|
||||
"management/internal/pkg/tpl"
|
||||
"management/internal/router/manage/util"
|
||||
)
|
||||
|
||||
type AuditHandler interface {
|
||||
List(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type auditHandler struct {
|
||||
render tpl.Renderer
|
||||
biz biz.IBiz
|
||||
}
|
||||
|
||||
var _ AuditHandler = (*auditHandler)(nil)
|
||||
|
||||
func NewAuditHandler(render tpl.Renderer, biz biz.IBiz) *auditHandler {
|
||||
return &auditHandler{
|
||||
render: render,
|
||||
biz: biz,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *auditHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
h.render.HTML(w, r, "audit_log/list.tmpl", nil)
|
||||
case http.MethodPost:
|
||||
var q dto.SearchDto
|
||||
q.SearchTimeBegin, q.SearchTimeEnd = util.DefaultStartTimeAndEndTime(r.PostFormValue("timeBegin"), r.PostFormValue("timeEnd"))
|
||||
q.SearchName = r.PostFormValue("name")
|
||||
q.SearchEmail = r.PostFormValue("email")
|
||||
q.Page = convertor.ConvertInt(r.PostFormValue("page"), 1)
|
||||
q.Rows = convertor.ConvertInt(r.PostFormValue("rows"), 10)
|
||||
res, count, err := h.biz.SystemV1().AuditBiz().List(r.Context(), q)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
data := tpl.ResponseList{
|
||||
Code: 0,
|
||||
Message: "ok",
|
||||
Count: count,
|
||||
Data: res,
|
||||
}
|
||||
h.render.JSON(w, data)
|
||||
default:
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"management/internal/erpserver/biz"
|
||||
"management/internal/pkg/session"
|
||||
"management/internal/pkg/tpl"
|
||||
)
|
||||
|
||||
@@ -23,19 +22,17 @@ type ConfigExpansion interface {
|
||||
|
||||
// configHandler 是 ConfigHandler 接口的实现.
|
||||
type configHandler struct {
|
||||
render tpl.Renderer
|
||||
session session.ISession
|
||||
biz biz.IBiz
|
||||
render tpl.Renderer
|
||||
biz biz.IBiz
|
||||
}
|
||||
|
||||
// 确保 userHandler 实现了 ConfigHandler 接口.
|
||||
var _ ConfigHandler = (*configHandler)(nil)
|
||||
|
||||
func NewConfigHandler(render tpl.Renderer, session session.ISession, biz biz.IBiz) *configHandler {
|
||||
func NewConfigHandler(render tpl.Renderer, biz biz.IBiz) *configHandler {
|
||||
return &configHandler{
|
||||
render: render,
|
||||
session: session,
|
||||
biz: biz,
|
||||
render: render,
|
||||
biz: biz,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,10 @@ func NewDepartmentHandler(render tpl.Renderer, biz biz.IBiz) *departmentHandler
|
||||
}
|
||||
|
||||
func (h *departmentHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodGet {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
h.render.HTML(w, r, "department/list.tmpl", nil)
|
||||
return
|
||||
} else if r.Method == http.MethodPost {
|
||||
case http.MethodPost:
|
||||
var q dto.SearchDto
|
||||
q.SearchStatus = convertor.ConvertInt(r.PostFormValue("status"), 9999)
|
||||
q.SearchParentID = convertor.ConvertInt(r.PostFormValue("parentId"), 0)
|
||||
@@ -62,10 +62,9 @@ func (h *departmentHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
Data: res,
|
||||
}
|
||||
h.render.JSON(w, data)
|
||||
return
|
||||
default:
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
func (h *departmentHandler) Add(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
58
internal/erpserver/handler/system/login_log.go
Normal file
58
internal/erpserver/handler/system/login_log.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/biz"
|
||||
"management/internal/pkg/convertor"
|
||||
"management/internal/pkg/tpl"
|
||||
"management/internal/router/manage/util"
|
||||
)
|
||||
|
||||
type LoginLogHandler interface {
|
||||
List(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type loginLogHandler struct {
|
||||
render tpl.Renderer
|
||||
biz biz.IBiz
|
||||
}
|
||||
|
||||
var _ LoginLogHandler = (*loginLogHandler)(nil)
|
||||
|
||||
func NewLoginLogHandler(render tpl.Renderer, biz biz.IBiz) *loginLogHandler {
|
||||
return &loginLogHandler{
|
||||
render: render,
|
||||
biz: biz,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *loginLogHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
h.render.HTML(w, r, "login_log/list.tmpl", nil)
|
||||
case http.MethodPost:
|
||||
var q dto.SearchDto
|
||||
q.SearchTimeBegin, q.SearchTimeEnd = util.DefaultStartTimeAndEndTime(r.PostFormValue("timeBegin"), r.PostFormValue("timeEnd"))
|
||||
q.SearchName = r.PostFormValue("name")
|
||||
q.SearchEmail = r.PostFormValue("email")
|
||||
q.Page = convertor.ConvertInt(r.PostFormValue("page"), 1)
|
||||
q.Rows = convertor.ConvertInt(r.PostFormValue("rows"), 10)
|
||||
res, count, err := h.biz.SystemV1().LoginLogBiz().List(r.Context(), q)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
data := tpl.ResponseList{
|
||||
Code: 0,
|
||||
Message: "ok",
|
||||
Count: count,
|
||||
Data: res,
|
||||
}
|
||||
h.render.JSON(w, data)
|
||||
default:
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,37 @@ package system
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
db "management/internal/db/sqlc"
|
||||
"management/internal/erpserver/biz"
|
||||
"management/internal/global/know"
|
||||
"management/internal/pkg/convertor"
|
||||
"management/internal/pkg/session"
|
||||
"management/internal/pkg/tpl"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const style = "layui-btn-primary layui-btn-sm"
|
||||
|
||||
type MenuHandler interface {
|
||||
MenuExpansion
|
||||
}
|
||||
|
||||
type MenuExpansion interface {
|
||||
Menus(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
List(w http.ResponseWriter, r *http.Request)
|
||||
Add(w http.ResponseWriter, r *http.Request)
|
||||
AddChildren(w http.ResponseWriter, r *http.Request)
|
||||
Edit(w http.ResponseWriter, r *http.Request)
|
||||
Save(w http.ResponseWriter, r *http.Request)
|
||||
Tree(w http.ResponseWriter, r *http.Request)
|
||||
Refresh(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type menuHandler struct {
|
||||
@@ -51,3 +68,189 @@ func (h *menuHandler) Menus(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
h.render.JSON(w, menus)
|
||||
}
|
||||
|
||||
func (h *menuHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
h.render.HTML(w, r, "menu/list.tmpl", nil)
|
||||
case http.MethodPost:
|
||||
res, err := h.biz.SystemV1().MenuBiz().ListMenuTree(r.Context())
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
data := tpl.ResponseList{
|
||||
Code: 0,
|
||||
Message: "ok",
|
||||
Count: 0,
|
||||
Data: res,
|
||||
}
|
||||
h.render.JSON(w, data)
|
||||
default:
|
||||
h.render.JSONERR(w, "method not allowed")
|
||||
}
|
||||
}
|
||||
|
||||
func (h *menuHandler) Add(w http.ResponseWriter, r *http.Request) {
|
||||
h.render.HTML(w, r, "menu/edit.tmpl", map[string]any{
|
||||
"Item": &db.SysMenu{Style: style, Visible: true, Sort: 6666},
|
||||
})
|
||||
}
|
||||
|
||||
func (h *menuHandler) AddChildren(w http.ResponseWriter, r *http.Request) {
|
||||
vars := r.URL.Query()
|
||||
parentID := convertor.QueryInt[int32](vars, "parentID", 0)
|
||||
vm := &db.SysMenu{ParentID: int32(parentID), Style: style, Visible: true, Sort: 6666}
|
||||
parent, err := h.biz.SystemV1().MenuBiz().Get(r.Context(), parentID)
|
||||
if err == nil {
|
||||
if parent.Type == "node" {
|
||||
vm.Type = "menu"
|
||||
} else if parent.Type == "menu" {
|
||||
vm.Type = "btn"
|
||||
}
|
||||
}
|
||||
h.render.HTML(w, r, "menu/edit.tmpl", map[string]any{
|
||||
"Item": vm,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *menuHandler) Edit(w http.ResponseWriter, r *http.Request) {
|
||||
vars := r.URL.Query()
|
||||
id := convertor.QueryInt[int32](vars, "id", 0)
|
||||
vm := &db.SysMenu{Style: style, Sort: 6666}
|
||||
if id > 0 {
|
||||
vm, _ = h.biz.SystemV1().MenuBiz().Get(r.Context(), id)
|
||||
}
|
||||
h.render.HTML(w, r, "menu/edit.tmpl", map[string]any{
|
||||
"Item": vm,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *menuHandler) Save(w http.ResponseWriter, r *http.Request) {
|
||||
id := convertor.ConvertInt[int32](r.PostFormValue("ID"), 0)
|
||||
name := r.PostFormValue("Name")
|
||||
dispalyName := r.PostFormValue("DisplayName")
|
||||
t := r.PostFormValue("Type")
|
||||
url := r.PostFormValue("Url")
|
||||
if len(url) == 0 {
|
||||
url = uuid.Must(uuid.NewRandom()).String()
|
||||
}
|
||||
avatar := r.PostFormValue("Avatar")
|
||||
style := r.PostFormValue("Style")
|
||||
parentID := convertor.ConvertInt[int32](r.PostFormValue("ParentID"), 0)
|
||||
visible := convertor.ConvertBool(r.PostFormValue("Visible"), false)
|
||||
isList := convertor.ConvertBool(r.PostFormValue("IsList"), false)
|
||||
sort := convertor.ConvertInt[int32](r.PostFormValue("Sort"), 6666)
|
||||
status := convertor.ConvertInt[int32](r.PostFormValue("Status"), 0)
|
||||
|
||||
ctx := r.Context()
|
||||
if len(avatar) > 0 && !strings.Contains(avatar, "layui-icon ") {
|
||||
avatar = "layui-icon " + avatar
|
||||
}
|
||||
|
||||
parentPath := ""
|
||||
if parentID > 0 {
|
||||
parent, err := h.biz.SystemV1().MenuBiz().Get(ctx, parentID)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
parentPath = parent.ParentPath + "," + strconv.Itoa(int(parentID)) + ","
|
||||
parentPath = strings.ReplaceAll(parentPath, ",,", ",")
|
||||
}
|
||||
|
||||
if id == 0 {
|
||||
arg := &db.CreateSysMenuParams{
|
||||
Name: name,
|
||||
DisplayName: dispalyName,
|
||||
Url: url,
|
||||
Type: t,
|
||||
ParentID: int32(parentID),
|
||||
ParentPath: parentPath,
|
||||
Avatar: avatar,
|
||||
Style: style,
|
||||
Visible: visible,
|
||||
IsList: isList,
|
||||
Status: status,
|
||||
Sort: sort,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
_, err := h.biz.SystemV1().MenuBiz().Create(ctx, arg)
|
||||
if err != nil {
|
||||
if db.IsUniqueViolation(err) {
|
||||
h.render.JSONERR(w, "菜单已存在")
|
||||
return
|
||||
}
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "添加成功")
|
||||
} else {
|
||||
res, err := h.biz.SystemV1().MenuBiz().Get(ctx, id)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
arg := &db.UpdateSysMenuParams{
|
||||
ID: res.ID,
|
||||
Name: name,
|
||||
DisplayName: dispalyName,
|
||||
Url: url,
|
||||
Type: t,
|
||||
ParentID: parentID,
|
||||
ParentPath: parentPath,
|
||||
Avatar: avatar,
|
||||
Style: style,
|
||||
Visible: visible,
|
||||
IsList: isList,
|
||||
Status: status,
|
||||
Sort: sort,
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
_, err = h.biz.SystemV1().MenuBiz().Update(ctx, arg)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "更新成功")
|
||||
}
|
||||
}
|
||||
|
||||
func (h *menuHandler) Tree(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
vars := r.URL.Query()
|
||||
if vars.Get("type") == "xmselect" {
|
||||
res, err := h.biz.SystemV1().MenuBiz().XmSelect(ctx, 0)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSON(w, res)
|
||||
return
|
||||
} else {
|
||||
res, err := h.biz.SystemV1().MenuBiz().Tree(ctx, 0)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSON(w, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *menuHandler) Refresh(w http.ResponseWriter, r *http.Request) {
|
||||
err := h.biz.SystemV1().MenuBiz().RefreshMenus(r.Context())
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "刷新成功")
|
||||
}
|
||||
|
||||
249
internal/erpserver/handler/system/role.go
Normal file
249
internal/erpserver/handler/system/role.go
Normal file
@@ -0,0 +1,249 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
db "management/internal/db/sqlc"
|
||||
"management/internal/erpserver/biz"
|
||||
"management/internal/pkg/convertor"
|
||||
"management/internal/pkg/tpl"
|
||||
)
|
||||
|
||||
type RoleHandler interface {
|
||||
List(w http.ResponseWriter, r *http.Request)
|
||||
Add(w http.ResponseWriter, r *http.Request)
|
||||
AddChildren(w http.ResponseWriter, r *http.Request)
|
||||
Edit(w http.ResponseWriter, r *http.Request)
|
||||
Save(w http.ResponseWriter, r *http.Request)
|
||||
Tree(w http.ResponseWriter, r *http.Request)
|
||||
Refresh(w http.ResponseWriter, r *http.Request)
|
||||
RebuildParentPath(w http.ResponseWriter, r *http.Request)
|
||||
RefreshRoleMenus(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
type roleHandler struct {
|
||||
render tpl.Renderer
|
||||
biz biz.IBiz
|
||||
}
|
||||
|
||||
var _ RoleHandler = (*roleHandler)(nil)
|
||||
|
||||
func NewRoleHandler(render tpl.Renderer, biz biz.IBiz) *roleHandler {
|
||||
return &roleHandler{
|
||||
render: render,
|
||||
biz: biz,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *roleHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
h.render.HTML(w, r, "role/list.tmpl", nil)
|
||||
case http.MethodPost:
|
||||
var q dto.SearchDto
|
||||
q.SearchStatus = convertor.ConvertInt(r.PostFormValue("status"), 9999)
|
||||
q.SearchParentID = convertor.ConvertInt(r.PostFormValue("parentId"), 0)
|
||||
q.SearchName = r.PostFormValue("name")
|
||||
q.SearchID = convertor.ConvertInt[int64](r.PostFormValue("id"), 0)
|
||||
q.Page = convertor.ConvertInt(r.PostFormValue("page"), 1)
|
||||
q.Rows = convertor.ConvertInt(r.PostFormValue("rows"), 10)
|
||||
res, count, err := h.biz.SystemV1().RoleBiz().List(r.Context(), q)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
data := tpl.ResponseList{
|
||||
Code: 0,
|
||||
Message: "ok",
|
||||
Count: count,
|
||||
Data: res,
|
||||
}
|
||||
h.render.JSON(w, data)
|
||||
default:
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *roleHandler) Add(w http.ResponseWriter, r *http.Request) {
|
||||
h.render.HTML(w, r, "role/edit.tmpl", map[string]any{
|
||||
"Item": &db.SysRole{Sort: 6666},
|
||||
})
|
||||
}
|
||||
|
||||
func (h *roleHandler) AddChildren(w http.ResponseWriter, r *http.Request) {
|
||||
vars := r.URL.Query()
|
||||
parentID := convertor.QueryInt(vars, "parentID", 0)
|
||||
vm := &db.SysRole{ParentID: int32(parentID), Sort: 6666}
|
||||
h.render.HTML(w, r, "role/edit.tmpl", map[string]any{
|
||||
"Item": vm,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *roleHandler) Edit(w http.ResponseWriter, r *http.Request) {
|
||||
vars := r.URL.Query()
|
||||
id := convertor.QueryInt[int32](vars, "id", 0)
|
||||
vm := &db.SysRole{Sort: 6666}
|
||||
if id > 0 {
|
||||
vm, _ = h.biz.SystemV1().RoleBiz().Get(r.Context(), id)
|
||||
}
|
||||
h.render.HTML(w, r, "role/edit.tmpl", map[string]any{
|
||||
"Item": vm,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *roleHandler) Save(w http.ResponseWriter, r *http.Request) {
|
||||
id := convertor.ConvertInt[int32](r.PostFormValue("ID"), 0)
|
||||
name := r.PostFormValue("Name")
|
||||
parentID := convertor.ConvertInt[int32](r.PostFormValue("ParentID"), 0)
|
||||
displayName := r.PostFormValue("DisplayName")
|
||||
sort := convertor.ConvertInt[int32](r.PostFormValue("Sort"), 6666)
|
||||
status := convertor.ConvertInt[int32](r.PostFormValue("Status"), 0)
|
||||
|
||||
ctx := r.Context()
|
||||
var parent *db.SysRole
|
||||
if parentID > 0 {
|
||||
var err error
|
||||
parent, err = h.biz.SystemV1().RoleBiz().Get(ctx, parentID)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, "父级节点错误")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
parent = &db.SysRole{
|
||||
ID: 0,
|
||||
ParentID: 0,
|
||||
ParentPath: ",0,",
|
||||
}
|
||||
}
|
||||
|
||||
if id == 0 {
|
||||
arg := &db.CreateSysRoleParams{
|
||||
Name: name,
|
||||
DisplayName: displayName,
|
||||
Vip: false,
|
||||
ParentID: parent.ID,
|
||||
ParentPath: fmt.Sprintf("%s,%d,", parent.ParentPath, parent.ID),
|
||||
Status: status,
|
||||
Sort: sort,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
_, err := h.biz.SystemV1().RoleBiz().Create(ctx, arg)
|
||||
if err != nil {
|
||||
if db.IsUniqueViolation(err) {
|
||||
h.render.JSONERR(w, "角色名称已存在")
|
||||
return
|
||||
}
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "添加成功")
|
||||
} else {
|
||||
res, err := h.biz.SystemV1().RoleBiz().Get(ctx, id)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
arg := &db.UpdateSysRoleParams{
|
||||
ID: res.ID,
|
||||
DisplayName: displayName,
|
||||
Status: status,
|
||||
ParentID: parent.ID,
|
||||
ParentPath: fmt.Sprintf("%s,%d,", parent.ParentPath, parent.ID),
|
||||
Sort: sort,
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
_, err = h.biz.SystemV1().RoleBiz().Update(ctx, arg)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "更新成功")
|
||||
}
|
||||
}
|
||||
|
||||
func (h *roleHandler) Tree(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
vars := r.URL.Query()
|
||||
if vars.Get("type") == "xmselect" {
|
||||
res, err := h.biz.SystemV1().RoleBiz().XmSelect(ctx, 0)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSON(w, res)
|
||||
return
|
||||
} else {
|
||||
res, err := h.biz.SystemV1().RoleBiz().Tree(ctx, 0)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSON(w, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *roleHandler) Refresh(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := h.biz.SystemV1().RoleBiz().Refresh(r.Context())
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "刷新成功")
|
||||
}
|
||||
|
||||
func (h *roleHandler) RebuildParentPath(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
err := h.biz.SystemV1().RoleBiz().RebuildParentPath(ctx)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "重建成功")
|
||||
}
|
||||
|
||||
func (h *roleHandler) RefreshRoleMenus(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
// 获取需要刷新的角色ID
|
||||
roleID := convertor.ConvertInt[int32](r.PostFormValue("roleID"), 0)
|
||||
sysRole, err := h.biz.SystemV1().RoleBiz().Get(ctx, int32(roleID))
|
||||
if err != nil || sysRole == nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 刷新角色菜单 (角色所拥有的菜单集合)
|
||||
_, err = h.biz.SystemV1().MenuBiz().SetOwnerListMenuByRoleID(ctx, sysRole.ID)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 刷新角色菜单 (角色所拥有的菜单集合)
|
||||
_, err = h.biz.SystemV1().MenuBiz().SetOwnerMapMenuByRoleID(ctx, sysRole.ID)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 刷新角色菜单树 (pear admin layui 使用的格式)
|
||||
_, err = h.biz.SystemV1().MenuBiz().SetRecursiveSysMenus(ctx, sysRole.ID)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "刷新成功")
|
||||
}
|
||||
@@ -12,8 +12,11 @@ type SystemHandler interface {
|
||||
Home(w http.ResponseWriter, req *http.Request)
|
||||
UserHandler() UserHandler
|
||||
MenuHandler() MenuHandler
|
||||
RoleHandler() RoleHandler
|
||||
DepartmentHandler() DepartmentHandler
|
||||
ConfigHandler() ConfigHandler
|
||||
AuditHandler() AuditHandler
|
||||
LoginLogHandler() LoginLogHandler
|
||||
}
|
||||
|
||||
type systemHandler struct {
|
||||
@@ -44,10 +47,22 @@ func (h *systemHandler) MenuHandler() MenuHandler {
|
||||
return NewMenuHandler(h.render, h.session, h.biz)
|
||||
}
|
||||
|
||||
func (h *systemHandler) RoleHandler() RoleHandler {
|
||||
return NewRoleHandler(h.render, h.biz)
|
||||
}
|
||||
|
||||
func (h *systemHandler) DepartmentHandler() DepartmentHandler {
|
||||
return NewDepartmentHandler(h.render, h.biz)
|
||||
}
|
||||
|
||||
func (h *systemHandler) ConfigHandler() ConfigHandler {
|
||||
return NewConfigHandler(h.render, h.session, h.biz)
|
||||
return NewConfigHandler(h.render, h.biz)
|
||||
}
|
||||
|
||||
func (h *systemHandler) AuditHandler() AuditHandler {
|
||||
return NewAuditHandler(h.render, h.biz)
|
||||
}
|
||||
|
||||
func (h *systemHandler) LoginLogHandler() LoginLogHandler {
|
||||
return NewLoginLogHandler(h.render, h.biz)
|
||||
}
|
||||
|
||||
@@ -4,14 +4,24 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
db "management/internal/db/sqlc"
|
||||
"management/internal/erpserver/biz"
|
||||
"management/internal/erpserver/model/req"
|
||||
"management/internal/global"
|
||||
"management/internal/global/html"
|
||||
"management/internal/global/know"
|
||||
"management/internal/middleware/manage/auth"
|
||||
"management/internal/pkg/convertor"
|
||||
"management/internal/pkg/crypto"
|
||||
"management/internal/pkg/rand"
|
||||
"management/internal/pkg/session"
|
||||
"management/internal/pkg/tpl"
|
||||
"management/internal/router/manage/util"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/zhang2092/browser"
|
||||
)
|
||||
|
||||
@@ -20,6 +30,8 @@ type UserHandler interface {
|
||||
Edit(w http.ResponseWriter, r *http.Request)
|
||||
Save(w http.ResponseWriter, r *http.Request)
|
||||
List(w http.ResponseWriter, r *http.Request)
|
||||
Profile(w http.ResponseWriter, r *http.Request)
|
||||
Tree(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
UserExpansion
|
||||
}
|
||||
@@ -47,17 +59,190 @@ func NewUserHandler(render tpl.Renderer, session session.ISession, biz biz.IBiz)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *userHandler) Add(w http.ResponseWriter, r *http.Request) {}
|
||||
func (h *userHandler) Add(w http.ResponseWriter, r *http.Request) {
|
||||
h.render.HTML(w, r, "user/edit.tmpl", map[string]any{
|
||||
"Item": &db.SysUser{
|
||||
HashedPassword: nil,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (h *userHandler) Edit(w http.ResponseWriter, r *http.Request) {}
|
||||
func (h *userHandler) Edit(w http.ResponseWriter, r *http.Request) {
|
||||
vars := r.URL.Query()
|
||||
id := convertor.QueryInt[int32](vars, "id", 0)
|
||||
sysUser := &db.SysUser{}
|
||||
if id > 0 {
|
||||
ctx := r.Context()
|
||||
if user, err := h.biz.SystemV1().UserBiz().Get(ctx, id); err == nil {
|
||||
user.HashedPassword = nil
|
||||
sysUser = user
|
||||
}
|
||||
}
|
||||
h.render.HTML(w, r, "user/edit.tmpl", map[string]any{
|
||||
"Item": sysUser,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *userHandler) Save(w http.ResponseWriter, r *http.Request) {}
|
||||
func (h *userHandler) Save(w http.ResponseWriter, r *http.Request) {
|
||||
id := convertor.ConvertInt[int32](r.PostFormValue("ID"), 0)
|
||||
email := r.PostFormValue("Email")
|
||||
username := r.PostFormValue("Username")
|
||||
password := r.PostFormValue("Password")
|
||||
changePassword := r.PostFormValue("ChangePassword")
|
||||
gender := convertor.ConvertInt[int32](r.PostFormValue("Gender"), 0)
|
||||
avatar := r.PostFormValue("File")
|
||||
status := convertor.ConvertInt[int32](r.PostFormValue("Status"), 0)
|
||||
|
||||
func (h *userHandler) List(w http.ResponseWriter, r *http.Request) {}
|
||||
ctx := r.Context()
|
||||
departmentID := convertor.ConvertInt[int32](r.PostFormValue("DepartmentID"), 0)
|
||||
var department *db.SysDepartment
|
||||
var err error
|
||||
if departmentID > 0 {
|
||||
department, err = h.biz.SystemV1().DepartmentBiz().Get(ctx, departmentID)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, "部门数据错误")
|
||||
return
|
||||
}
|
||||
}
|
||||
var role *db.SysRole
|
||||
roleID := convertor.ConvertInt[int32](r.PostFormValue("RoleID"), 0)
|
||||
if roleID > 0 {
|
||||
role, err = h.biz.SystemV1().RoleBiz().Get(ctx, roleID)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, "角色数据错误")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if id == 0 {
|
||||
salt, err := rand.String(10)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
hashedPassword, err := crypto.BcryptHashPassword(password + salt)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
initTime, err := time.ParseInLocation(time.DateTime, "0001-01-01 00:00:00", time.Local)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
arg := &db.CreateSysUserParams{
|
||||
Uuid: uuid.Must(uuid.NewV7()),
|
||||
Email: email,
|
||||
Username: username,
|
||||
HashedPassword: hashedPassword,
|
||||
Salt: salt,
|
||||
Avatar: avatar,
|
||||
Gender: gender,
|
||||
DepartmentID: department.ID,
|
||||
RoleID: role.ID,
|
||||
Status: status,
|
||||
ChangePasswordAt: initTime,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
_, err = h.biz.SystemV1().UserBiz().Create(ctx, arg)
|
||||
if err != nil {
|
||||
if db.IsUniqueViolation(err) {
|
||||
h.render.JSONERR(w, "数据已存在")
|
||||
return
|
||||
}
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "添加成功")
|
||||
} else {
|
||||
res, err := h.biz.SystemV1().UserBiz().Get(ctx, id)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
arg := &db.UpdateSysUserParams{
|
||||
ID: res.ID,
|
||||
Username: username,
|
||||
HashedPassword: res.HashedPassword,
|
||||
Avatar: avatar,
|
||||
Gender: int32(gender),
|
||||
DepartmentID: department.ID,
|
||||
RoleID: role.ID,
|
||||
Status: int32(status),
|
||||
ChangePasswordAt: res.ChangePasswordAt,
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
if changePassword == "on" {
|
||||
hashedPassword, err := crypto.BcryptHashPassword(password + res.Salt)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
arg.HashedPassword = hashedPassword
|
||||
arg.ChangePasswordAt = time.Now()
|
||||
}
|
||||
_, err = h.biz.SystemV1().UserBiz().Update(ctx, arg)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "更新成功")
|
||||
}
|
||||
}
|
||||
|
||||
func (h *userHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
h.render.HTML(w, r, "user/list.tmpl", map[string]any{
|
||||
"Statuses": html.NewSelectControls(global.SearchStatuses, 0),
|
||||
})
|
||||
case http.MethodPost:
|
||||
var q dto.SearchDto
|
||||
q.SearchStatus = util.ConvertInt(r.PostFormValue("status"), 9999)
|
||||
q.SearchName = r.PostFormValue("name")
|
||||
q.SearchEmail = r.PostFormValue("email")
|
||||
q.SearchID = convertor.ConvertInt[int64](r.PostFormValue("id"), 0)
|
||||
q.Page = util.ConvertInt(r.PostFormValue("page"), 1)
|
||||
q.Rows = util.ConvertInt(r.PostFormValue("rows"), 10)
|
||||
res, count, err := h.biz.SystemV1().UserBiz().List(r.Context(), q)
|
||||
if err != nil {
|
||||
h.render.JSONERR(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
data := tpl.ResponseList{
|
||||
Code: 0,
|
||||
Message: "ok",
|
||||
Count: count,
|
||||
Data: res,
|
||||
}
|
||||
h.render.JSON(w, data)
|
||||
default:
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *userHandler) Profile(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
user := auth.AuthUser(ctx)
|
||||
vm, _ := h.biz.SystemV1().UserBiz().Get(ctx, user.ID)
|
||||
h.render.HTML(w, r, "user/profile.tmpl", map[string]any{
|
||||
"Item": vm,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *userHandler) Tree(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
func (h *userHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
if r.Method == http.MethodGet {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
var user dto.AuthorizeUser
|
||||
u := h.session.GetBytes(ctx, know.StoreName)
|
||||
if err := json.Unmarshal(u, &user); err == nil {
|
||||
@@ -68,11 +253,9 @@ func (h *userHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
h.session.Destroy(ctx)
|
||||
h.render.HTML(w, r, "oauth/login.tmpl", nil)
|
||||
return
|
||||
} else if r.Method == http.MethodPost {
|
||||
case http.MethodPost:
|
||||
req := &req.Login{
|
||||
Email: strings.TrimSpace(r.PostFormValue("email")),
|
||||
Password: strings.TrimSpace(r.PostFormValue("password")),
|
||||
@@ -115,10 +298,9 @@ func (h *userHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
h.render.JSONOK(w, "login successful")
|
||||
return
|
||||
default:
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
func (h *userHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user