This commit is contained in:
2025-10-27 15:24:08 +08:00
parent 4186cd0caf
commit df4c3dd46f
47 changed files with 1757 additions and 306 deletions

View File

@@ -82,12 +82,11 @@ func (a *app) login(w http.ResponseWriter, r *http.Request) {
//err := a.userService.Login(ctx, &req)
risk, err := a.authService.Authenticate(ctx, req)
if err != nil {
log.Println(err)
a.render.JSONErr(w, err.Error())
return
}
log.Println(risk)
log.Println("risk:", risk)
a.render.JSONOk(w, "login successfully")
default:

View File

@@ -2,6 +2,7 @@ package config
import (
"encoding/json"
"errors"
"net/http"
"strings"
@@ -11,8 +12,8 @@ import (
systemService "management/internal/erpserver/service/v1"
"management/internal/erpserver/templ/system/config"
"management/internal/pkg/convertor"
"management/internal/pkg/database"
"management/internal/pkg/render"
"management/internal/pkg/sqldb"
)
type app struct {
@@ -91,7 +92,7 @@ func (a *app) save(w http.ResponseWriter, r *http.Request) {
}
err := a.configService.Create(ctx, arg)
if err != nil {
if database.IsUniqueViolation(err) {
if errors.Is(err, sqldb.ErrDBDuplicatedEntry) {
a.render.JSONErr(w, "数据已存在")
return
}

View File

@@ -1,6 +1,7 @@
package menu
import (
"errors"
"net/http"
"strconv"
"strings"
@@ -10,9 +11,9 @@ import (
v1 "management/internal/erpserver/service/v1"
"management/internal/erpserver/templ/system/menu"
"management/internal/pkg/convertor"
"management/internal/pkg/database"
"management/internal/pkg/mid"
"management/internal/pkg/render"
"management/internal/pkg/sqldb"
"github.com/google/uuid"
)
@@ -144,7 +145,7 @@ func (a *app) save(w http.ResponseWriter, r *http.Request) {
}
err := a.menuService.Create(ctx, arg)
if err != nil {
if database.IsUniqueViolation(err) {
if errors.Is(err, sqldb.ErrDBDuplicatedEntry) {
a.render.JSONErr(w, "菜单已存在")
return
}

View File

@@ -8,8 +8,8 @@ import (
)
type DepartmentRepository interface {
Initialize(ctx context.Context) error
Create(ctx context.Context, obj *Department) error
Initialize(ctx context.Context) (*Department, error)
Create(ctx context.Context, obj *Department) (*Department, error)
Update(ctx context.Context, obj *Department) error
Get(ctx context.Context, id int32) (*Department, error)
All(ctx context.Context) ([]*Department, error)

View File

@@ -9,7 +9,7 @@ import (
type RoleRepository interface {
Initialize(ctx context.Context) (*Role, error)
Create(ctx context.Context, obj *Role) error
Create(ctx context.Context, obj *Role) (*Role, error)
Update(ctx context.Context, obj *Role) error
Get(ctx context.Context, id int32) (*Role, error)
GetByVip(ctx context.Context, vip bool) (*Role, error)

View File

@@ -11,8 +11,8 @@ import (
type UserRepository interface {
Initialize(ctx context.Context, departId, roleId int32) error
Create(ctx context.Context, obj *User) error
Update(ctx context.Context, obj *User) error
Create(ctx context.Context, obj *User) (*User, error)
Update(ctx context.Context, obj *User) (*User, error)
Get(ctx context.Context, id int32) (*User, error)
GetByEmail(ctx context.Context, email string) (*User, error)
All(ctx context.Context) ([]*User, error)

View File

@@ -41,7 +41,7 @@ func (s *Seed) Run() error {
}
// 部门
err := s.departmentRepository.Initialize(ctx)
depart, err := s.departmentRepository.Initialize(ctx)
if err != nil {
return err
}
@@ -53,7 +53,7 @@ func (s *Seed) Run() error {
}
// 用户
if err := s.userRepository.Initialize(ctx, 0, role.ID); err != nil {
if err := s.userRepository.Initialize(ctx, depart.ID, role.ID); err != nil {
return err
}

View File

@@ -3,13 +3,14 @@ package config
import (
"bytes"
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"management/internal/erpserver/model/dto"
"management/internal/erpserver/model/system"
"management/internal/erpserver/repository"
"management/internal/pkg/database"
"management/internal/pkg/know/pearadmin"
"management/internal/pkg/sqldb"
@@ -32,7 +33,7 @@ func NewStore(db *repository.Store, log *logger.Logger) system.ConfigRepository
func (s *store) Initialize(ctx context.Context) error {
_, err := s.GetByKey(ctx, pearadmin.PearKey)
if err != nil {
if database.IsNoRows(err) {
if errors.Is(err, sql.ErrNoRows) {
b, e := json.Marshal(pearadmin.PearJson)
if e != nil {
return e

View File

@@ -26,14 +26,14 @@ func NewStore(db *repository.Store, log *logger.Logger) system.DepartmentReposit
}
}
func (s *store) Initialize(ctx context.Context) error {
func (s *store) Initialize(ctx context.Context) (*system.Department, error) {
count, err := s.Count(ctx, dto.SearchDto{})
if err != nil {
return err
return nil, err
}
if count == 0 {
obj := system.Department{
obj := &system.Department{
Name: "公司",
ParentID: 0,
ParentPath: ",0,",
@@ -42,21 +42,33 @@ func (s *store) Initialize(ctx context.Context) error {
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
return s.Create(ctx, &obj)
return s.Create(ctx, obj)
}
return nil
return s.Get(ctx, 1)
}
func (s *store) Create(ctx context.Context, obj *system.Department) error {
func (s *store) Create(ctx context.Context, obj *system.Department) (*system.Department, error) {
//goland:noinspection ALL
const q = `
INSERT INTO sys_department (
name, parent_id, parent_path, status, sort
) VALUES (
:name, :parent_id, :parent_path, :status, :sort
);`
) RETURNING *;`
return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj)
data := map[string]any{
"name": obj.Name,
"parent_id": obj.ParentID,
"parent_path": obj.ParentPath,
"status": obj.Status,
"sort": obj.Sort,
}
err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &obj)
if err != nil {
return nil, err
}
return obj, err
}
func (s *store) Update(ctx context.Context, obj *system.Department) error {

View File

@@ -30,9 +30,24 @@ func (s *store) Create(ctx context.Context, obj *system.Menu) (*system.Menu, err
name, display_name, url, type, parent_id, parent_path, avatar, style, visible, is_list, status, sort
) VALUES (
:name, :display_name, :url, :type, :parent_id, :parent_path, :avatar, :style, :visible, :is_list, :status, :sort
);`
) RETURNING *;`
err := sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj)
data := map[string]any{
"name": obj.Name,
"display_name": obj.DisplayName,
"url": obj.Url,
"type": obj.Type,
"parent_id": obj.ParentID,
"parent_path": obj.ParentPath,
"avatar": obj.Avatar,
"style": obj.Style,
"visible": obj.Visible,
"is_list": obj.IsList,
"status": obj.Status,
"sort": obj.Sort,
}
err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &obj)
if err != nil {
return nil, err
}

View File

@@ -32,7 +32,8 @@ func (s *store) Initialize(ctx context.Context) (*system.Role, error) {
return nil, err
}
if count == 0 {
obj := system.Role{
var err error
obj := &system.Role{
Name: "Company",
DisplayName: "公司",
Vip: false,
@@ -42,11 +43,12 @@ func (s *store) Initialize(ctx context.Context) (*system.Role, error) {
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if err := s.Create(ctx, &obj); err != nil {
obj, err = s.Create(ctx, obj)
if err != nil {
return nil, err
}
obj1 := system.Role{
obj1 := &system.Role{
Name: "SuperAdmin",
DisplayName: "超级管理员",
Vip: true,
@@ -56,26 +58,42 @@ func (s *store) Initialize(ctx context.Context) (*system.Role, error) {
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if err := s.Create(ctx, &obj1); err != nil {
obj1, err = s.Create(ctx, obj1)
if err != nil {
return nil, err
}
return &obj1, nil
return obj1, nil
}
return s.GetByVip(ctx, true)
}
func (s *store) Create(ctx context.Context, obj *system.Role) error {
func (s *store) Create(ctx context.Context, obj *system.Role) (*system.Role, error) {
//goland:noinspection ALL
const q = `
INSERT INTO sys_role (
name, display_name, parent_id, parent_path, vip, status, sort
) VALUES (
:name, :display_name, :parent_id, :parent_path, :vip, :status, :sort
)`
) RETURNING *`
return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj)
data := map[string]any{
"name": obj.Name,
"display_name": obj.DisplayName,
"parent_id": obj.ParentID,
"parent_path": obj.ParentPath,
"vip": obj.Vip,
"status": obj.Status,
"sort": obj.Sort,
}
err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &obj)
if err != nil {
return nil, err
}
return obj, nil
}
func (s *store) Update(ctx context.Context, obj *system.Role) error {

View File

@@ -67,25 +67,44 @@ func (s *store) Initialize(ctx context.Context, departId, roleId int32) error {
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
return s.Create(ctx, &user)
_, err = s.Create(ctx, &user)
return err
}
return nil
}
func (s *store) Create(ctx context.Context, obj *system.User) error {
func (s *store) Create(ctx context.Context, obj *system.User) (*system.User, error) {
//goland:noinspection ALL
const q = `
INSERT INTO sys_user (
uuid, email, username, hashed_password, salt, avatar, gender, department_id, role_id, status
) VALUES (
:uuid, :email, :username, :hashed_password, :salt, :avatar, :gender, :department_id, :role_id, :status
);`
) RETURNING *;`
return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj)
data := map[string]any{
"uuid": obj.Uuid.String(),
"email": obj.Email,
"username": obj.Username,
"hashed_password": obj.HashedPassword,
"salt": obj.Salt,
"avatar": obj.Avatar,
"gender": obj.Gender,
"department_id": obj.DepartmentID,
"role_id": obj.RoleID,
"status": obj.Status,
}
err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &obj)
if err != nil {
return nil, err
}
return obj, nil
}
func (s *store) Update(ctx context.Context, obj *system.User) error {
func (s *store) Update(ctx context.Context, obj *system.User) (*system.User, error) {
//goland:noinspection ALL
const q = `
UPDATE sys_user
@@ -99,9 +118,28 @@ func (s *store) Update(ctx context.Context, obj *system.User) error {
status = :status,
change_password_at = :change_password_at,
updated_at = :updated_at
WHERE id = :id;`
WHERE id = :id RETURNING *;`
return sqldb.NamedExecContext(ctx, s.log, s.db.DB(ctx), q, obj)
data := map[string]any{
"email": obj.Email,
"username": obj.Username,
"hashed_password": obj.HashedPassword,
"avatar": obj.Avatar,
"gender": obj.Gender,
"department_id": obj.DepartmentID,
"role_id": obj.RoleID,
"status": obj.Status,
"change_password_at": obj.ChangePasswordAt,
"updated_at": obj.UpdatedAt,
"id": obj.ID,
}
err := sqldb.NamedQueryStruct(ctx, s.log, s.db.DB(ctx), q, data, &obj)
if err != nil {
return nil, err
}
return obj, nil
}
func (s *store) Get(ctx context.Context, id int32) (*system.User, error) {

View File

@@ -167,7 +167,7 @@ func (a *Auth) validateUser(ctx context.Context, email, password string) (*syste
user.Role, err = a.roleService.Get(ctx, user.RoleID)
if err != nil {
return nil, err
return nil, errors.New("账号没有配置角色, 请联系管理员")
}
if user.Role == nil || user.Role.ID == 0 {

View File

@@ -12,10 +12,10 @@ import (
"management/internal/erpserver/model/system"
"management/internal/erpserver/model/view"
"management/internal/erpserver/service/util"
"management/internal/erpserver/service/v1"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/convertor"
"management/internal/pkg/database"
"management/internal/pkg/know"
"management/internal/pkg/sqldb"
)
type departmentService struct {
@@ -58,9 +58,9 @@ func (s *departmentService) Create(ctx context.Context, req *form.Department) er
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
err := s.repo.Create(ctx, arg)
_, err := s.repo.Create(ctx, arg)
if err != nil {
if database.IsUniqueViolation(err) {
if errors.Is(err, sqldb.ErrDBDuplicatedEntry) {
return errors.New("部门已存在")
}
return err

View File

@@ -12,10 +12,10 @@ import (
"management/internal/erpserver/model/system"
"management/internal/erpserver/model/view"
"management/internal/erpserver/service/util"
"management/internal/erpserver/service/v1"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/convertor"
"management/internal/pkg/database"
"management/internal/pkg/know"
"management/internal/pkg/sqldb"
)
type roleService struct {
@@ -60,9 +60,9 @@ func (s *roleService) Create(ctx context.Context, req *form.Role) error {
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
err := s.repo.Create(ctx, arg)
_, err := s.repo.Create(ctx, arg)
if err != nil {
if database.IsUniqueViolation(err) {
if errors.Is(err, sqldb.ErrDBDuplicatedEntry) {
return errors.New("角色名称已存在")
}
return err

View File

@@ -10,11 +10,11 @@ import (
"management/internal/erpserver/model/form"
"management/internal/erpserver/model/system"
"management/internal/erpserver/model/view"
"management/internal/erpserver/service/v1"
v1 "management/internal/erpserver/service/v1"
"management/internal/pkg/crypto"
"management/internal/pkg/database"
"management/internal/pkg/know"
"management/internal/pkg/rand"
"management/internal/pkg/sqldb"
"github.com/google/uuid"
"go.uber.org/zap"
@@ -75,9 +75,9 @@ func (s *userService) Create(ctx context.Context, req *form.User) error {
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
err = s.repo.Create(ctx, user)
_, err = s.repo.Create(ctx, user)
if err != nil {
if database.IsUniqueViolation(err) {
if errors.Is(err, sqldb.ErrDBDuplicatedEntry) {
return errors.New("用户已经存在")
}
return err
@@ -106,7 +106,9 @@ func (s *userService) Update(ctx context.Context, req *form.User) error {
user.HashedPassword = hashedPassword
user.ChangePasswordAt = time.Now()
}
return s.repo.Update(ctx, user)
_, err = s.repo.Update(ctx, user)
return err
}
func (s *userService) All(ctx context.Context) ([]*system.User, error) {

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package auth
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package base
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package component
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package component
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package home
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package home
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package auditlog
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package category
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package config
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package config
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package department
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@@ -61,7 +61,7 @@ func Edit(ctx context.Context, item *system.Department) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<input type=\"hidden\" id=\"id\" name=\"id\" value=\"\"")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<input type=\"hidden\" id=\"id\" name=\"id\" value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -70,11 +70,11 @@ func Edit(ctx context.Context, item *system.Department) templ.Component {
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/erpserver/templ/system/department/edit.templ`, Line: 21, Col: 75}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(` ` + templ_7745c5c3_Var3))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "><div class=\"layui-tab layui-tab-card\"><ul class=\"layui-tab-title\"><li class=\"layui-this\">基础信息</li><li>其它</li></ul><div class=\"layui-tab-content\"><!-- 基础信息 --><div class=\"layui-tab-item layui-show\">")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"><div class=\"layui-tab layui-tab-card\"><ul class=\"layui-tab-title\"><li class=\"layui-this\">基础信息</li><li>其它</li></ul><div class=\"layui-tab-content\"><!-- 基础信息 --><div class=\"layui-tab-item layui-show\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package department
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package loginlog
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package menu
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package menu
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package role
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package role
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package role
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package user
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package user
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View File

@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.898
// templ: version: v0.3.960
package user
//lint:file-ignore SA4006 This context is only used if a nested component is present.