statics file change

This commit is contained in:
2025-06-16 16:17:18 +08:00
parent 90d1ef301d
commit a8bc73ae99
800 changed files with 105 additions and 4877 deletions

View File

@@ -5,7 +5,6 @@ import (
"management/internal/erpserver/handler"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/render"
)
type CaptchaHandler struct {
@@ -44,5 +43,5 @@ func (h *CaptchaHandler) Captcha(w http.ResponseWriter, _ *http.Request) {
CaptchaLength: h.Config.Captcha.KeyLong,
OpenCaptcha: h.Config.Captcha.OpenCaptcha,
}
h.JSON(w, render.Response{Success: true, Message: "ok", Data: rsp})
h.JSONObj(w, "ok", rsp)
}

View File

@@ -2,13 +2,13 @@ package handler
import (
"context"
"encoding/json"
"fmt"
"net/http"
"management/internal/erpserver/model/dto"
"management/internal/pkg/config"
"management/internal/pkg/know"
"management/internal/pkg/render"
"management/internal/pkg/session"
"github.com/a-h/templ"
@@ -25,20 +25,17 @@ type Handler struct {
Log *logger.Logger
session session.Manager
render render.Render
}
func NewHandler(
config *config.Config,
log *logger.Logger,
session session.Manager,
render render.Render,
) *Handler {
return &Handler{
Config: config,
Log: log,
session: session,
render: render,
}
}
@@ -73,17 +70,56 @@ func (h *Handler) Render(ctx context.Context, w http.ResponseWriter, t templ.Com
}
func (h *Handler) JSON(w http.ResponseWriter, data any) {
h.render.JSON(w, data)
respond(w, data)
}
func (h *Handler) JSONObj(w http.ResponseWriter, message string, data any) {
h.render.JSONObj(w, message, data)
respond(w, Response{Success: true, Message: message, Data: data})
}
func (h *Handler) JSONOk(w http.ResponseWriter, message string) {
h.render.JSONOk(w, message)
respond(w, Response{Success: true, Message: message})
}
func (h *Handler) JSONErr(w http.ResponseWriter, message string) {
h.render.JSONErr(w, message)
respond(w, Response{Success: false, Message: message})
}
type Response struct {
Success bool `json:"success"`
Message string `json:"msg"`
Data any `json:"data"`
}
type ResponseTree struct {
Status ResponseTreeStatus `json:"status"`
Data any `json:"data"`
}
type ResponseTreeStatus struct {
Code int `json:"code"`
Message string `json:"message"`
}
type ResponseList struct {
Code int `json:"code"`
Message string `json:"msg"`
Count int64 `json:"count"`
Data any `json:"data"`
}
func respond(w http.ResponseWriter, data any) {
v, err := json.Marshal(data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusOK)
_, err = w.Write(v)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

View File

@@ -8,7 +8,6 @@ import (
v1 "management/internal/erpserver/service/v1"
"management/internal/erpserver/templ/system/auditlog"
"management/internal/pkg/convertor"
"management/internal/pkg/render"
)
type AuditHandler struct {
@@ -41,7 +40,7 @@ func (h *AuditHandler) List(w http.ResponseWriter, r *http.Request) {
return
}
data := render.ResponseList{
data := handler.ResponseList{
Code: 0,
Message: "ok",
Count: count,

View File

@@ -13,7 +13,6 @@ import (
"management/internal/erpserver/templ/system/config"
"management/internal/pkg/convertor"
"management/internal/pkg/database"
"management/internal/pkg/render"
)
type ConfigHandler struct {
@@ -46,7 +45,7 @@ func (h *ConfigHandler) List(w http.ResponseWriter, r *http.Request) {
return
}
data := render.ResponseList{
data := handler.ResponseList{
Code: 0,
Message: "ok",
Count: count,

View File

@@ -11,7 +11,6 @@ import (
"management/internal/erpserver/templ/system/department"
"management/internal/pkg/binding"
"management/internal/pkg/convertor"
"management/internal/pkg/render"
)
type DepartmentHandler struct {
@@ -46,7 +45,7 @@ func (h *DepartmentHandler) List(w http.ResponseWriter, r *http.Request) {
return
}
data := render.ResponseList{
data := handler.ResponseList{
Code: 0,
Message: "ok",
Count: count,

View File

@@ -8,7 +8,6 @@ import (
v1 "management/internal/erpserver/service/v1"
"management/internal/erpserver/templ/system/loginlog"
"management/internal/pkg/convertor"
"management/internal/pkg/render"
)
type LoginLogHandler struct {
@@ -40,7 +39,7 @@ func (h *LoginLogHandler) List(w http.ResponseWriter, r *http.Request) {
return
}
data := render.ResponseList{
data := handler.ResponseList{
Code: 0,
Message: "ok",
Count: count,

View File

@@ -12,7 +12,6 @@ import (
"management/internal/erpserver/templ/system/menu"
"management/internal/pkg/convertor"
"management/internal/pkg/database"
"management/internal/pkg/render"
"github.com/google/uuid"
)
@@ -55,7 +54,7 @@ func (h *MenuHandler) List(w http.ResponseWriter, r *http.Request) {
return
}
data := render.ResponseList{
data := handler.ResponseList{
Code: 0,
Message: "ok",
Count: 0,

View File

@@ -13,7 +13,6 @@ import (
"management/internal/erpserver/templ/system/role"
"management/internal/pkg/binding"
"management/internal/pkg/convertor"
"management/internal/pkg/render"
)
type RoleHandler struct {
@@ -50,7 +49,7 @@ func (h *RoleHandler) List(w http.ResponseWriter, r *http.Request) {
return
}
data := render.ResponseList{
data := handler.ResponseList{
Code: 0,
Message: "ok",
Count: count,

View File

@@ -14,7 +14,6 @@ import (
"management/internal/erpserver/templ/system/user"
"management/internal/pkg/binding"
"management/internal/pkg/convertor"
"management/internal/pkg/render"
)
type UserHandler struct {
@@ -120,7 +119,7 @@ func (h *UserHandler) List(w http.ResponseWriter, r *http.Request) {
return
}
data := render.ResponseList{
data := handler.ResponseList{
Code: 0,
Message: "ok",
Count: count,

View File

@@ -3,12 +3,12 @@ package erpserver
import (
"net/http"
"management/assets"
"management/internal/erpserver/handler/common"
"management/internal/erpserver/handler/system"
v1 "management/internal/erpserver/service/v1"
mi "management/internal/pkg/mid"
"management/internal/pkg/session"
static "management/web/statics"
"github.com/drhin/logger"
"github.com/go-chi/chi/v5"
@@ -38,9 +38,8 @@ func NewHTTPServer(
// r.Use(mid.Logger)
r.Use(middleware.Recoverer)
//staticServer := http.FileServer(http.Dir("./web/statics/"))
staticServer := http.FileServer(http.FS(static.StaticFS))
r.Handle("/statics/*", http.StripPrefix("/statics", staticServer))
staticServer := http.FileServer(http.FS(assets.FS))
r.Handle("/assets/*", http.StripPrefix("/assets", staticServer))
uploadServer := http.FileServer(http.Dir("./public/"))
r.Handle("/public/*", http.StripPrefix("/public", uploadServer))

View File

@@ -53,7 +53,7 @@ func (s *userRepository) Initialize(ctx context.Context, departId, roleId int32)
Username: "kenneth",
HashedPassword: hashedPassword,
Salt: salt,
Avatar: "/statics/admin/images/avatar.jpg",
Avatar: "/assets/admin/images/avatar.jpg",
Gender: 1,
DepartmentID: departId,
RoleID: roleId,

View File

@@ -119,12 +119,8 @@ func (s *departmentService) List(ctx context.Context, q dto.SearchDto) ([]*syste
}
func (s *departmentService) RefreshCache(ctx context.Context) error {
var res []*system.Department
key := know.GetManageKey(ctx, know.AllDepartments)
err := util.GetOrSetCache(ctx, s.Redis, key, util.GetCacheExpire(), func() (any, error) {
return s.All(ctx)
}, &res)
return err
return s.Redis.Del(ctx, key)
}
func (s *departmentService) RebuildParentPath(ctx context.Context) error {

View File

@@ -191,12 +191,8 @@ func (s *menuService) SetRoleMenu(ctx context.Context, roleID int32, rms []*syst
}
func (s *menuService) RefreshCache(ctx context.Context) error {
var res []*system.Menu
key := know.GetManageKey(ctx, know.AllMenus)
getData := func() (any, error) {
return s.repo.All(ctx)
}
return util.GetOrSetCache(ctx, s.Redis, key, util.GetCacheExpire(), getData, &res)
return s.Redis.Del(ctx, key)
}
func (s *menuService) RebuildParentPath(ctx context.Context) error {

View File

@@ -122,14 +122,8 @@ func (s *roleService) List(ctx context.Context, q dto.SearchDto) ([]*system.Role
}
func (s *roleService) RefreshCache(ctx context.Context) error {
var res []*system.Role
key := know.GetManageKey(ctx, know.AllRoles)
if err := s.Redis.Del(ctx, key); err != nil {
return err
}
return util.GetOrSetCache(ctx, s.Redis, key, util.GetCacheExpire(), func() (any, error) {
return s.repo.All(ctx)
}, &res)
return s.Redis.Del(ctx, key)
}
func (s *roleService) RebuildParentPath(ctx context.Context) error {

View File

@@ -14,23 +14,23 @@ templ Login(ctx context.Context) {
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>登录</title>
<link rel="icon" type="image/x-icon" href="/statics/favicon.ico">
<link rel="stylesheet" href="/statics/component/pear/css/pear.css" />
<link rel="stylesheet" href="/statics/admin/css/other/login.css" />
<link rel="stylesheet" href="/statics/admin/css/variables.css" />
<link rel="icon" type="image/x-icon" href="/assets/favicon.ico">
<link rel="stylesheet" href="/assets/component/pear/css/pear.css" />
<link rel="stylesheet" href="/assets/admin/css/other/login.css" />
<link rel="stylesheet" href="/assets/admin/css/variables.css" />
</head>
<body>
<div class="login-page" style="background-image: url('/statics/admin/images/background.svg')">
<div class="login-page" style="background-image: url('/assets/admin/images/background.svg')">
<div class="layui-row">
<div class="layui-col-sm6 login-bg layui-hide-xs">
<img class="login-bg-img" src="/statics/admin/images/banner.png" alt="" />
<img class="login-bg-img" src="/assets/admin/images/banner.png" alt="" />
</div>
<div class="layui-col-sm6 layui-col-xs12 login-form">
<div class="layui-form">
<div class="form-center">
<div class="form-center-box">
<div class="top-log-title">
<img class="top-log" src="/statics/favicon.ico" alt="" />
<img class="top-log" src="/assets/favicon.ico" alt="" />
<span>Pear Admin 4.0</span>
</div>
<div class="top-desc">
@@ -82,8 +82,8 @@ templ Login(ctx context.Context) {
</div>
</div>
<!-- 资 源 引 入 -->
<script src="/statics/component/layui/layui.js"></script>
<script src="/statics/component/pear/pear.js"></script>
<script src="/assets/component/layui/layui.js"></script>
<script src="/assets/component/pear/pear.js"></script>
<script>
layui.use(['jquery', 'form', 'button', 'popup'], function () {
var $ = layui.jquery;

View File

@@ -36,7 +36,7 @@ func Login(ctx context.Context) templ.Component {
}
ctx = templ.ClearChildren(ctx)
token := mid.GetCsrfToken(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\"><title>登录</title><link rel=\"icon\" type=\"image/x-icon\" href=\"/statics/favicon.ico\"><link rel=\"stylesheet\" href=\"/statics/component/pear/css/pear.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/other/login.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/variables.css\"></head><body><div class=\"login-page\" style=\"background-image: url('/statics/admin/images/background.svg')\"><div class=\"layui-row\"><div class=\"layui-col-sm6 login-bg layui-hide-xs\"><img class=\"login-bg-img\" src=\"/statics/admin/images/banner.png\" alt=\"\"></div><div class=\"layui-col-sm6 layui-col-xs12 login-form\"><div class=\"layui-form\"><div class=\"form-center\"><div class=\"form-center-box\"><div class=\"top-log-title\"><img class=\"top-log\" src=\"/statics/favicon.ico\" alt=\"\"> <span>Pear Admin 4.0</span></div><div class=\"top-desc\">以 超 乎 想 象 的 速 度 构 建 内 部 工 具</div><div style=\"margin-top: 30px;\"><div class=\"layui-form-item\"><div class=\"layui-input-wrap\"><div class=\"layui-input-prefix\"><i class=\"layui-icon layui-icon-username\"></i></div><input placeholder=\"邮 箱 \" name=\"email\" type=\"email\" value=\"1185230223@qq.com\" lay-verify=\"required\" hover class=\"layui-input\"></div></div><div class=\"layui-form-item\"><div class=\"layui-input-wrap\"><div class=\"layui-input-prefix\"><i class=\"layui-icon layui-icon-password\"></i></div><input placeholder=\"密 码 \" name=\"password\" type=\"password\" value=\"secret\" lay-verify=\"required\" hover class=\"layui-input\"></div></div><div class=\"tab-log-verification\"><div class=\"verification-text\"><div class=\"layui-input-wrap\"><div class=\"layui-input-prefix\"><i class=\"layui-icon layui-icon-auz\"></i></div><input name=\"captcha\" type=\"text\" lay-verify=\"required\" value=\"\" placeholder=\"验证码\" autocomplete=\"off\" class=\"layui-input\"> <input type=\"hidden\" id=\"captcha_id\" name=\"captcha_id\"></div></div><img id=\"captcha\" src=\"/captcha\" class=\"verification-img\" style=\"cursor: pointer;\"></div><div class=\"login-btn\" style=\"margin-top: 15px;\"><button type=\"button\" lay-submit lay-filter=\"login\" class=\"layui-btn pear-btn-success login\">登录</button></div></div></div></div></div></div></div></div><!-- 资 源 引 入 --><script src=\"/statics/component/layui/layui.js\"></script><script src=\"/statics/component/pear/pear.js\"></script><script>\n \t layui.use(['jquery', 'form', 'button', 'popup'], function () {\n \t\t\tvar $ = layui.jquery;\n \t\t\tvar form = layui.form;\n \t\t\tvar button = layui.button;\n \t\t\tvar popup = layui.popup;\n\n \t\t\t$(function () {\n \t\t\t\t$('#captcha').click();\n \t\t\t})\n\n \t\t\t$('#captcha').click(function () {\n \t\t\t\t$.ajax({\n \t\t\t\t\turl: '/captcha',\n \t\t\t\t\tmethod: 'get',\n \t\t\t\t\tsuccess: function (j) {\n \t\t\t\t\t\tif (j.success) {\n \t\t\t\t\t\t\t$('#captcha').attr('src', j.data.pic_path);\n \t\t\t\t\t\t\t$('#captcha_id').val(j.data.captcha_id);\n \t\t\t\t\t\t} else {\n \t\t\t\t\t\t\tconsole.log(j)\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n \t\t\t\t});\n \t\t\t});\n\n \t\t\t// 登 录 提 交\n \t\t\tform.on('submit(login)', function (data) {\n \t\t\t\tlet loading = button.load({\n \t\t\t\t\telem: '.login',\n \t\t\t\t});\n\n \t\t\t\tdata.field.csrf_token = '")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\"><title>登录</title><link rel=\"icon\" type=\"image/x-icon\" href=\"/assets/favicon.ico\"><link rel=\"stylesheet\" href=\"/assets/component/pear/css/pear.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/other/login.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/variables.css\"></head><body><div class=\"login-page\" style=\"background-image: url('/assets/admin/images/background.svg')\"><div class=\"layui-row\"><div class=\"layui-col-sm6 login-bg layui-hide-xs\"><img class=\"login-bg-img\" src=\"/assets/admin/images/banner.png\" alt=\"\"></div><div class=\"layui-col-sm6 layui-col-xs12 login-form\"><div class=\"layui-form\"><div class=\"form-center\"><div class=\"form-center-box\"><div class=\"top-log-title\"><img class=\"top-log\" src=\"/assets/favicon.ico\" alt=\"\"> <span>Pear Admin 4.0</span></div><div class=\"top-desc\">以 超 乎 想 象 的 速 度 构 建 内 部 工 具</div><div style=\"margin-top: 30px;\"><div class=\"layui-form-item\"><div class=\"layui-input-wrap\"><div class=\"layui-input-prefix\"><i class=\"layui-icon layui-icon-username\"></i></div><input placeholder=\"邮 箱 \" name=\"email\" type=\"email\" value=\"1185230223@qq.com\" lay-verify=\"required\" hover class=\"layui-input\"></div></div><div class=\"layui-form-item\"><div class=\"layui-input-wrap\"><div class=\"layui-input-prefix\"><i class=\"layui-icon layui-icon-password\"></i></div><input placeholder=\"密 码 \" name=\"password\" type=\"password\" value=\"secret\" lay-verify=\"required\" hover class=\"layui-input\"></div></div><div class=\"tab-log-verification\"><div class=\"verification-text\"><div class=\"layui-input-wrap\"><div class=\"layui-input-prefix\"><i class=\"layui-icon layui-icon-auz\"></i></div><input name=\"captcha\" type=\"text\" lay-verify=\"required\" value=\"\" placeholder=\"验证码\" autocomplete=\"off\" class=\"layui-input\"> <input type=\"hidden\" id=\"captcha_id\" name=\"captcha_id\"></div></div><img id=\"captcha\" src=\"/captcha\" class=\"verification-img\" style=\"cursor: pointer;\"></div><div class=\"login-btn\" style=\"margin-top: 15px;\"><button type=\"button\" lay-submit lay-filter=\"login\" class=\"layui-btn pear-btn-success login\">登录</button></div></div></div></div></div></div></div></div><!-- 资 源 引 入 --><script src=\"/assets/component/layui/layui.js\"></script><script src=\"/assets/component/pear/pear.js\"></script><script>\n \t layui.use(['jquery', 'form', 'button', 'popup'], function () {\n \t\t\tvar $ = layui.jquery;\n \t\t\tvar form = layui.form;\n \t\t\tvar button = layui.button;\n \t\t\tvar popup = layui.popup;\n\n \t\t\t$(function () {\n \t\t\t\t$('#captcha').click();\n \t\t\t})\n\n \t\t\t$('#captcha').click(function () {\n \t\t\t\t$.ajax({\n \t\t\t\t\turl: '/captcha',\n \t\t\t\t\tmethod: 'get',\n \t\t\t\t\tsuccess: function (j) {\n \t\t\t\t\t\tif (j.success) {\n \t\t\t\t\t\t\t$('#captcha').attr('src', j.data.pic_path);\n \t\t\t\t\t\t\t$('#captcha_id').val(j.data.captcha_id);\n \t\t\t\t\t\t} else {\n \t\t\t\t\t\t\tconsole.log(j)\n \t\t\t\t\t\t}\n \t\t\t\t\t}\n \t\t\t\t});\n \t\t\t});\n\n \t\t\t// 登 录 提 交\n \t\t\tform.on('submit(login)', function (data) {\n \t\t\t\tlet loading = button.load({\n \t\t\t\t\telem: '.login',\n \t\t\t\t});\n\n \t\t\t\tdata.field.csrf_token = '")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@@ -14,23 +14,23 @@ templ Base(ctx context.Context, style, script tpl.Component) {
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>component</title>
<link rel="icon" type="image/x-icon" href="/statics/favicon.ico">
<link rel="stylesheet" href="/statics/component/pear/css/pear.css" />
<link rel="stylesheet" href="/statics/admin/css/admin.css" />
<link rel="stylesheet" href="/statics/admin/css/admin.dark.css" />
<link rel="stylesheet" href="/statics/admin/css/variables.css" />
<link rel="stylesheet" href="/statics/admin/css/reset.css" />
<link rel="stylesheet" href="/statics/admin/css/style.css" />
<link rel="icon" type="image/x-icon" href="/assets/favicon.ico">
<link rel="stylesheet" href="/assets/component/pear/css/pear.css" />
<link rel="stylesheet" href="/assets/admin/css/admin.css" />
<link rel="stylesheet" href="/assets/admin/css/admin.dark.css" />
<link rel="stylesheet" href="/assets/admin/css/variables.css" />
<link rel="stylesheet" href="/assets/admin/css/reset.css" />
<link rel="stylesheet" href="/assets/admin/css/style.css" />
@style
</head>
<body class="pear-container">
{ children... }
<script src="/statics/component/layui/layui.js"></script>
<script src="/statics/component/pear/pear.js"></script>
<script src="/statics/component/pear/help.js"></script>
<script src="/statics/js/function/public.js"></script>
<script src="/statics/js/upload.js"></script>
<script src="/assets/component/layui/layui.js"></script>
<script src="/assets/component/pear/pear.js"></script>
<script src="/assets/component/pear/help.js"></script>
<script src="/assets/js/function/public.js"></script>
<script src="/assets/js/upload.js"></script>
<script>
layui.use(['admin', 'jquery', 'popup', 'drawer'], function () {
var $ = layui.jquery;

View File

@@ -35,7 +35,7 @@ func Base(ctx context.Context, style, script tpl.Component) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\"><title>component</title><link rel=\"icon\" type=\"image/x-icon\" href=\"/statics/favicon.ico\"><link rel=\"stylesheet\" href=\"/statics/component/pear/css/pear.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/admin.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/admin.dark.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/variables.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/reset.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/style.css\">")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\"><title>component</title><link rel=\"icon\" type=\"image/x-icon\" href=\"/assets/favicon.ico\"><link rel=\"stylesheet\" href=\"/assets/component/pear/css/pear.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/admin.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/admin.dark.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/variables.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/reset.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/style.css\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -51,7 +51,7 @@ func Base(ctx context.Context, style, script tpl.Component) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<script src=\"/statics/component/layui/layui.js\"></script><script src=\"/statics/component/pear/pear.js\"></script><script src=\"/statics/component/pear/help.js\"></script><script src=\"/statics/js/function/public.js\"></script><script src=\"/statics/js/upload.js\"></script><script>\n layui.use(['admin', 'jquery', 'popup', 'drawer'], function () {\n var $ = layui.jquery;\n var admin = layui.admin;\n var popup = layui.popup;\n\n // 读取 localStorage 主题颜色值,初始化 iframe 主题\n darkTheme();\n themeColor();\n\n // iframe 页监听 localStorage [pear 框架主题颜色] 变化。发生变化,同步更新 iframe 显示效果\n window.addEventListener('storage', function (event) {\n if (event.key === 'dark') {\n darkTheme();\n }\n if (event.key === 'theme-color') {\n themeColor();\n }\n });\n\n // 夜间模式切换\n function darkTheme() {\n var $pearAdmin = $(\".pear-admin\"); // 主体\n var $layuiCard = $('.layui-card'); // 编辑页\n\n if (localStorage.getItem('dark') === 'true') {\n $pearAdmin.addClass(\"pear-admin-dark\");\n $layuiCard.addClass('layui-card-dark');\n } else {\n $pearAdmin.removeClass(\"pear-admin-dark\");\n $layuiCard.removeClass('layui-card-dark');\n }\n }\n\n // 主题颜色切换\n function themeColor() {\n const variableKey = \"--global-primary-color\";\n const variableVal = localStorage.getItem(\"theme-color-color\");\n document.documentElement.style.setProperty(variableKey, variableVal);\n }\n })\n </script>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<script src=\"/assets/component/layui/layui.js\"></script><script src=\"/assets/component/pear/pear.js\"></script><script src=\"/assets/component/pear/help.js\"></script><script src=\"/assets/js/function/public.js\"></script><script src=\"/assets/js/upload.js\"></script><script>\n layui.use(['admin', 'jquery', 'popup', 'drawer'], function () {\n var $ = layui.jquery;\n var admin = layui.admin;\n var popup = layui.popup;\n\n // 读取 localStorage 主题颜色值,初始化 iframe 主题\n darkTheme();\n themeColor();\n\n // iframe 页监听 localStorage [pear 框架主题颜色] 变化。发生变化,同步更新 iframe 显示效果\n window.addEventListener('storage', function (event) {\n if (event.key === 'dark') {\n darkTheme();\n }\n if (event.key === 'theme-color') {\n themeColor();\n }\n });\n\n // 夜间模式切换\n function darkTheme() {\n var $pearAdmin = $(\".pear-admin\"); // 主体\n var $layuiCard = $('.layui-card'); // 编辑页\n\n if (localStorage.getItem('dark') === 'true') {\n $pearAdmin.addClass(\"pear-admin-dark\");\n $layuiCard.addClass('layui-card-dark');\n } else {\n $pearAdmin.removeClass(\"pear-admin-dark\");\n $layuiCard.removeClass('layui-card-dark');\n }\n }\n\n // 主题颜色切换\n function themeColor() {\n const variableKey = \"--global-primary-color\";\n const variableVal = localStorage.getItem(\"theme-color-color\");\n document.documentElement.style.setProperty(variableKey, variableVal);\n }\n })\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@@ -14,13 +14,13 @@ templ Home(ctx context.Context) {
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>管理后台</title>
<link rel="icon" type="image/x-icon" href="/statics/favicon.ico">
<link rel="stylesheet" href="/statics/component/pear/css/pear.css" />
<link rel="stylesheet" href="/statics/admin/css/admin.css" />
<link rel="stylesheet" href="/statics/admin/css/admin.dark.css" />
<link rel="stylesheet" href="/statics/admin/css/variables.css" />
<link rel="stylesheet" href="/statics/admin/css/reset.css" />
<link rel="stylesheet" href="/statics/admin/css/style.css" />
<link rel="icon" type="image/x-icon" href="/assets/favicon.ico">
<link rel="stylesheet" href="/assets/component/pear/css/pear.css" />
<link rel="stylesheet" href="/assets/admin/css/admin.css" />
<link rel="stylesheet" href="/assets/admin/css/admin.dark.css" />
<link rel="stylesheet" href="/assets/admin/css/variables.css" />
<link rel="stylesheet" href="/assets/admin/css/reset.css" />
<link rel="stylesheet" href="/assets/admin/css/style.css" />
</head>
<body class="layui-layout-body pear-admin">
@@ -108,8 +108,8 @@ templ Home(ctx context.Context) {
<a href="#" class="layui-icon layui-icon-shrink-right"></a>
</div>
<script src="/statics/component/layui/layui.js"></script>
<script src="/statics/component/pear/pear.js"></script>
<script src="/assets/component/layui/layui.js"></script>
<script src="/assets/component/pear/pear.js"></script>
<script>
layui.use(['admin', 'jquery', 'popup', 'drawer'], function () {
const $ = layui.jquery;

View File

@@ -35,7 +35,7 @@ func Home(ctx context.Context) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\"><title>管理后台</title><link rel=\"icon\" type=\"image/x-icon\" href=\"/statics/favicon.ico\"><link rel=\"stylesheet\" href=\"/statics/component/pear/css/pear.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/admin.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/admin.dark.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/variables.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/reset.css\"><link rel=\"stylesheet\" href=\"/statics/admin/css/style.css\"></head><body class=\"layui-layout-body pear-admin\"><!-- 布 局 框 架 --><div class=\"layui-layout layui-layout-admin\"><!-- 顶 部 样 式 --><div class=\"layui-header\"><!-- 菜 单 顶 部 --><div class=\"layui-logo\"><!-- 图 标 --><img class=\"logo\" alt=\"\" src=\"\"><!-- 标 题 --><span class=\"title\"></span></div><!-- 顶 部 左 侧 功 能 --><ul class=\"layui-nav layui-layout-left\"><li class=\"collapse layui-nav-item\"><a href=\"#\" class=\"layui-icon layui-icon-shrink-right\"></a></li><li class=\"refresh layui-nav-item\"><a href=\"#\" class=\"layui-icon layui-icon-refresh-1\"></a></li></ul><!-- 多 系 统 菜 单 --><div id=\"control\" class=\"layui-layout-control\"></div><!-- 顶 部 右 侧 菜 单 --><ul class=\"layui-nav layui-layout-right\"><!-- <li class=\"layui-nav-item layui-hide-xs\"><a href=\"#\"\n class=\"menuSearch layui-icon layui-icon-search\"></a></li>\n <li class=\"layui-nav-item layui-hide-xs message\"></li> --><li class=\"layui-nav-item layui-hide-xs\"><a href=\"#\" class=\"fullScreen layui-icon layui-icon-screen-full\"></a></li><li class=\"layui-nav-item user\"><!-- 头 像 --><a class=\"layui-icon layui-icon-username\" href=\"javascript:;\"></a><!-- 功 能 菜 单 --><dl class=\"layui-nav-child\">")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\"><title>管理后台</title><link rel=\"icon\" type=\"image/x-icon\" href=\"/assets/favicon.ico\"><link rel=\"stylesheet\" href=\"/assets/component/pear/css/pear.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/admin.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/admin.dark.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/variables.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/reset.css\"><link rel=\"stylesheet\" href=\"/assets/admin/css/style.css\"></head><body class=\"layui-layout-body pear-admin\"><!-- 布 局 框 架 --><div class=\"layui-layout layui-layout-admin\"><!-- 顶 部 样 式 --><div class=\"layui-header\"><!-- 菜 单 顶 部 --><div class=\"layui-logo\"><!-- 图 标 --><img class=\"logo\" alt=\"\" src=\"\"><!-- 标 题 --><span class=\"title\"></span></div><!-- 顶 部 左 侧 功 能 --><ul class=\"layui-nav layui-layout-left\"><li class=\"collapse layui-nav-item\"><a href=\"#\" class=\"layui-icon layui-icon-shrink-right\"></a></li><li class=\"refresh layui-nav-item\"><a href=\"#\" class=\"layui-icon layui-icon-refresh-1\"></a></li></ul><!-- 多 系 统 菜 单 --><div id=\"control\" class=\"layui-layout-control\"></div><!-- 顶 部 右 侧 菜 单 --><ul class=\"layui-nav layui-layout-right\"><!-- <li class=\"layui-nav-item layui-hide-xs\"><a href=\"#\"\n class=\"menuSearch layui-icon layui-icon-search\"></a></li>\n <li class=\"layui-nav-item layui-hide-xs message\"></li> --><li class=\"layui-nav-item layui-hide-xs\"><a href=\"#\" class=\"fullScreen layui-icon layui-icon-screen-full\"></a></li><li class=\"layui-nav-item user\"><!-- 头 像 --><a class=\"layui-icon layui-icon-username\" href=\"javascript:;\"></a><!-- 功 能 菜 单 --><dl class=\"layui-nav-child\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -59,7 +59,7 @@ func Home(ctx context.Context) templ.Component {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</dl></li><!-- 主 题 配 置 --><li class=\"layui-nav-item setting\"><a href=\"#\" class=\"layui-icon layui-icon-more-vertical\"></a></li></ul></div><!-- 侧 边 区 域 --><div class=\"layui-side layui-bg-black\"><!-- 菜 单 顶 部 --><div class=\"layui-logo\"><!-- 图 标 --><img class=\"logo\"><!-- 标 题 --><span class=\"title\"></span></div><!-- 菜 单 内 容 --><div class=\"layui-side-scroll\"><div id=\"side\"></div></div></div><!-- 视 图 页 面 --><div class=\"layui-body\" style=\"padding: 0\"><!-- 内 容 页 面 --><div id=\"content\"></div></div><!-- 页脚 --><div class=\"layui-footer layui-text\"></div><!-- 遮 盖 层 --><div class=\"pear-cover\"></div><!-- 加 载 动 画 --><div class=\"loader-wrapper\"><!-- 动 画 对 象 --><div class=\"loader\"></div></div></div><!-- 移 动 端 便 捷 操 作 --><div class=\"pear-collapsed-pe collapse\"><a href=\"#\" class=\"layui-icon layui-icon-shrink-right\"></a></div><script src=\"/statics/component/layui/layui.js\"></script><script src=\"/statics/component/pear/pear.js\"></script><script>\n layui.use(['admin', 'jquery', 'popup', 'drawer'], function () {\n const $ = layui.jquery;\n const admin = layui.admin;\n const popup = layui.popup;\n\n // yml | json | api\n admin.setConfigurationPath(\"/pear.json\");\n\n admin.render();\n\n // 登出逻辑\n admin.logout(function () {\n window.location.href = '/logout';\n // 清空 tabs 缓存\n return new Promise((resolve) => {\n resolve(true)\n });\n })\n\n // 读取 localStorage 主题颜色值,初始化 iframe 主题\n //darkTheme();\n //themeColor();\n\n // iframe 页监听 localStorage [pear 框架主题颜色] 变化。发生变化,同步更新 iframe 显示效果\n // window.addEventListener('storage', function (event) {\n // if (event.key === 'dark') {\n // darkTheme();\n // }\n // if (event.key === 'theme-color') {\n // themeColor();\n // }\n // });\n\n // 夜间模式切换\n // function darkTheme() {\n // var $pearAdmin = $(\".pear-admin\"); // 主体\n // var $layuiCard = $('.layui-card'); // 编辑页\n\n // if (localStorage.getItem('dark') === 'true') {\n // $pearAdmin.addClass(\"pear-admin-dark\");\n // $layuiCard.addClass('layui-card-dark');\n // } else {\n // $pearAdmin.removeClass(\"pear-admin-dark\");\n // $layuiCard.removeClass('layui-card-dark');\n // }\n // }\n\n // 主题颜色切换\n // function themeColor() {\n // const variableKey = \"--global-primary-color\";\n // const variableVal = localStorage.getItem(\"theme-color-color\");\n // document.documentElement.style.setProperty(variableKey, variableVal);\n // }\n\n // 消息点击回调\n // admin.message(function (id, title, context, form) { });\n })\n </script></body></html>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</dl></li><!-- 主 题 配 置 --><li class=\"layui-nav-item setting\"><a href=\"#\" class=\"layui-icon layui-icon-more-vertical\"></a></li></ul></div><!-- 侧 边 区 域 --><div class=\"layui-side layui-bg-black\"><!-- 菜 单 顶 部 --><div class=\"layui-logo\"><!-- 图 标 --><img class=\"logo\"><!-- 标 题 --><span class=\"title\"></span></div><!-- 菜 单 内 容 --><div class=\"layui-side-scroll\"><div id=\"side\"></div></div></div><!-- 视 图 页 面 --><div class=\"layui-body\" style=\"padding: 0\"><!-- 内 容 页 面 --><div id=\"content\"></div></div><!-- 页脚 --><div class=\"layui-footer layui-text\"></div><!-- 遮 盖 层 --><div class=\"pear-cover\"></div><!-- 加 载 动 画 --><div class=\"loader-wrapper\"><!-- 动 画 对 象 --><div class=\"loader\"></div></div></div><!-- 移 动 端 便 捷 操 作 --><div class=\"pear-collapsed-pe collapse\"><a href=\"#\" class=\"layui-icon layui-icon-shrink-right\"></a></div><script src=\"/assets/component/layui/layui.js\"></script><script src=\"/assets/component/pear/pear.js\"></script><script>\n layui.use(['admin', 'jquery', 'popup', 'drawer'], function () {\n const $ = layui.jquery;\n const admin = layui.admin;\n const popup = layui.popup;\n\n // yml | json | api\n admin.setConfigurationPath(\"/pear.json\");\n\n admin.render();\n\n // 登出逻辑\n admin.logout(function () {\n window.location.href = '/logout';\n // 清空 tabs 缓存\n return new Promise((resolve) => {\n resolve(true)\n });\n })\n\n // 读取 localStorage 主题颜色值,初始化 iframe 主题\n //darkTheme();\n //themeColor();\n\n // iframe 页监听 localStorage [pear 框架主题颜色] 变化。发生变化,同步更新 iframe 显示效果\n // window.addEventListener('storage', function (event) {\n // if (event.key === 'dark') {\n // darkTheme();\n // }\n // if (event.key === 'theme-color') {\n // themeColor();\n // }\n // });\n\n // 夜间模式切换\n // function darkTheme() {\n // var $pearAdmin = $(\".pear-admin\"); // 主体\n // var $layuiCard = $('.layui-card'); // 编辑页\n\n // if (localStorage.getItem('dark') === 'true') {\n // $pearAdmin.addClass(\"pear-admin-dark\");\n // $layuiCard.addClass('layui-card-dark');\n // } else {\n // $pearAdmin.removeClass(\"pear-admin-dark\");\n // $layuiCard.removeClass('layui-card-dark');\n // }\n // }\n\n // 主题颜色切换\n // function themeColor() {\n // const variableKey = \"--global-primary-color\";\n // const variableVal = localStorage.getItem(\"theme-color-color\");\n // document.documentElement.style.setProperty(variableKey, variableVal);\n // }\n\n // 消息点击回调\n // admin.message(function (id, title, context, form) { });\n })\n </script></body></html>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@@ -1,17 +0,0 @@
package minifyjs
import (
"github.com/tdewolff/minify"
"github.com/tdewolff/minify/js"
)
func Compile(raw string) string {
m := minify.New()
m.AddFunc("text/javascript", js.Minify)
minified, err := m.String("text/javascript", raw)
if err != nil {
return raw // 失败时返回原始代码
}
return minified
}

View File

@@ -11,7 +11,7 @@ import (
templ List(ctx context.Context) {
@base.Base(ctx, listCss(), listJs(ctx)) {
{{ meuns := mid.GetCurMenus(ctx) }}
@component.TemplBtn(meuns, true, "add", "refresh_cache")
@component.TemplBtn(meuns, false, "add", "refresh_cache")
@component.TemplLink(meuns, "add_children", "edit")
<div class="layui-panel">

View File

@@ -50,7 +50,7 @@ func List(ctx context.Context) templ.Component {
}
ctx = templ.InitializeContext(ctx)
meuns := mid.GetCurMenus(ctx)
templ_7745c5c3_Err = component.TemplBtn(meuns, true, "add", "refresh_cache").Render(ctx, templ_7745c5c3_Buffer)
templ_7745c5c3_Err = component.TemplBtn(meuns, false, "add", "refresh_cache").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@@ -15,7 +15,6 @@ import (
systemService "management/internal/erpserver/service/v1/system"
"management/internal/pkg/cache"
"management/internal/pkg/config"
"management/internal/pkg/render"
"management/internal/pkg/session"
"github.com/drhin/logger"
@@ -76,7 +75,6 @@ func NewWire(*config.Config, *logger.Logger) (App, func(), error) {
cache.NewRedisCache,
session.NewSCSManager,
serviceSet,
render.New,
handlerSet,
serverSet,
))

View File

@@ -20,7 +20,6 @@ import (
system2 "management/internal/erpserver/service/v1/system"
"management/internal/pkg/cache"
"management/internal/pkg/config"
"management/internal/pkg/render"
"management/internal/pkg/session"
)
@@ -58,13 +57,7 @@ func NewWire(configConfig *config.Config, loggerLogger *logger.Logger) (App, fun
roleMenuRepository := system.NewRoleMenuRepository(repositoryRepository)
roleMenuService := system2.NewRoleMenuService(service, roleMenuRepository)
menuService := system2.NewMenuService(service, menuRepository, roleService, roleMenuService)
renderRender, err := render.New(manager, menuService)
if err != nil {
cleanup2()
cleanup()
return App{}, nil, err
}
handlerHandler := handler.NewHandler(configConfig, loggerLogger, manager, renderRender)
handlerHandler := handler.NewHandler(configConfig, loggerLogger, manager)
captchaService := common.NewCaptchaService()
captchaHandler := common2.NewCaptchaHandler(handlerHandler, captchaService)
uploadHandler := common2.NewUploadHandler(handlerHandler)

View File

@@ -7,7 +7,7 @@ const PearKey = "PEAR_JSON"
var PearJson = &dto.PearConfig{
Logo: dto.Logo{
Title: "Pear Admin",
Image: "/statics/admin/images/logo.png",
Image: "/assets/admin/images/logo.png",
},
Menu: dto.Menu{
Data: "/system/menus",
@@ -70,6 +70,6 @@ var PearJson = &dto.PearConfig{
Footer: false,
},
Header: dto.Header{
Message: "/statics/admin/data/message.json",
Message: "/assets/admin/data/message.json",
},
}

View File

@@ -1,65 +0,0 @@
package funcs
import (
"html/template"
"strings"
"time"
)
func Methods() map[string]any {
res := make(map[string]any, 1)
res["dateFormat"] = func(dt time.Time) template.HTML {
return template.HTML(dt.Format(time.DateTime))
}
res["today"] = func() template.HTML {
return template.HTML(time.Now().Format("2006-01-02"))
}
res["threeMonth"] = func() template.HTML {
return template.HTML(time.Now().AddDate(0, 3, 0).Format("2006-01-02"))
}
res["yearBegin"] = func() template.HTML {
dt := time.Now()
t := dt.AddDate(0, -int(dt.Month())+1, -dt.Day()+1)
return template.HTML(t.Format("2006-01-02") + " 00:00:00")
}
res["monthBegin"] = func() template.HTML {
dt := time.Now()
t := dt.AddDate(0, 0, -dt.Day()+1)
return template.HTML(t.Format("2006-01-02") + " 00:00:00")
}
res["monthEnd"] = func() template.HTML {
dt := time.Now()
t := dt.AddDate(0, 0, -dt.Day()+1).AddDate(0, 1, -1)
return template.HTML(t.Format("2006-01-02") + " 23:59:59")
}
res["trimSpace"] = func(s string) template.HTML {
return template.HTML(strings.TrimSpace(s))
}
res["expandTags"] = func(s []string) template.HTML {
if len(s) == 0 {
return ""
}
if len(s) == 1 && s[0] == "all" {
return ""
}
return template.HTML(strings.Join(s, ","))
}
res["toString"] = func(b []byte) string {
return string(b)
}
res["add"] = func(n1, n2 int64) int64 {
return n1 + n2
}
return res
}

View File

@@ -1,99 +0,0 @@
package gen
import (
"html/template"
"path/filepath"
"strings"
"management/internal/erpserver/model/dto"
)
func Button() map[string]any {
res := make(map[string]any, 3)
res["genBtn"] = func(buttons []*dto.OwnerMenuDto, actionNames ...string) template.HTML {
if len(buttons) == 0 {
return ""
}
var res string
for _, action := range actionNames {
for _, btn := range buttons {
btn.Style = strings.ReplaceAll(btn.Style, "pear", "layui")
base := filepath.Base(btn.Url)
if base == action {
res += `<button type="button" class="layui-btn ` + btn.Style + `" lay-event="` + firstLower(action) + `" lay-on="` + firstLower(action) + `">`
if len(btn.Avatar) > 0 {
res += `<i class="` + btn.Avatar + `"></i> `
}
res += btn.DisplayName + `</button>`
}
}
}
return template.HTML(res)
}
res["genLink"] = func(buttons []*dto.OwnerMenuDto, actionNames ...string) template.HTML {
if len(buttons) == 0 {
return ""
}
var res string
for _, action := range actionNames {
for _, btn := range buttons {
btn.Style = strings.ReplaceAll(btn.Style, "pear", "layui")
base := filepath.Base(btn.Url)
if base == action {
res += `<button type="button" style="font-size:12px !important;" class="layui-btn ` + btn.Style + `" lay-event="` + firstLower(action) + `" lay-on="` + firstLower(action) + `">`
if len(btn.Avatar) > 0 {
res += `<i class="` + btn.Avatar + `"></i> `
}
res += btn.DisplayName + `</button>`
}
}
}
return template.HTML(res)
}
res["previewPicture"] = func(name string) template.HTML {
var res string
res += `<a><img src="https://school-1251542740.cos.ap-shanghai.myqcloud.com{{` + name + `}}" data-type="1" height="30" width="30" class="preview-all screenshot" onclick="previewPicture('https://school-1251542740.cos.ap-shanghai.myqcloud.com/{{` + name + `}}')"/></a>`
return template.HTML(res)
}
res["submitBtn"] = func(buttons []*dto.OwnerMenuDto, actionNames ...string) template.HTML {
if len(buttons) == 0 {
return ""
}
var res string
for _, action := range actionNames {
for _, btn := range buttons {
btn.Style = strings.ReplaceAll(btn.Style, "pear", "layui")
base := filepath.Base(btn.Url)
if base == action {
res += `<button type="submit" class="layui-btn ` + btn.Style + `" lay-submit lay-filter="` + firstLower(action) + `">`
if len(btn.Avatar) > 0 {
res += `<i class="` + btn.Avatar + `"></i> `
}
res += btn.DisplayName + `</button>`
}
}
}
return template.HTML(res)
}
return res
}
func firstLower(s string) string {
if len(s) == 0 {
return s
}
return strings.ToLower(s[:1]) + s[1:]
}

View File

@@ -1,105 +0,0 @@
package render
import (
"bytes"
"context"
"fmt"
"html/template"
"net/http"
"path/filepath"
"strings"
"management/internal/erpserver/model/dto"
"management/internal/pkg/know"
"github.com/justinas/nosurf"
)
type TemplateConfig struct {
Root string
Extension string
Layout string
Partial string
}
type HtmlData struct {
IsAuthenticated bool
AuthorizeUser dto.AuthorizeUser
AuthorizeMenus []*dto.OwnerMenuDto
Data any
}
func (r *render) HTML(w http.ResponseWriter, req *http.Request, tpl string, data map[string]any) {
name := strings.ReplaceAll(tpl, "/", "_")
t, ok := r.templates[name]
if !ok {
http.Error(w, "template is empty", http.StatusInternalServerError)
return
}
hd := r.setDefaultData(req, data)
buf := new(bytes.Buffer)
err := t.ExecuteTemplate(buf, filepath.Base(tpl), hd)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_, err = buf.WriteTo(w)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func (r *render) setDefaultData(req *http.Request, data map[string]any) map[string]any {
if data == nil {
data = make(map[string]any)
}
ctx := req.Context()
authUser, err := r.session.GetUser(ctx, know.StoreName)
if err != nil || authUser.ID == 0 {
data["IsAuthenticated"] = false
} else {
data["IsAuthenticated"] = true
data["AuthorizeMenus"] = r.getCurrentPathButtons(ctx, authUser.RoleID, req.URL.Path)
}
token := nosurf.Token(req)
data["CsrfToken"] = token
data["CsrfTokenField"] = template.HTML(fmt.Sprintf(`<input type="hidden" name="csrf_token" value="%s" />`, token))
return data
}
func (r *render) getCurrentPathButtons(ctx context.Context, roleID int32, path string) []*dto.OwnerMenuDto {
var res []*dto.OwnerMenuDto
// 获取当前登陆角色的权限
menus, err := r.menuService.ListByRoleIDToMap(ctx, roleID)
if err != nil {
return res
}
menu, ok := menus[path]
if !ok {
return res
}
for _, item := range menus {
if menu.IsList {
if item.ParentID == menu.ID || item.ID == menu.ID {
res = append(res, item)
}
} else {
if item.ParentID == menu.ParentID {
res = append(res, item)
}
}
}
return res
}

View File

@@ -1,17 +0,0 @@
package html
type SelectDict struct {
Name string
Value string
Selected bool
}
func NewSelectControls(data []*SelectDict, value string) []*SelectDict {
for _, item := range data {
item.Selected = false
if item.Value == value {
item.Selected = true
}
}
return data
}

View File

@@ -1,19 +0,0 @@
package html
var SearchStatuses = []*SelectDict{
{Name: "状态", Value: "9999", Selected: false},
{Name: "正常", Value: "0", Selected: false},
{Name: "删除", Value: "-1", Selected: false},
}
var Statuses = []*SelectDict{
{Name: "正常", Value: "0", Selected: false},
{Name: "删除", Value: "-1", Selected: false},
}
var ProjectStatuses = []*SelectDict{
{Name: "未开始", Value: "0", Selected: false},
{Name: "进行中", Value: "10", Selected: false},
{Name: "已结项", Value: "20", Selected: false},
{Name: "已删除", Value: "-1", Selected: false},
}

View File

@@ -1,57 +0,0 @@
package render
import (
"encoding/json"
"net/http"
)
type Response struct {
Success bool `json:"success"`
Message string `json:"msg"`
Data any `json:"data"`
}
type ResponseTree struct {
Status ResponseTreeStatus `json:"status"`
Data any `json:"data"`
}
type ResponseTreeStatus struct {
Code int `json:"code"`
Message string `json:"message"`
}
type ResponseList struct {
Code int `json:"code"`
Message string `json:"msg"`
Count int64 `json:"count"`
Data any `json:"data"`
}
func (r *render) JSONOk(w http.ResponseWriter, message string) {
r.JSON(w, Response{Success: true, Message: message})
}
func (r *render) JSONErr(w http.ResponseWriter, message string) {
r.JSON(w, Response{Success: false, Message: message})
}
func (r *render) JSONObj(w http.ResponseWriter, message string, data any) {
r.JSON(w, Response{Success: true, Message: message, Data: data})
}
func (r *render) JSON(w http.ResponseWriter, data any) {
v, err := json.Marshal(data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusOK)
_, err = w.Write(v)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

View File

@@ -1,60 +0,0 @@
package render
import (
"html/template"
"net/http"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/render/util"
"management/internal/pkg/session"
)
type Render interface {
htmlRender
jsonRender
}
type htmlRender interface {
HTML(w http.ResponseWriter, req *http.Request, name string, data map[string]any)
}
type jsonRender interface {
JSON(w http.ResponseWriter, data any)
JSONObj(w http.ResponseWriter, message string, data any)
JSONOk(w http.ResponseWriter, message string)
JSONErr(w http.ResponseWriter, message string)
}
type render struct {
templateConfig *TemplateConfig
templates map[string]*template.Template
session session.Manager
menuService v1.MenuService
}
func New(session session.Manager, menuService v1.MenuService) (Render, error) {
r := &render{
templateConfig: &TemplateConfig{
Root: ".",
Extension: ".tmpl",
Layout: "base",
Partial: "partial",
},
session: session,
menuService: menuService,
}
var err error
r.templates, err = util.CreateTemplateCache(
r.templateConfig.Root,
r.templateConfig.Layout,
r.templateConfig.Partial,
r.templateConfig.Extension,
)
if err != nil {
return nil, err
}
return r, nil
}

View File

@@ -1,99 +0,0 @@
package util
import (
"fmt"
"html/template"
"io/fs"
"os"
"path/filepath"
"slices"
"strings"
"management/internal/pkg/render/funcs"
"management/internal/pkg/render/gen"
templates "management/web/templates/manage"
)
func CreateTemplateCache(root, layout, partial, extension string) (map[string]*template.Template, error) {
cache := make(map[string]*template.Template)
pages, err := getFiles(root, extension)
if err != nil {
return nil, err
}
layoutAndPartial, err := getLayoutAndPartials(layout, partial, extension)
if err != nil {
return nil, err
}
for _, page := range pages {
if strings.HasPrefix(page, layout) || strings.HasSuffix(page, partial) {
continue
}
name := filepath.Base(page)
pathArr := strings.Split(page, "/")
dir := pathArr[len(pathArr)-2 : len(pathArr)-1]
templateName := fmt.Sprintf("%s_%s", dir[0], name)
ts := template.Must(template.New(templateName).Funcs(gen.Button()).Funcs(funcs.Methods()).ParseFS(templates.TemplateFS, page))
ts, err = ts.ParseFS(templates.TemplateFS, layoutAndPartial...)
if err != nil {
return nil, err
}
cache[templateName] = ts
}
return cache, nil
}
func getLayoutAndPartials(layout, partial, extension string) ([]string, error) {
layouts, err := getFiles(layout, extension)
if err != nil {
return nil, err
}
partials, err := getFiles(partial, extension)
if err != nil {
return nil, err
}
return slices.Concat(layouts, partials), nil
}
func getFiles(path string, suffix string) ([]string, error) {
files := make([]string, 0)
b, err := pathExists(templates.TemplateFS, path)
if err != nil {
return nil, err
}
if !b {
return files, nil
}
err = fs.WalkDir(templates.TemplateFS, path, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
if strings.HasSuffix(path, suffix) {
files = append(files, path)
}
return nil
})
return files, err
}
func pathExists(fs fs.FS, path string) (bool, error) {
_, err := fs.Open(path)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
return true, err
}