├── .dockerignore
├── config
├── db-end-mysql.sql
├── db-begin-mysql.sql
├── settings.demo.yml
├── extend.go
├── pg.sql
└── settings.sqlite.yml
├── static
├── image
│ ├── img.png
│ ├── login.png
│ ├── order.png
│ ├── task.png
│ ├── customflow.png
│ ├── orderApply.png
│ ├── statistics.png
│ ├── tasktype.png
│ ├── ordermanage.png
│ ├── customtemplate.png
│ └── orderApply-v2.png
└── form-generator
│ ├── css
│ └── parser-example.69e16e51.css
│ ├── img
│ └── logo.e1bc3747.png
│ ├── js
│ └── tinymce-example.641995ab.js
│ └── preview.html
├── common
├── actions
│ ├── type.go
│ ├── create.go
│ ├── index.go
│ ├── update.go
│ ├── delete.go
│ └── view.go
├── global
│ ├── topic.go
│ ├── adm.go
│ ├── logo.go
│ ├── casbin.go
│ └── pagingquery.go
├── middleware
│ ├── handler
│ │ ├── ping.go
│ │ ├── httpshandler.go
│ │ ├── role.go
│ │ ├── login.go
│ │ └── user.go
│ ├── db.go
│ ├── trace.go
│ ├── sentinel.go
│ ├── request_id.go
│ ├── init.go
│ ├── demo.go
│ ├── auth.go
│ ├── customerror.go
│ ├── header.go
│ ├── permission.go
│ └── settings.go
├── models
│ ├── menu.go
│ ├── type.go
│ ├── migrate.go
│ ├── response.go
│ └── user.go
├── dto
│ ├── order.go
│ ├── pagination.go
│ ├── type.go
│ └── search.go
├── file_store
│ ├── obs_test.go
│ ├── oss_test.go
│ ├── kodo_test.go
│ ├── interface.go
│ ├── initialize.go
│ ├── oss.go
│ └── obs.go
├── database
│ ├── open.go
│ ├── open_sqlite3.go
│ └── initialize.go
├── service
│ └── service.go
├── ip.go
├── storage
│ └── initialize.go
└── utils
│ ├── encrypt.go
│ ├── tasklog.go
│ └── machinehealth.go
├── app
├── smart
│ ├── service
│ │ ├── .DS_Store
│ │ └── dto
│ │ │ ├── user_favorite.go
│ │ │ ├── order_rating.go
│ │ │ ├── order_comment.go
│ │ │ ├── order_category.go
│ │ │ └── order_statistics.go
│ ├── models
│ │ ├── order_rating.go
│ │ ├── user_favorite.go
│ │ ├── order_comment.go
│ │ ├── order_category.go
│ │ ├── order_items.go
│ │ ├── flow_templates.go
│ │ ├── exec_machine.go
│ │ └── flow_manage.go
│ └── router
│ │ ├── user_favorite.go
│ │ ├── flow_templates.go
│ │ ├── order_category.go
│ │ ├── order_items.go
│ │ ├── init_router.go
│ │ ├── flow_manage.go
│ │ ├── order_statistics.go
│ │ ├── order_comment.go
│ │ ├── order_rating.go
│ │ ├── exec_machine.go
│ │ ├── router.go
│ │ ├── order_task.go
│ │ └── order_works.go
├── system
│ ├── service
│ │ ├── dto
│ │ │ ├── sys_notify.go
│ │ │ └── sys_login_log.go
│ │ ├── sys_login_log.go
│ │ └── sys_opera_log.go
│ ├── models
│ │ ├── model.go
│ │ ├── casbin_rule.go
│ │ ├── sys_dict_type.go
│ │ ├── sys_config.go
│ │ ├── sys_post.go
│ │ ├── sys_dept.go
│ │ ├── sys_dict_data.go
│ │ ├── initdb.go
│ │ ├── sys_role.go
│ │ ├── sys_menu.go
│ │ └── sys_login_log.go
│ ├── router
│ │ ├── sys_notify.go
│ │ ├── sys_opera_log.go
│ │ ├── sys_login_log.go
│ │ ├── sys_api.go
│ │ ├── sys_post.go
│ │ ├── sys_dept.go
│ │ ├── sys_menu.go
│ │ ├── sys_role.go
│ │ ├── init_router.go
│ │ ├── router.go
│ │ ├── sys_config.go
│ │ ├── sys_dict.go
│ │ └── sys_user.go
│ └── apis
│ │ ├── sys_notify.go
│ │ ├── go_admin.go
│ │ └── captcha.go
├── other
│ ├── service
│ │ └── dto
│ │ │ └── sys_tables.go
│ ├── router
│ │ ├── file.go
│ │ ├── monitor.go
│ │ ├── sys_server_monitor.go
│ │ ├── init_router.go
│ │ ├── router.go
│ │ └── gen_router.go
│ ├── apis
│ │ └── tools
│ │ │ ├── db_columns.go
│ │ │ └── db_tables.go
│ └── models
│ │ └── tools
│ │ └── db_tables.go
└── jobs
│ ├── type.go
│ ├── router
│ ├── int_router.go
│ ├── router.go
│ └── sys_job.go
│ ├── examples.go
│ ├── apis
│ └── sys_job.go
│ └── models
│ └── sys_job.go
├── scripts
├── swag.sh
├── k8s
│ └── install.sh
└── migrate.sh
├── cmd
├── migrate
│ └── migration
│ │ ├── version-local
│ │ └── doc.go
│ │ ├── models
│ │ ├── model.go
│ │ ├── role_dept.go
│ │ ├── tb_demo.go
│ │ ├── sys_dict_type.go
│ │ ├── order
│ │ │ ├── user_favorite.go
│ │ │ ├── order_rating.go
│ │ │ ├── order_comment.go
│ │ │ ├── order_category.go
│ │ │ ├── flow_templates.go
│ │ │ ├── order_items.go
│ │ │ ├── flow_manage.go
│ │ │ ├── order_works.go
│ │ │ ├── exec_machine.go
│ │ │ └── common.go
│ │ ├── sys_api.go
│ │ ├── sys_post.go
│ │ ├── by.go
│ │ ├── casbin_rule.go
│ │ ├── sys_config.go
│ │ ├── sys_dept.go
│ │ ├── sys_role.go
│ │ ├── sys_job.go
│ │ ├── sys_dict_data.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu.go
│ │ ├── sys_user.go
│ │ ├── sys_opera_log.go
│ │ ├── initdb.go
│ │ └── sys_tables.go
│ │ ├── version
│ │ ├── 1653638869132_migrate.go
│ │ ├── 1599190683659_tables.go
│ │ └── 1730013300607_migrate.go
│ │ └── init.go
├── api
│ ├── jobs.go
│ ├── other.go
│ └── smart.go
└── cobra.go
├── template
├── cmd_api.template
├── v4
│ ├── no_actions
│ │ ├── router_no_check_role.go.template
│ │ └── router_check_role.go.template
│ ├── actions
│ │ ├── router_no_check_role.go.template
│ │ └── router_check_role.go.template
│ ├── js.go.template
│ └── model.go.template
├── migrate.template
└── router.template
├── .gitignore
├── .github
└── workflows
│ ├── go.yml
│ └── build.yml
├── main.go
├── LICENSE.md
├── test
└── gen_test.go
└── Makefile
/.dockerignore:
--------------------------------------------------------------------------------
1 | config/settings.yml
2 |
--------------------------------------------------------------------------------
/config/db-end-mysql.sql:
--------------------------------------------------------------------------------
1 | SET FOREIGN_KEY_CHECKS = 1;
--------------------------------------------------------------------------------
/config/db-begin-mysql.sql:
--------------------------------------------------------------------------------
1 | SET NAMES utf8mb4;
2 | SET FOREIGN_KEY_CHECKS = 0;
--------------------------------------------------------------------------------
/static/image/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/img.png
--------------------------------------------------------------------------------
/static/image/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/login.png
--------------------------------------------------------------------------------
/static/image/order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/order.png
--------------------------------------------------------------------------------
/static/image/task.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/task.png
--------------------------------------------------------------------------------
/common/actions/type.go:
--------------------------------------------------------------------------------
1 | package actions
2 |
3 | const (
4 | PermissionKey = "dataPermission"
5 | )
6 |
--------------------------------------------------------------------------------
/app/smart/service/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/app/smart/service/.DS_Store
--------------------------------------------------------------------------------
/static/image/customflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/customflow.png
--------------------------------------------------------------------------------
/static/image/orderApply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/orderApply.png
--------------------------------------------------------------------------------
/static/image/statistics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/statistics.png
--------------------------------------------------------------------------------
/static/image/tasktype.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/tasktype.png
--------------------------------------------------------------------------------
/static/image/ordermanage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/ordermanage.png
--------------------------------------------------------------------------------
/static/image/customtemplate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/customtemplate.png
--------------------------------------------------------------------------------
/static/image/orderApply-v2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/image/orderApply-v2.png
--------------------------------------------------------------------------------
/static/form-generator/css/parser-example.69e16e51.css:
--------------------------------------------------------------------------------
1 | .test-form[data-v-77b1aafa]{margin:15px auto;width:800px;padding:15px}
--------------------------------------------------------------------------------
/static/form-generator/img/logo.e1bc3747.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunwenbo/smart-api/HEAD/static/form-generator/img/logo.e1bc3747.png
--------------------------------------------------------------------------------
/scripts/swag.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | swag i -g init_router.go -dir app/smart-api/router --instanceName admin --parseDependency -o docs/smart-api
4 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/version-local/doc.go:
--------------------------------------------------------------------------------
1 | package version_local
2 |
3 | func init() {
4 | }
5 |
6 | /**
7 | 开发者项目的迁移脚本放在这个目录里,init写法参考version目录里的migrate或者自动生成
8 | */
9 |
--------------------------------------------------------------------------------
/common/global/topic.go:
--------------------------------------------------------------------------------
1 | package global
2 |
3 | const (
4 | LoginLog = "login_log_queue"
5 | OperateLog = "operate_log_queue"
6 | ApiCheck = "api_check_queue"
7 | )
8 |
--------------------------------------------------------------------------------
/common/global/adm.go:
--------------------------------------------------------------------------------
1 | package global
2 |
3 | const (
4 | // Version go-admin version info
5 | Version = "1.1.1"
6 | )
7 |
8 | var (
9 | // Driver 数据库驱动
10 | Driver string
11 | )
12 |
--------------------------------------------------------------------------------
/cmd/api/jobs.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import "smart-api/app/jobs/router"
4 |
5 | func init() {
6 | //注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
7 | AppRouters = append(AppRouters, router.InitRouter)
8 | }
9 |
--------------------------------------------------------------------------------
/cmd/api/other.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import "smart-api/app/other/router"
4 |
5 | func init() {
6 | //注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
7 | AppRouters = append(AppRouters, router.InitRouter)
8 | }
9 |
--------------------------------------------------------------------------------
/common/middleware/handler/ping.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | )
6 |
7 | func Ping(c *gin.Context) {
8 | c.JSON(200, gin.H{
9 | "message": "ok",
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/template/cmd_api.template:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import "smart-api/app/{{.appName}}/router"
4 |
5 | func init() {
6 | //注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
7 | AppRouters = append(AppRouters, router.InitRouter)
8 | }
9 |
--------------------------------------------------------------------------------
/common/global/logo.go:
--------------------------------------------------------------------------------
1 | package global
2 |
3 | import "github.com/common-nighthawk/go-figure"
4 |
5 | func SmartLogo() string {
6 | myFigure := figure.NewFigure("Hello, SMART", "", true)
7 | return myFigure.String()
8 | }
9 |
--------------------------------------------------------------------------------
/app/system/service/dto/sys_notify.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | type SysNotify struct {
4 | OrderName string `json:"orderName" binding:"required"` // 工单名称
5 | ReceiveName string `json:"receiveName" binding:"required"` // 接收者名称
6 | }
7 |
--------------------------------------------------------------------------------
/common/models/menu.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | // Menu 菜单中的类型枚举值
4 | const (
5 | // Directory 目录
6 | Directory string = "M"
7 | // Menu 菜单
8 | Menu string = "C"
9 | // Button 按钮
10 | Button string = "F"
11 | )
12 |
--------------------------------------------------------------------------------
/app/system/models/model.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type BaseModel struct {
8 | CreatedAt time.Time `json:"createdAt"`
9 | UpdatedAt time.Time `json:"updatedAt"`
10 | DeletedAt *time.Time `json:"deletedAt"`
11 | }
12 |
--------------------------------------------------------------------------------
/common/models/type.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "gorm.io/gorm/schema"
4 |
5 | type ActiveRecord interface {
6 | schema.Tabler
7 | SetCreateBy(createBy int)
8 | SetUpdateBy(updateBy int)
9 | Generate() ActiveRecord
10 | GetId() interface{}
11 | }
12 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/model.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type BaseModel struct {
8 | CreatedAt time.Time `json:"createdAt"`
9 | UpdatedAt time.Time `json:"updatedAt"`
10 | DeletedAt *time.Time `json:"deletedAt"`
11 | }
12 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/role_dept.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysRoleDept struct {
4 | RoleId int `gorm:"size:11;primaryKey"`
5 | DeptId int `gorm:"size:11;primaryKey"`
6 | }
7 |
8 | func (SysRoleDept) TableName() string {
9 | return "sys_role_dept"
10 | }
11 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/tb_demo.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type TbDemo struct {
4 | Model
5 | Name string `json:"name" gorm:"type:varchar(128);comment:名称"`
6 | ModelTime
7 | ControlBy
8 | }
9 |
10 | func (TbDemo) TableName() string {
11 | return "tb_demo"
12 | }
13 |
--------------------------------------------------------------------------------
/common/models/migrate.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "time"
4 |
5 | type Migration struct {
6 | Version string `gorm:"primaryKey"`
7 | ApplyTime time.Time `gorm:"autoCreateTime"`
8 | }
9 |
10 | func (Migration) TableName() string {
11 | return "sys_migration"
12 | }
13 |
--------------------------------------------------------------------------------
/common/middleware/db.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/go-admin-team/go-admin-core/sdk"
6 | )
7 |
8 | func WithContextDb(c *gin.Context) {
9 | c.Set("db", sdk.Runtime.GetDbByKey(c.Request.Host).WithContext(c))
10 | c.Next()
11 | }
12 |
--------------------------------------------------------------------------------
/app/other/service/dto/sys_tables.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | type SysTableSearch struct {
4 | TBName string `form:"tableName" search:"type:exact;column:table_name;table:table_name"`
5 | TableComment string `form:"tableComment" search:"type:icontains;column:table_comment;table:table_comment"`
6 | }
7 |
--------------------------------------------------------------------------------
/common/dto/order.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "gorm.io/gorm"
5 | "gorm.io/gorm/clause"
6 | )
7 |
8 | func OrderDest(sort string, bl bool) func(db *gorm.DB) *gorm.DB {
9 | return func(db *gorm.DB) *gorm.DB {
10 | return db.Order(clause.OrderByColumn{Column: clause.Column{Name: sort}, Desc: bl})
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/common/file_store/obs_test.go:
--------------------------------------------------------------------------------
1 | package file_store
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestOBSUpload(t *testing.T) {
8 | e := OXS{"", "", "", ""}
9 | var oxs = e.Setup(HuaweiOBS)
10 | err := oxs.UpLoad("test.png", "./test.png")
11 | if err != nil {
12 | t.Error(err)
13 | }
14 | t.Log("ok")
15 | }
16 |
--------------------------------------------------------------------------------
/app/jobs/type.go:
--------------------------------------------------------------------------------
1 | package jobs
2 |
3 | import "github.com/robfig/cron/v3"
4 |
5 | type Job interface {
6 | Run()
7 | addJob(*cron.Cron) (int, error)
8 | }
9 |
10 | type JobExec interface {
11 | Exec(arg interface{}) error
12 | }
13 |
14 | func CallExec(e JobExec, arg interface{}) error {
15 | return e.Exec(arg)
16 | }
17 |
--------------------------------------------------------------------------------
/common/file_store/oss_test.go:
--------------------------------------------------------------------------------
1 | package file_store
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestOSSUpload(t *testing.T) {
8 | // 打括号内填写自己的测试信息即可
9 | e := OXS{}
10 | var oxs = e.Setup(AliYunOSS)
11 | err := oxs.UpLoad("test.png", "./test.png")
12 | if err != nil {
13 | t.Error(err)
14 | }
15 | t.Log("ok")
16 | }
17 |
--------------------------------------------------------------------------------
/scripts/k8s/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # 创建k8s sre 命名空间
3 | kubectl create ns sre
4 |
5 | # 拷贝配置文件
6 | cp ../../config/settings.full.yml settings.yml
7 |
8 | # 创建secret
9 | kubectl create secret generic smart-settings \
10 | --from-file=settings.yml=./settings.yml \
11 | -n sre
12 |
13 | # 部署服务,并挂载secret
14 | kubectl apply -f scripts/smart-api-deploy.yaml
15 |
--------------------------------------------------------------------------------
/cmd/api/smart.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package api
4 |
5 | import (
6 | "fmt"
7 | "smart-api/app/smart/router"
8 | )
9 |
10 | func init() {
11 | fmt.Println("注册Smart api路由...")
12 | //注册Smart路由 fixme 其他应用的路由,自定义注册路由
13 | // AppRouters 在system.go 中定义,将自定义的路由追加到AppRouters切片实现路由注册
14 | AppRouters = append(AppRouters, router.InitRouter)
15 | }
16 |
--------------------------------------------------------------------------------
/common/database/open.go:
--------------------------------------------------------------------------------
1 | //go:build !sqlite3
2 |
3 | package database
4 |
5 | import (
6 | "gorm.io/driver/mysql"
7 | "gorm.io/driver/postgres"
8 | "gorm.io/driver/sqlserver"
9 | "gorm.io/gorm"
10 | )
11 |
12 | var opens = map[string]func(string) gorm.Dialector{
13 | "mysql": mysql.Open,
14 | "postgres": postgres.Open,
15 | "sqlserver": sqlserver.Open,
16 | }
17 |
--------------------------------------------------------------------------------
/common/dto/pagination.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | type Pagination struct {
4 | PageIndex int `form:"pageIndex"`
5 | PageSize int `form:"pageSize"`
6 | }
7 |
8 | func (m *Pagination) GetPageIndex() int {
9 | if m.PageIndex <= 0 {
10 | m.PageIndex = 1
11 | }
12 | return m.PageIndex
13 | }
14 |
15 | func (m *Pagination) GetPageSize() int {
16 | if m.PageSize <= 0 {
17 | m.PageSize = 100
18 | }
19 | return m.PageSize
20 | }
21 |
--------------------------------------------------------------------------------
/common/database/open_sqlite3.go:
--------------------------------------------------------------------------------
1 | //go:build sqlite3
2 | // +build sqlite3
3 |
4 | package database
5 |
6 | import (
7 | "gorm.io/driver/mysql"
8 | "gorm.io/driver/postgres"
9 | "gorm.io/driver/sqlite"
10 | "gorm.io/driver/sqlserver"
11 | "gorm.io/gorm"
12 | )
13 |
14 | var opens = map[string]func(string) gorm.Dialector{
15 | "mysql": mysql.Open,
16 | "postgres": postgres.Open,
17 | "sqlite3": sqlite.Open,
18 | "sqlserver": sqlserver.Open,
19 | }
20 |
--------------------------------------------------------------------------------
/common/dto/type.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "smart-api/common/models"
6 | )
7 |
8 | type Index interface {
9 | Generate() Index
10 | Bind(ctx *gin.Context) error
11 | GetPageIndex() int
12 | GetPageSize() int
13 | GetNeedSearch() interface{}
14 | }
15 |
16 | type Control interface {
17 | Generate() Control
18 | Bind(ctx *gin.Context) error
19 | GenerateM() (models.ActiveRecord, error)
20 | GetId() interface{}
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .vscode
3 | config/settings.yml
4 | config/settings.dev.yml
5 | config/settings.dev.*.yml
6 | config/settings.dev.*.yml.log
7 | */.DS_Store
8 | static/uploadfile
9 | main.exe
10 | *.exe
11 | smart-api
12 | smart-api.exe
13 | temp/
14 | logs/
15 |
16 |
17 | !temp
18 | vendor
19 |
20 | temp/logs
21 | config/settings.dev.yml.log
22 | config/settings.b.dev.yml
23 | cmd/migrate/migration/version-local/*
24 | !cmd/migrate/migration/version-local/doc.go
25 |
26 | # go sum
27 | #go.sum
28 |
--------------------------------------------------------------------------------
/common/service/service.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/go-admin-team/go-admin-core/logger"
7 | "gorm.io/gorm"
8 | )
9 |
10 | type Service struct {
11 | Orm *gorm.DB
12 | Msg string
13 | MsgID string
14 | Log *logger.Helper
15 | Error error
16 | }
17 |
18 | func (db *Service) AddError(err error) error {
19 | if db.Error == nil {
20 | db.Error = err
21 | } else if err != nil {
22 | db.Error = fmt.Errorf("%v; %w", db.Error, err)
23 | }
24 | return db.Error
25 | }
26 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_dict_type.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type DictType struct {
4 | DictId int `gorm:"primaryKey;autoIncrement;" json:"dictId"`
5 | DictName string `gorm:"size:128;" json:"dictName"` //字典名称
6 | DictType string `gorm:"size:128;" json:"dictType"` //字典类型
7 | Status int `gorm:"size:4;" json:"status"` //状态
8 | Remark string `gorm:"size:255;" json:"remark"` //备注
9 | ControlBy
10 | ModelTime
11 | }
12 |
13 | func (DictType) TableName() string {
14 | return "sys_dict_type"
15 | }
16 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/user_favorite.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/13 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type UserFavorites struct {
10 | ID uint `gorm:"primaryKey" json:"id"`
11 | UserID int `gorm:"column:user_id" json:"userId"`
12 | OrderItemID uint `gorm:"column:order_item_id" json:"orderItemId"` // 确保类型一致
13 | models.ControlBy
14 | models.ModelTime
15 | }
16 |
17 | func (*UserFavorites) TableName() string {
18 | return "user_favorites"
19 | }
20 |
--------------------------------------------------------------------------------
/app/other/router/file.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/other/apis"
7 | )
8 |
9 | func init() {
10 | routerCheckRole = append(routerCheckRole, registerFileRouter)
11 | }
12 |
13 | // 需认证的路由代码
14 | func registerFileRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
15 | var api = apis.File{}
16 | r := v1.Group("").Use(authMiddleware.MiddlewareFunc())
17 | {
18 | r.POST("/public/uploadFile", api.UploadFile)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/common/middleware/handler/httpshandler.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/unrolled/secure"
6 |
7 | "github.com/go-admin-team/go-admin-core/sdk/config"
8 | )
9 |
10 | func TlsHandler() gin.HandlerFunc {
11 | return func(c *gin.Context) {
12 | secureMiddleware := secure.New(secure.Options{
13 | SSLRedirect: true,
14 | SSLHost: config.SslConfig.Domain,
15 | })
16 | err := secureMiddleware.Process(c.Writer, c.Request)
17 | if err != nil {
18 | return
19 | }
20 | c.Next()
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_api.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysApi struct {
4 | Id int `json:"id" gorm:"primaryKey;autoIncrement;comment:主键编码"`
5 | Handle string `json:"handle" gorm:"size:128;comment:handle"`
6 | Title string `json:"title" gorm:"size:128;comment:标题"`
7 | Path string `json:"path" gorm:"size:128;comment:地址"`
8 | Type string `json:"type" gorm:"size:16;comment:接口类型"`
9 | Action string `json:"action" gorm:"size:16;comment:请求类型"`
10 | ModelTime
11 | ControlBy
12 | }
13 |
14 | func (SysApi) TableName() string {
15 | return "sys_api"
16 | }
--------------------------------------------------------------------------------
/common/file_store/kodo_test.go:
--------------------------------------------------------------------------------
1 | package file_store
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestKODOUpload(t *testing.T) {
8 | e := OXS{"", "", "", ""}
9 | var oxs = e.Setup(QiNiuKodo, map[string]interface{}{"Zone": "华东"})
10 | err := oxs.UpLoad("test.png", "./test.png")
11 | if err != nil {
12 | t.Error(err)
13 | }
14 | t.Log("ok")
15 | }
16 |
17 | func TestKODOGetTempToken(t *testing.T) {
18 | e := OXS{"", "", "", ""}
19 | var oxs = e.Setup(QiNiuKodo, map[string]interface{}{"Zone": "华东"})
20 | token, _ := oxs.GetTempToken()
21 | t.Log(token)
22 | t.Log("ok")
23 | }
24 |
--------------------------------------------------------------------------------
/app/other/router/monitor.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gin-gonic/gin"
7 | "github.com/go-admin-team/go-admin-core/tools/transfer"
8 | "github.com/prometheus/client_golang/prometheus/promhttp"
9 | )
10 |
11 | func init() {
12 | routerNoCheckRole = append(routerNoCheckRole, registerMonitorRouter)
13 | }
14 |
15 | // 不需认证的路由代码
16 | func registerMonitorRouter(v1 *gin.RouterGroup) {
17 | v1.GET("/metrics", transfer.Handler(promhttp.Handler()))
18 | //健康检查
19 | v1.GET("/health", func(c *gin.Context) {
20 | c.Status(http.StatusOK)
21 | })
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/common/global/casbin.go:
--------------------------------------------------------------------------------
1 | package global
2 |
3 | import (
4 | "github.com/casbin/casbin/v2"
5 | "github.com/gin-gonic/gin"
6 | "github.com/go-admin-team/go-admin-core/sdk"
7 | "github.com/go-admin-team/go-admin-core/sdk/api"
8 | )
9 |
10 | func LoadPolicy(c *gin.Context) (*casbin.SyncedEnforcer, error) {
11 | log := api.GetRequestLogger(c)
12 | if err := sdk.Runtime.GetCasbinKey(c.Request.Host).LoadPolicy(); err == nil {
13 | return sdk.Runtime.GetCasbinKey(c.Request.Host), err
14 | } else {
15 | log.Errorf("casbin rbac_model or policy init error, %s ", err.Error())
16 | return nil, err
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_post.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysPost struct {
4 | PostId int `gorm:"primaryKey;autoIncrement" json:"postId"` //岗位编号
5 | PostName string `gorm:"size:128;" json:"postName"` //岗位名称
6 | PostCode string `gorm:"size:128;" json:"postCode"` //岗位代码
7 | Sort int `gorm:"size:4;" json:"sort"` //岗位排序
8 | Status int `gorm:"size:4;" json:"status"` //状态
9 | Remark string `gorm:"size:255;" json:"remark"` //描述
10 | ControlBy
11 | ModelTime
12 | }
13 |
14 | func (SysPost) TableName() string {
15 | return "sys_post"
16 | }
--------------------------------------------------------------------------------
/app/smart/models/order_rating.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/8/17 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type OrderRating struct {
10 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
11 | OrderID int `gorm:"column:order_id" json:"orderID"` // 与工单ID关联
12 | Ratings int `gorm:"column:rating;type:int" json:"ratings"` // 评分
13 | Taskhandler int `gorm:"column:task_handler;type:int" json:"taskHandler"` // 评分所有人
14 | models.ControlBy
15 | models.ModelTime
16 | }
17 |
18 | func (*OrderRating) TableName() string {
19 | return "order_rating"
20 | }
21 |
--------------------------------------------------------------------------------
/app/system/router/sys_notify.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerSysNotifyRouter)
12 | }
13 |
14 | // 需认证的路由代码
15 | func registerSysNotifyRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.SysNotify{}
17 |
18 | r := v1.Group("/notify").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
19 | {
20 | r.POST("", api.NotifySend)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/by.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "gorm.io/gorm"
5 | "smart-api/common/models"
6 | )
7 |
8 | type ControlBy struct {
9 | CreateBy int `json:"createBy" gorm:"index;comment:创建者"`
10 | UpdateBy int `json:"updateBy" gorm:"index;comment:更新者"`
11 | }
12 |
13 | type Model struct {
14 | Id int `json:"id" gorm:"primaryKey;autoIncrement;comment:主键编码"`
15 | }
16 |
17 | type ModelTime struct {
18 | CreatedAt models.JSONTime `json:"createdAt" gorm:"comment:创建时间"`
19 | UpdatedAt models.JSONTime `json:"updatedAt" gorm:"comment:最后更新时间"`
20 | DeletedAt gorm.DeletedAt `json:"-" gorm:"index;comment:删除时间"`
21 | }
22 |
--------------------------------------------------------------------------------
/app/system/models/casbin_rule.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type CasbinRule struct {
4 | ID uint `gorm:"primaryKey;autoIncrement"`
5 | Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
6 | V0 string `gorm:"size:512;uniqueIndex:unique_index"`
7 | V1 string `gorm:"size:512;uniqueIndex:unique_index"`
8 | V2 string `gorm:"size:512;uniqueIndex:unique_index"`
9 | V3 string `gorm:"size:512;uniqueIndex:unique_index"`
10 | V4 string `gorm:"size:512;uniqueIndex:unique_index"`
11 | V5 string `gorm:"size:512;uniqueIndex:unique_index"`
12 | }
13 |
14 | func (CasbinRule) TableName() string {
15 | return "sys_casbin_rule"
16 | }
17 |
--------------------------------------------------------------------------------
/common/ip.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "strings"
6 | )
7 |
8 | func GetClientIP(c *gin.Context) string {
9 | ClientIP := c.ClientIP()
10 | //fmt.Println("ClientIP:", ClientIP)
11 | RemoteIP := c.RemoteIP()
12 | //fmt.Println("RemoteIP:", RemoteIP)
13 | ip := c.Request.Header.Get("X-Forwarded-For")
14 | if strings.Contains(ip, "127.0.0.1") || ip == "" {
15 | ip = c.Request.Header.Get("X-real-ip")
16 | }
17 | if ip == "" {
18 | ip = "127.0.0.1"
19 | }
20 | if RemoteIP != "127.0.0.1" {
21 | ip = RemoteIP
22 | }
23 | if ClientIP != "127.0.0.1" {
24 | ip = ClientIP
25 | }
26 | return ip
27 | }
28 |
--------------------------------------------------------------------------------
/.github/workflows/go.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a golang project
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
3 |
4 | name: Go
5 |
6 | on:
7 | push:
8 | branches: [ "main" ]
9 | pull_request:
10 | branches: [ "main" ]
11 |
12 | jobs:
13 |
14 | build:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@v4
18 |
19 | - name: Set up Go
20 | uses: actions/setup-go@v4
21 | with:
22 | go-version: '1.24'
23 |
24 | - name: Build
25 | run: go build -v ./...
26 |
27 | - name: Test
28 | run: go test -v ./...
29 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/order_rating.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/8/17 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type OrderRating struct {
10 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
11 | OrderID int `gorm:"column:order_id" json:"orderID"` // 与工单ID关联
12 | Ratings int `gorm:"column:rating;type:int" json:"ratings"` // 评分
13 | Taskhandler int `gorm:"column:task_handler;type:int" json:"taskHandler"` // 评分所有人
14 | models.ControlBy
15 | models.ModelTime
16 | }
17 |
18 | func (*OrderRating) TableName() string {
19 | return "order_rating"
20 | }
21 |
--------------------------------------------------------------------------------
/app/other/router/sys_server_monitor.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/other/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerSysServerMonitorRouter)
12 | }
13 |
14 | // 需认证的路由代码
15 | func registerSysServerMonitorRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.ServerMonitor{}
17 | r := v1.Group("/server-monitor").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
18 | {
19 | r.GET("", api.ServerInfo)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "smart-api/cmd"
5 | )
6 |
7 | //go:generate swag init --parseDependency --parseDepth=6 --instanceName smart -o ./docs/smart
8 |
9 | // @title smart-api API
10 | // @version 1.0.0
11 | // @description 基于Gin + Vue + Element UI的前后端分离运维工单系统的接口文档
12 | // @description 添加qq群: xxxx 进入技术交流群 请先star,谢谢!
13 | // @license.name MIT
14 | // @contact.email swb956721830@163.com
15 |
16 | // @license.name Apache 2.0
17 | // @license.url https://github.com/sunwenbo/smart-api/blob/master/LICENSE.md
18 |
19 | // @securityDefinitions.apikey Bearer
20 | // @in header
21 | // @name Authorization
22 |
23 | func main() {
24 | cmd.Execute()
25 | }
26 |
--------------------------------------------------------------------------------
/static/form-generator/js/tinymce-example.641995ab.js:
--------------------------------------------------------------------------------
1 | (window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["tinymce-example"],{a5aa:function(e,t,n){"use strict";n.r(t);var a=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[n("Tinymce",{attrs:{height:300,placeholder:"在这里输入文字"},model:{value:e.defaultValue,callback:function(t){e.defaultValue=t},expression:"defaultValue"}})],1)},c=[],u=n("31c6"),l={components:{Tinymce:u["a"]},props:{},data:function(){return{defaultValue:"
配置文档参阅:http://tinymce.ax-z.cn
"}},computed:{},watch:{},created:function(){},mounted:function(){},methods:{}},o=l,i=n("2877"),p=Object(i["a"])(o,a,c,!1,null,null,null);t["default"]=p.exports}}]);
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/order_comment.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/8/17 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type OrderComment struct {
10 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
11 | OrderID int `gorm:"column:order_id" json:"orderID"` // 与工单ID关联
12 | ParentID *int `gorm:"column:parent_id" json:"parentID"` // 父留言ID,如果为空表示是顶级留言
13 | Comments string `gorm:"column:comment;type:varchar(255)" json:"comments"` // 留言内容
14 | models.ControlBy
15 | models.ModelTime
16 | }
17 |
18 | func (*OrderComment) TableName() string {
19 | return "order_comment"
20 | }
21 |
--------------------------------------------------------------------------------
/common/global/pagingquery.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/16 12:05
3 | package global
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | "strconv"
8 | )
9 |
10 | func PagingQuery(c *gin.Context) (pageNum, limit int) {
11 | // 从请求中获取分页参数
12 | page := c.Query("page")
13 | pageSize := c.Query("pageSize")
14 |
15 | // 默认分页参数,你也可以根据需求自定义默认值
16 | defaultPage := 1
17 | defaultPageSize := 9999
18 |
19 | // 将字符串参数转换为整数,处理可能的错误
20 | pageNum, err := strconv.Atoi(page)
21 | if err != nil || pageNum < 1 {
22 | pageNum = defaultPage
23 | }
24 | limit, err = strconv.Atoi(pageSize)
25 | if err != nil || limit < 1 {
26 | limit = defaultPageSize
27 | }
28 | return
29 | }
30 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/casbin_rule.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | // CasbinRule sys_casbin_rule
4 | type CasbinRule struct {
5 | ID uint `gorm:"primaryKey;autoIncrement"`
6 | Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
7 | V0 string `gorm:"size:512;uniqueIndex:unique_index"`
8 | V1 string `gorm:"size:512;uniqueIndex:unique_index"`
9 | V2 string `gorm:"size:512;uniqueIndex:unique_index"`
10 | V3 string `gorm:"size:512;uniqueIndex:unique_index"`
11 | V4 string `gorm:"size:512;uniqueIndex:unique_index"`
12 | V5 string `gorm:"size:512;uniqueIndex:unique_index"`
13 | }
14 |
15 | func (CasbinRule) TableName() string {
16 | return "sys_casbin_rule"
17 | }
18 |
--------------------------------------------------------------------------------
/app/smart/models/user_favorite.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/13 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type UserFavorites struct {
10 | ID uint `gorm:"primaryKey" json:"id"`
11 | UserID int `gorm:"column:user_id" json:"userId"`
12 | OrderItemID uint `gorm:"column:order_item_id" json:"orderItemId"` // 确保类型一致
13 | models.ControlBy
14 | models.ModelTime
15 | }
16 |
17 | func (*UserFavorites) TableName() string {
18 | return "user_favorites"
19 | }
20 | func (e *UserFavorites) Generate() models.ActiveRecord {
21 | o := *e
22 | return &o
23 | }
24 |
25 | func (e *UserFavorites) GetId() interface{} {
26 | return e.ID
27 | }
28 |
--------------------------------------------------------------------------------
/app/system/router/sys_opera_log.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerSysOperaLogRouter)
12 | }
13 |
14 | // 需认证的路由代码
15 | func registerSysOperaLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.SysOperaLog{}
17 | r := v1.Group("/sys-opera-log").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
18 | {
19 | r.GET("", api.GetPage)
20 | r.GET("/:id", api.Get)
21 | r.DELETE("", api.Delete)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/system/router/sys_login_log.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerSysLoginLogRouter)
12 | }
13 |
14 | // 需认证的路由代码
15 | func registerSysLoginLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.SysLoginLog{}
17 |
18 | r := v1.Group("/sys-login-log").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
19 | {
20 | r.GET("", api.GetPage)
21 | r.GET("/:id", api.Get)
22 | r.DELETE("", api.Delete)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_config.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysConfig struct {
4 | Model
5 | ConfigName string `json:"configName" gorm:"type:varchar(128);comment:ConfigName"`
6 | ConfigKey string `json:"configKey" gorm:"type:varchar(128);comment:ConfigKey"`
7 | ConfigValue string `json:"configValue" gorm:"type:varchar(255);comment:ConfigValue"`
8 | ConfigType string `json:"configType" gorm:"type:varchar(64);comment:ConfigType"`
9 | IsFrontend int `json:"isFrontend" gorm:"type:varchar(64);comment:是否前台"`
10 | Remark string `json:"remark" gorm:"type:varchar(128);comment:Remark"`
11 | ControlBy
12 | ModelTime
13 | }
14 |
15 | func (SysConfig) TableName() string {
16 | return "sys_config"
17 | }
18 |
--------------------------------------------------------------------------------
/common/models/response.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type Response struct {
4 | // 代码
5 | Code int `json:"code" example:"200"`
6 | // 数据集
7 | Data interface{} `json:"data"`
8 | // 消息
9 | Msg string `json:"msg"`
10 | RequestId string `json:"requestId"`
11 | }
12 |
13 | type Page struct {
14 | List interface{} `json:"list"`
15 | Count int `json:"count"`
16 | PageIndex int `json:"pageIndex"`
17 | PageSize int `json:"pageSize"`
18 | }
19 |
20 | // ReturnOK 正常返回
21 | func (res *Response) ReturnOK() *Response {
22 | res.Code = 200
23 | return res
24 | }
25 |
26 | // ReturnError 错误返回
27 | func (res *Response) ReturnError(code int) *Response {
28 | res.Code = code
29 | return res
30 | }
31 |
--------------------------------------------------------------------------------
/app/system/router/sys_api.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 |
7 | "smart-api/app/system/apis"
8 | "smart-api/common/middleware"
9 | )
10 |
11 | func init() {
12 | routerCheckRole = append(routerCheckRole, registerSysApiRouter)
13 | }
14 |
15 | // registerSysApiRouter
16 | func registerSysApiRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
17 | api := apis.SysApi{}
18 | r := v1.Group("/sys-api").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
19 | {
20 | r.GET("", api.GetPage)
21 | r.GET("/:id", api.Get)
22 | r.PUT("/:id", api.Update)
23 | r.DELETE("", api.DeleteSysApi)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/system/router/sys_post.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerSyPostRouter)
12 | }
13 |
14 | // 需认证的路由代码
15 | func registerSyPostRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.SysPost{}
17 | r := v1.Group("/post").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
18 | {
19 | r.GET("", api.GetPage)
20 | r.GET("/:id", api.Get)
21 | r.POST("", api.Insert)
22 | r.PUT("/:id", api.Update)
23 | r.DELETE("", api.Delete)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/common/file_store/interface.go:
--------------------------------------------------------------------------------
1 | package file_store
2 |
3 | // DriverType 驱动类型
4 | type DriverType string
5 |
6 | const (
7 | // HuaweiOBS 华为云OBS
8 | HuaweiOBS DriverType = "HuaweiOBS"
9 | // AliYunOSS 阿里云OSS
10 | AliYunOSS DriverType = "AliYunOSS"
11 | // QiNiuKodo 七牛云kodo
12 | QiNiuKodo DriverType = "QiNiuKodo"
13 | )
14 |
15 | type ClientOption map[string]interface{}
16 |
17 | // TODO: FileStoreType名称待定
18 |
19 | // FileStoreType OXS
20 | type FileStoreType interface {
21 | // Setup 装载 endpoint sss
22 | Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error
23 | // UpLoad 上传
24 | UpLoad(yourObjectName string, localFile interface{}) error
25 | // GetTempToken 获取临时Token
26 | GetTempToken() (string, error)
27 | }
28 |
--------------------------------------------------------------------------------
/template/v4/no_actions/router_no_check_role.go.template:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 |
7 | "smart-api/app/{{.PackageName}}/apis"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, register{{.ClassName}}Router)
12 | }
13 |
14 | // register{{.ClassName}}Router
15 | func register{{.ClassName}}Router(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.{{.ClassName}}{}
17 | r := v1.Group("/{{.ModuleName}}").Use(authMiddleware.MiddlewareFunc())
18 | {
19 | r.GET("", api.GetPage)
20 | r.GET("/:id", api.Get)
21 | r.POST("", api.Insert)
22 | r.PUT("/:id", api.Update)
23 | r.DELETE("", api.Delete)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/scripts/migrate.sh:
--------------------------------------------------------------------------------
1 | ./smart migrate -a true -g true
2 | ./smart migrate -c config/settings.yml
3 |
4 | 生成迁移文件
5 | go run main.go migrate -g true -c config/settings.yml
6 |
7 | 修改完迁移文件后,执行下面命令开始变更
8 | go run main.go migrate -c config/settings.yml
9 |
10 | go run main.go migrate -h # 帮助
11 | go run main.go migrate -g true -a true -c config/settings.dev.yml # 生成 smart系统预置 迁移文件
12 | go run main.go migrate -g true -c config/settings.dev.yml # 生成 自定义功能 迁移文件 自己开发新功能用这个功能
13 | go run main.go migrate -c config/settings.dev.yml # 执行迁移命令 迁移 未迁移过的 文件
14 |
15 |
16 | 生成迁移文件
17 | go run main.go migrate -g true -c config/settings.yml
18 |
19 | 修改完迁移文件后,执行下面命令开始变更
20 | go run main.go migrate -c config/settings.yml
21 |
22 | 生成迁移文件--系统相关
23 | go run main.go migrate -g true -a true -c config/settings.yml
24 |
--------------------------------------------------------------------------------
/app/smart/router/user_favorite.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerUserFavoriteAuthRouter)
14 | }
15 |
16 | // registerSysApiRouter 需要JWT认证
17 | func registerUserFavoriteAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | api := apis.UserFavorites{}
19 | r := v1.Group("/favorite").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | r.POST("", api.AddFavorite)
22 | r.DELETE("", api.RemoveFavorite)
23 | r.GET("", api.GetUserFavorites)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/system/models/sys_dict_type.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "smart-api/common/models"
5 | )
6 |
7 | type SysDictType struct {
8 | ID int `json:"id" gorm:"primaryKey;column:dict_id;autoIncrement;comment:主键编码"`
9 | DictName string `json:"dictName" gorm:"size:128;comment:DictName"`
10 | DictType string `json:"dictType" gorm:"size:128;comment:DictType"`
11 | Status int `json:"status" gorm:"size:4;comment:Status"`
12 | Remark string `json:"remark" gorm:"size:255;comment:Remark"`
13 | models.ControlBy
14 | models.ModelTime
15 | }
16 |
17 | func (*SysDictType) TableName() string {
18 | return "sys_dict_type"
19 | }
20 |
21 | func (e *SysDictType) Generate() models.ActiveRecord {
22 | o := *e
23 | return &o
24 | }
25 |
26 | func (e *SysDictType) GetId() interface{} {
27 | return e.ID
28 | }
29 |
--------------------------------------------------------------------------------
/app/smart/router/flow_templates.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerFlowTemplatesAuthRouter)
14 | }
15 |
16 | // 注册工单模板路由
17 | func registerFlowTemplatesAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | api := apis.FlowTemplates{}
19 | r := v1.Group("/flow-templates").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | r.GET("", api.GetPage)
22 | r.GET("/:id", api.Get)
23 | r.POST("", api.Insert)
24 | r.PUT("", api.Update)
25 | r.DELETE("", api.Delete)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/smart/router/order_category.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerOrderCategoryAuthRouter)
14 | }
15 |
16 | // 注册工单类别路由
17 | func registerOrderCategoryAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | api := apis.OrderCategory{}
19 | r := v1.Group("/order-category").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | r.GET("", api.GetPage)
22 | r.GET("/:id", api.Get)
23 | r.POST("", api.Insert)
24 | r.PUT("", api.Update)
25 | r.DELETE("", api.Delete)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/smart/router/order_items.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerOrderItemsAuthRouter)
14 | }
15 |
16 | // registerSysApiRouter 需要JWT认证
17 | func registerOrderItemsAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | api := apis.OrderItems{}
19 | r := v1.Group("/order-items").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | r.GET("", api.GetPage)
22 | r.GET("/:id", api.Get)
23 | r.POST("", api.Insert)
24 | r.PUT("", api.Update)
25 | r.DELETE("", api.Delete)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/smart/models/order_comment.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/8/17 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type OrderComment struct {
10 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
11 | OrderID int `gorm:"column:order_id" json:"orderID"` // 与工单ID关联
12 | ParentID *int `gorm:"column:parent_id" json:"parentID"` // 父留言ID,如果为空表示是顶级留言
13 | Comments string `gorm:"column:comment;type:varchar(255)" json:"comments"` // 留言内容
14 | models.ControlBy
15 | models.ModelTime
16 | }
17 |
18 | func (*OrderComment) TableName() string {
19 | return "order_comment"
20 | }
21 |
22 | func (e *OrderComment) Generate() models.ActiveRecord {
23 | o := *e
24 | return &o
25 | }
26 |
27 | func (e *OrderComment) GetId() interface{} {
28 | return e.ID
29 | }
30 |
--------------------------------------------------------------------------------
/common/middleware/trace.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/opentracing/opentracing-go"
6 | )
7 |
8 | // Trace 链路追踪
9 | func Trace() gin.HandlerFunc {
10 | return func(ctx *gin.Context) {
11 | var sp opentracing.Span
12 | opName := ctx.Request.URL.Path
13 | // Attempt to join a trace by getting trace context from the headers.
14 | wireContext, err := opentracing.GlobalTracer().Extract(
15 | opentracing.TextMap,
16 | opentracing.HTTPHeadersCarrier(ctx.Request.Header))
17 | if err != nil {
18 | // If for whatever reason we can't join, go ahead and start a new root span.
19 | sp = opentracing.StartSpan(opName)
20 | } else {
21 | sp = opentracing.StartSpan(opName, opentracing.ChildOf(wireContext))
22 | }
23 | ctx.Set("traceSpan", sp)
24 | ctx.Next()
25 | sp.Finish()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/common/middleware/sentinel.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "github.com/alibaba/sentinel-golang/core/system"
5 | sentinel "github.com/alibaba/sentinel-golang/pkg/adapters/gin"
6 | "github.com/gin-gonic/gin"
7 |
8 | log "github.com/go-admin-team/go-admin-core/logger"
9 | )
10 |
11 | // Sentinel 限流
12 | func Sentinel() gin.HandlerFunc {
13 | if _, err := system.LoadRules([]*system.Rule{
14 | {
15 | MetricType: system.InboundQPS,
16 | TriggerCount: 200,
17 | Strategy: system.BBR,
18 | },
19 | }); err != nil {
20 | log.Fatalf("Unexpected error: %+v", err)
21 | }
22 | return sentinel.SentinelMiddleware(
23 | sentinel.WithBlockFallback(func(ctx *gin.Context) {
24 | ctx.AbortWithStatusJSON(200, map[string]interface{}{
25 | "msg": "too many request; the quota used up!",
26 | "code": 500,
27 | })
28 | }),
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_dept.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysDept struct {
4 | DeptId int `json:"deptId" gorm:"primaryKey;autoIncrement;"` //部门编码
5 | ParentId int `json:"parentId" gorm:""` //上级部门
6 | DeptPath string `json:"deptPath" gorm:"size:255;"` //
7 | DeptName string `json:"deptName" gorm:"size:128;"` //部门名称
8 | Sort int `json:"sort" gorm:"size:4;"` //排序
9 | Leader string `json:"leader" gorm:"size:128;"` //负责人
10 | Phone string `json:"phone" gorm:"size:11;"` //手机
11 | Email string `json:"email" gorm:"size:64;"` //邮箱
12 | Status int `json:"status" gorm:"size:4;"` //状态
13 | ControlBy
14 | ModelTime
15 | }
16 |
17 | func (SysDept) TableName() string {
18 | return "sys_dept"
19 | }
20 |
--------------------------------------------------------------------------------
/app/system/router/sys_dept.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerSysDeptRouter)
12 | }
13 |
14 | // 需认证的路由代码
15 | func registerSysDeptRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.SysDept{}
17 |
18 | r := v1.Group("/dept").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
19 | {
20 | r.GET("", api.GetPage)
21 | r.GET("/:id", api.Get)
22 | r.POST("", api.Insert)
23 | r.PUT("/:id", api.Update)
24 | r.DELETE("", api.Delete)
25 | }
26 |
27 | r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
28 | {
29 | r1.GET("/deptTree", api.Get2Tree)
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/app/jobs/router/int_router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | //"github.com/go-admin-team/go-admin-core/sdk/pkg"
5 | "os"
6 |
7 | "github.com/gin-gonic/gin"
8 | log "github.com/go-admin-team/go-admin-core/logger"
9 | "github.com/go-admin-team/go-admin-core/sdk"
10 | common "smart-api/common/middleware"
11 | )
12 |
13 | // InitRouter 路由初始化,不要怀疑,这里用到了
14 | func InitRouter() {
15 | var r *gin.Engine
16 | h := sdk.Runtime.GetEngine()
17 | if h == nil {
18 | log.Fatal("not found engine...")
19 | os.Exit(-1)
20 | }
21 | switch h.(type) {
22 | case *gin.Engine:
23 | r = h.(*gin.Engine)
24 | default:
25 | log.Fatal("not support other engine")
26 | os.Exit(-1)
27 | }
28 |
29 | authMiddleware, err := common.AuthInit()
30 | if err != nil {
31 | log.Fatalf("JWT Init Error, %s", err.Error())
32 | }
33 |
34 | // 注册业务路由
35 | initRouter(r, authMiddleware)
36 | }
37 |
--------------------------------------------------------------------------------
/app/smart/router/init_router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "os"
5 |
6 | "github.com/gin-gonic/gin"
7 | log "github.com/go-admin-team/go-admin-core/logger"
8 | "github.com/go-admin-team/go-admin-core/sdk"
9 | common "smart-api/common/middleware"
10 | )
11 |
12 | // Smart Api自定义路由
13 | func InitRouter() {
14 | var r *gin.Engine
15 | h := sdk.Runtime.GetEngine()
16 | if h == nil {
17 | log.Fatal("not found engine...")
18 | os.Exit(-1)
19 | }
20 | switch h.(type) {
21 | case *gin.Engine:
22 | r = h.(*gin.Engine)
23 | default:
24 | log.Fatal("not support smart-api engine")
25 | os.Exit(-1)
26 | }
27 | // the jwt middleware
28 | authMiddleware, err := common.AuthInit()
29 | if err != nil {
30 | log.Fatalf("JWT Init Error, %s", err.Error())
31 | }
32 |
33 | // 注册业务路由
34 | // TODO: 这里存放业务路由,当前目录下的router.go
35 | initRouter(r, authMiddleware)
36 | }
37 |
--------------------------------------------------------------------------------
/app/other/router/init_router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "os"
5 |
6 | "github.com/gin-gonic/gin"
7 | log "github.com/go-admin-team/go-admin-core/logger"
8 | "github.com/go-admin-team/go-admin-core/sdk"
9 | common "smart-api/common/middleware"
10 | )
11 |
12 | // InitRouter 路由初始化,不要怀疑,这里用到了
13 | func InitRouter() {
14 | var r *gin.Engine
15 | h := sdk.Runtime.GetEngine()
16 | if h == nil {
17 | log.Fatal("not found engine...")
18 | os.Exit(-1)
19 | }
20 | switch h.(type) {
21 | case *gin.Engine:
22 | r = h.(*gin.Engine)
23 | default:
24 | log.Fatal("not support other engine")
25 | os.Exit(-1)
26 | }
27 | // the jwt middleware
28 | authMiddleware, err := common.AuthInit()
29 | if err != nil {
30 | log.Fatalf("JWT Init Error, %s", err.Error())
31 | }
32 |
33 | // 注册业务路由
34 | // TODO: 这里可存放业务路由,里边并无实际路由只有演示代码
35 | initRouter(r, authMiddleware)
36 | }
37 |
--------------------------------------------------------------------------------
/config/settings.demo.yml:
--------------------------------------------------------------------------------
1 | settings:
2 | application:
3 | demomsg: "谢谢您的参与,但为了大家更好的体验,所以本次提交就算了吧!\U0001F600\U0001F600\U0001F600"
4 | enabledp: true
5 | host: 0.0.0.0
6 | mode: demo
7 | name: testApp
8 | port: 8000
9 | readtimeout: 10000
10 | writertimeout: 20000
11 | database:
12 | driver: sqlite3
13 | source: ./smart-api-db.db
14 | gen:
15 | dbname: testhhh
16 | frontpath: ../smart-api-ui/src
17 | jwt:
18 | secret: smart-api
19 | timeout: 3600
20 | logger:
21 | # 日志存放路径
22 | path: temp/logs
23 | # 日志输出,file:文件,default:命令行,其他:命令行
24 | stdout: '' #控制台日志,启用后,不输出到文件
25 | # 日志等级, trace, debug, info, warn, error, fatal
26 | level: trace
27 | # 数据库日志开关
28 | enableddb: true
29 | queue:
30 | memory:
31 | poolSize: 100
32 | extend:
33 | amap:
34 | key: de7a062c984bf828d5d1b3a631a517e4
35 |
--------------------------------------------------------------------------------
/app/system/apis/sys_notify.go:
--------------------------------------------------------------------------------
1 | package apis
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/gin-gonic/gin/binding"
6 | "github.com/go-admin-team/go-admin-core/sdk/api"
7 | _ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
8 | "smart-api/app/system/service"
9 | "smart-api/app/system/service/dto"
10 | )
11 |
12 | type SysNotify struct {
13 | api.Api
14 | }
15 |
16 | func (e SysNotify) NotifySend(c *gin.Context) {
17 | s := service.SysNotify{}
18 | req := dto.SysNotify{}
19 | err := e.MakeContext(c).
20 | MakeOrm().
21 | Bind(&req, binding.JSON).
22 | MakeService(&s.Service).
23 | Errors
24 | if err != nil {
25 | e.Logger.Error(err)
26 | e.Error(500, err, err.Error())
27 | return
28 | }
29 |
30 | // 设置创建
31 | err = s.SendMessage(&req)
32 | if err != nil {
33 | e.Error(500, err, "发送通知失败")
34 | return
35 | }
36 | e.OK(nil, "通知发送成功")
37 | }
38 |
--------------------------------------------------------------------------------
/app/smart/router/flow_manage.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/actions"
10 | "smart-api/common/middleware"
11 | )
12 |
13 | func init() {
14 | routerCheckRole = append(routerCheckRole, registerFlowManageAuthRouter)
15 | }
16 |
17 | // 注册工单模板路由
18 | func registerFlowManageAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
19 | api := apis.FlowManage{}
20 | r := v1.Group("/flow-manage").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()).Use(actions.PermissionAction())
21 | {
22 | r.POST("", api.Insert)
23 | r.POST("/:id", api.Clone)
24 | r.GET("", api.GetPage)
25 | r.GET("/:id", api.Get)
26 | r.PUT("", api.Update)
27 | r.DELETE("", api.Delete)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/config/extend.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | var ExtConfig *Extend
4 |
5 | // Extend 扩展配置
6 | //
7 | // extend:
8 | // demo:
9 | // name: demo-name
10 | //
11 | // 使用方法: config.ExtConfig......即可!!
12 |
13 | type Extend struct {
14 | Ldap *Ldap // 这里配置对应配置文件的结构即可
15 | Notify *Notify
16 | AesSecrets *AesSecrets // 对称加密 key
17 | }
18 |
19 | type Ldap struct {
20 | Host string `yaml:"host"`
21 | Tls bool `yaml:"tls"`
22 | Port int `yaml:"port"`
23 | BindDN string `yaml:"bindDN"`
24 | BindPassword string `yaml:"bindPassword"`
25 | SearchDomain string `yaml:"searchDomain"`
26 | }
27 |
28 | type Notify struct {
29 | BotCredit *BotCredit `yaml:"bot_credit"`
30 | }
31 |
32 | type BotCredit struct {
33 | AppID string `yaml:"appid" `
34 | AppSecret string `yaml:"app_secret" `
35 | }
36 |
37 | type AesSecrets struct {
38 | Key string `yaml:"key"`
39 | }
40 |
--------------------------------------------------------------------------------
/app/system/apis/go_admin.go:
--------------------------------------------------------------------------------
1 | package apis
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | )
6 |
7 | const INDEX = `
8 |
9 |
10 |
11 |
12 | Smart 欢迎您
13 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 | `
35 |
36 | func GoAdmin(c *gin.Context) {
37 | c.Header("Content-Type", "text/html; charset=utf-8")
38 | c.String(200, INDEX)
39 | }
40 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/order_category.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/16 21:14
3 | package models
4 |
5 | import (
6 | models2 "smart-api/cmd/migrate/migration/models"
7 | )
8 |
9 | type OrderCategory struct {
10 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
11 | Name string `gorm:"column:name;type:varchar(50)" json:"name"`
12 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
13 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
14 | ChineseName string `gorm:"column:chineseName;type:varchar(50)" json:"chineseName"`
15 | FlowTemplates []FlowTemplates `gorm:"foreignKey:CategoryID" json:"flowTemplates"`
16 | models2.ControlBy
17 | models2.ModelTime
18 | }
19 |
20 | func (OrderCategory) TableName() string {
21 | return "order_category"
22 | }
23 |
--------------------------------------------------------------------------------
/app/smart/router/order_statistics.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/9/25 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerOrderStatisticsAuthRouter)
14 | }
15 |
16 | // registerSysApiRouter 需要JWT认证
17 | func registerOrderStatisticsAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | api := apis.OrderStatistics{}
19 | r := v1.Group("/statistics").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | r.GET("/orders", api.GetOrderStatistics) // 获取工单统计
22 | r.GET("/orders/count", api.GetOrderCountByPeriod) // 根据周或月统计工单数量,以及个人提交排行榜
23 |
24 | r.GET("/ratings", api.GetOrderRatingsByPeriod) // 根据周或月统计获取评分统计
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/system/router/sys_menu.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerSysMenuRouter)
12 | }
13 |
14 | // 需认证的路由代码
15 | func registerSysMenuRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
16 | api := apis.SysMenu{}
17 |
18 | r := v1.Group("/menu").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
19 | {
20 | r.GET("", api.GetPage)
21 | r.GET("/:id", api.Get)
22 | r.POST("", api.Insert)
23 | r.PUT("/:id", api.Update)
24 | r.DELETE("", api.Delete)
25 | }
26 |
27 | r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
28 | {
29 | r1.GET("/menurole", api.GetMenuRole)
30 | //r1.GET("/menuids", api.GetMenuIDS)
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/system/router/sys_role.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 |
7 | "smart-api/app/system/apis"
8 | "smart-api/common/middleware"
9 | )
10 |
11 | func init() {
12 | routerCheckRole = append(routerCheckRole, registerSysRoleRouter)
13 | }
14 |
15 | // 需认证的路由代码
16 | func registerSysRoleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
17 | api := apis.SysRole{}
18 | r := v1.Group("/role").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
19 | {
20 | r.GET("", api.GetPage)
21 | r.GET("/:id", api.Get)
22 | r.POST("", api.Insert)
23 | r.PUT("/:id", api.Update)
24 | r.DELETE("", api.Delete)
25 | }
26 | r1 := v1.Group("").Use(authMiddleware.MiddlewareFunc())
27 | {
28 | r1.PUT("/role-status", api.Update2Status)
29 | r1.PUT("/roledatascope", api.Update2DataScope)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/system/models/sys_config.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "smart-api/common/models"
5 | )
6 |
7 | type SysConfig struct {
8 | models.Model
9 | ConfigName string `json:"configName" gorm:"size:128;comment:ConfigName"` //
10 | ConfigKey string `json:"configKey" gorm:"size:128;comment:ConfigKey"` //
11 | ConfigValue string `json:"configValue" gorm:"size:255;comment:ConfigValue"` //
12 | ConfigType string `json:"configType" gorm:"size:64;comment:ConfigType"`
13 | IsFrontend string `json:"isFrontend" gorm:"size:64;comment:是否前台"` //
14 | Remark string `json:"remark" gorm:"size:128;comment:Remark"` //
15 | models.ControlBy
16 | models.ModelTime
17 | }
18 |
19 | func (*SysConfig) TableName() string {
20 | return "sys_config"
21 | }
22 |
23 | func (e *SysConfig) Generate() models.ActiveRecord {
24 | o := *e
25 | return &o
26 | }
27 |
28 | func (e *SysConfig) GetId() interface{} {
29 | return e.Id
30 | }
31 |
--------------------------------------------------------------------------------
/template/v4/no_actions/router_check_role.go.template:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 |
7 | "smart-api/app/{{.PackageName}}/apis"
8 | "smart-api/common/middleware"
9 | "smart-api/common/actions"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, register{{.ClassName}}Router)
14 | }
15 |
16 | // register{{.ClassName}}Router
17 | func register{{.ClassName}}Router(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | api := apis.{{.ClassName}}{}
19 | r := v1.Group("/{{.ModuleName}}").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | r.GET("", actions.PermissionAction(), api.GetPage)
22 | r.GET("/:id", actions.PermissionAction(), api.Get)
23 | r.POST("", api.Insert)
24 | r.PUT("/:id", actions.PermissionAction(), api.Update)
25 | r.DELETE("", api.Delete)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/smart/router/order_comment.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerOrderCommentAuthRouter)
14 | }
15 |
16 | // 注册工单评论路由
17 | func registerOrderCommentAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | commentApi := apis.OrderCommentAPI{}
19 |
20 | r := v1.Group("/order-comments").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
21 | {
22 | // 根据ID获取评论
23 | r.GET("/:orderID", commentApi.Get) // 根据工单ID获取所有留言
24 | // 添加留言
25 | r.POST("", commentApi.Insert) // 添加留言的路由
26 | // 更新留言
27 | r.PUT("", commentApi.Update) // 更新留言的路由
28 | // 删除留言
29 | r.DELETE("", commentApi.Delete) // 删除留言的路由
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/smart/service/dto/user_favorite.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "smart-api/app/smart/models"
5 | common "smart-api/common/models"
6 | )
7 |
8 | type UserFavoriteInsertReq struct {
9 | OrderItemID uint `json:"orderItemId" binding:"required"` // 工单项ID
10 | UserID int `json:"userID"` // 用户id
11 | common.ControlBy
12 | }
13 |
14 | // Generate 生成 OrderRating 模型实例
15 | func (s *UserFavoriteInsertReq) Generate(userID int, model *models.UserFavorites) {
16 | model.OrderItemID = s.OrderItemID
17 | model.UserID = userID
18 | model.ControlBy = s.ControlBy
19 | }
20 |
21 | // GetId 获取数据对应的 ID
22 | func (s *UserFavoriteInsertReq) GetId() interface{} {
23 | return s.OrderItemID
24 | }
25 |
26 | type UserFavoriteDeleteReq struct {
27 | OrderItemID uint `json:"orderItemId" binding:"required"` // 工单项ID
28 | }
29 |
30 | // GetId 删除数据对应的 ID
31 | func (s *UserFavoriteDeleteReq) GetId() interface{} {
32 | return s.OrderItemID
33 | }
34 |
--------------------------------------------------------------------------------
/app/system/models/sys_post.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "smart-api/common/models"
4 |
5 | type SysPost struct {
6 | PostId int `gorm:"primaryKey;autoIncrement" json:"postId"` //岗位编号
7 | PostName string `gorm:"size:128;" json:"postName"` //岗位名称
8 | PostCode string `gorm:"size:128;" json:"postCode"` //岗位代码
9 | Sort int `gorm:"size:4;" json:"sort"` //岗位排序
10 | Status int `gorm:"size:4;" json:"status"` //状态
11 | Remark string `gorm:"size:255;" json:"remark"` //描述
12 | models.ControlBy
13 | models.ModelTime
14 |
15 | DataScope string `gorm:"-" json:"dataScope"`
16 | Params string `gorm:"-" json:"params"`
17 | }
18 |
19 | func (*SysPost) TableName() string {
20 | return "sys_post"
21 | }
22 |
23 | func (e *SysPost) Generate() models.ActiveRecord {
24 | o := *e
25 | return &o
26 | }
27 |
28 | func (e *SysPost) GetId() interface{} {
29 | return e.PostId
30 | }
31 |
--------------------------------------------------------------------------------
/config/pg.sql:
--------------------------------------------------------------------------------
1 | -- 开始初始化数据 ;
2 | create sequence if not exists sys_role_role_id_seq;
3 | create sequence if not exists sys_user_user_id_seq;
4 | create sequence if not exists sys_post_post_id_seq;
5 | create sequence if not exists sys_menu_menu_id_seq;
6 | create sequence if not exists sys_dict_type_dict_id_seq;
7 | create sequence if not exists sys_dict_data_dict_code_seq;
8 | create sequence if not exists sys_dept_dept_id_seq;
9 | create sequence if not exists sys_config_config_id_seq;
10 | create sequence if not exists sys_job_id_seq;
11 |
12 | select setval('sys_role_role_id_seq',4);
13 | select setval('sys_user_user_id_seq',5);
14 | select setval('sys_post_post_id_seq',4);
15 | select setval('sys_menu_menu_id_seq',543);
16 | select setval('sys_dict_type_dict_id_seq',12);
17 | select setval('sys_dict_data_dict_code_seq',34);
18 | select setval('sys_dept_dept_id_seq',11);
19 | select setval('sys_config_config_id_seq',6);
20 | select setval('sys_job_id_seq',3);
21 | -- 数据完成 ;
22 |
--------------------------------------------------------------------------------
/app/smart/router/order_rating.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerOrderRatingAuthRouter)
14 | }
15 |
16 | // 注册工单评论路由
17 | func registerOrderRatingAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | ratingApi := apis.OrderRatingAPI{} // 假设你有一个处理评分的 API
19 |
20 | rating := v1.Group("/order-ratings").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
21 | {
22 | // 获取工单评分
23 | rating.GET("/:orderID", ratingApi.Get) // 添加评分的路由
24 | // 添加评分
25 | rating.POST("", ratingApi.Insert) // 添加评分的路由
26 | // 更新评分
27 | rating.PUT("", ratingApi.Update) // 更新评分的路由
28 | // 删除评分
29 | rating.DELETE("", ratingApi.Delete) // 删除评分的路由
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/smart/router/exec_machine.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerExecMachineAuthRouter)
14 | }
15 |
16 | // 执行节点管理
17 | func registerExecMachineAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
18 | api := apis.ExecMachine{}
19 | r := v1.Group("/exec-machine").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | // 查询所有节点
22 | r.GET("", api.GetPage)
23 | // 根据ID 查询
24 | r.GET("/:id", api.Get)
25 | // 创建节点
26 | r.POST("", api.Insert)
27 | // 更新节点信息
28 | r.PUT("", api.Update)
29 | // 删除节点
30 | r.DELETE("", api.Delete)
31 | // 新增连接测试接口
32 | r.POST("/testConnection", api.TestConnection) // 添加连接测试接口
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/system/router/init_router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "os"
5 |
6 | "github.com/gin-gonic/gin"
7 | log "github.com/go-admin-team/go-admin-core/logger"
8 | "github.com/go-admin-team/go-admin-core/sdk"
9 | common "smart-api/common/middleware"
10 | )
11 |
12 | // InitRouter 路由初始化,不要怀疑,这里用到了
13 | func InitRouter() {
14 | var r *gin.Engine
15 | h := sdk.Runtime.GetEngine()
16 | if h == nil {
17 | log.Fatal("not found engine...")
18 | os.Exit(-1)
19 | }
20 | switch h.(type) {
21 | case *gin.Engine:
22 | r = h.(*gin.Engine)
23 | default:
24 | log.Fatal("not support other engine")
25 | os.Exit(-1)
26 | }
27 |
28 | // the jwt middleware
29 | authMiddleware, err := common.AuthInit()
30 | if err != nil {
31 | log.Fatalf("JWT Init Error, %s", err.Error())
32 | }
33 |
34 | // 注册系统路由
35 | InitSysRouter(r, authMiddleware)
36 |
37 | // 注册业务路由
38 | InitSmartApiRouter(r, authMiddleware)
39 |
40 | // 注册LDAP路由
41 | InitLDAPRouter(r, authMiddleware)
42 | }
43 |
--------------------------------------------------------------------------------
/common/middleware/request_id.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "github.com/go-admin-team/go-admin-core/logger"
5 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
6 | "net/http"
7 | "strings"
8 |
9 | "github.com/gin-gonic/gin"
10 | "github.com/google/uuid"
11 | )
12 |
13 | // RequestId 自动增加requestId
14 | func RequestId(trafficKey string) gin.HandlerFunc {
15 | return func(c *gin.Context) {
16 | if c.Request.Method == http.MethodOptions {
17 | c.Next()
18 | return
19 | }
20 | requestId := c.GetHeader(trafficKey)
21 | if requestId == "" {
22 | requestId = c.GetHeader(strings.ToLower(trafficKey))
23 | }
24 | if requestId == "" {
25 | requestId = uuid.New().String()
26 | }
27 | c.Request.Header.Set(trafficKey, requestId)
28 | c.Set(trafficKey, requestId)
29 | c.Set(pkg.LoggerKey,
30 | logger.NewHelper(logger.DefaultLogger).
31 | WithFields(map[string]interface{}{
32 | trafficKey: requestId,
33 | }))
34 | c.Next()
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/config/settings.sqlite.yml:
--------------------------------------------------------------------------------
1 | settings:
2 | application:
3 | # dev开发环境 test测试环境 prod线上环境
4 | mode: dev
5 | # 服务器ip,默认使用 0.0.0.0
6 | host: 0.0.0.0
7 | # 服务名称
8 | name: testApp
9 | # 端口号
10 | port: 8000 # 服务端口号
11 | readtimeout: 3000
12 | writertimeout: 2000
13 | # 数据权限功能开关
14 | enabledp: false
15 | logger:
16 | # 日志存放路径
17 | path: temp/logs
18 | # 日志输出,file:文件,default:命令行,其他:命令行
19 | stdout: '' #控制台日志,启用后,不输出到文件
20 | # 日志等级, trace, debug, info, warn, error, fatal
21 | level: trace
22 | # 数据库日志开关
23 | enableddb: false
24 | jwt:
25 | # token 密钥,生产环境时及的修改
26 | secret: smart-api
27 | # token 过期时间 单位:秒
28 | timeout: 3600
29 | database:
30 | # 数据库类型 mysql,sqlite3, postgres
31 | driver: sqlite3
32 | # 数据库连接sqlite3数据文件的路径
33 | source: smart-api-db.db
34 | gen:
35 | # 代码生成读取的数据库名称
36 | dbname: dbname
37 | # 代码生成是使用前端代码存放位置,需要指定到src文件夹,相对路径
38 | frontpath: ../smart-api-ui/src
39 |
--------------------------------------------------------------------------------
/app/system/apis/captcha.go:
--------------------------------------------------------------------------------
1 | package apis
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/go-admin-team/go-admin-core/sdk/api"
6 | "github.com/go-admin-team/go-admin-core/sdk/pkg/captcha"
7 | )
8 |
9 | type System struct {
10 | api.Api
11 | }
12 |
13 | // GenerateCaptchaHandler 获取验证码
14 | // @Summary 获取验证码
15 | // @Description 获取验证码
16 | // @Tags 登陆
17 | // @Success 200 {object} response.Response{data=string,id=string,msg=string} "{"code": 200, "data": [...]}"
18 | // @Router /api/v1/captcha [get]
19 | func (e System) GenerateCaptchaHandler(c *gin.Context) {
20 | err := e.MakeContext(c).Errors
21 | if err != nil {
22 | e.Error(500, err, "服务初始化失败!")
23 | return
24 | }
25 | id, b64s, err := captcha.DriverDigitFunc()
26 | if err != nil {
27 | e.Logger.Errorf("DriverDigitFunc error, %s", err.Error())
28 | e.Error(500, err, "验证码获取失败")
29 | return
30 | }
31 | e.Custom(gin.H{
32 | "code": 200,
33 | "data": b64s,
34 | "id": id,
35 | "msg": "success",
36 | })
37 | }
38 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_role.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysRole struct {
4 | RoleId int `json:"roleId" gorm:"primaryKey;autoIncrement"` // 角色编码
5 | RoleName string `json:"roleName" gorm:"size:128;"` // 角色名称
6 | Status string `json:"status" gorm:"size:4;"` //
7 | RoleKey string `json:"roleKey" gorm:"size:128;"` //角色代码
8 | RoleSort int `json:"roleSort" gorm:""` //角色排序
9 | Flag string `json:"flag" gorm:"size:128;"` //
10 | Remark string `json:"remark" gorm:"size:255;"` //备注
11 | Admin bool `json:"admin" gorm:"size:4;"`
12 | DataScope string `json:"dataScope" gorm:"size:128;"`
13 | SysMenu []SysMenu `json:"sysMenu" gorm:"many2many:sys_role_menu;foreignKey:RoleId;joinForeignKey:role_id;references:MenuId;joinReferences:menu_id;"`
14 | ControlBy
15 | ModelTime
16 | }
17 |
18 | func (SysRole) TableName() string {
19 | return "sys_role"
20 | }
--------------------------------------------------------------------------------
/common/middleware/handler/role.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import "smart-api/common/models"
4 |
5 | type SysRole struct {
6 | RoleId int `json:"roleId" gorm:"primaryKey;autoIncrement"` // 角色编码
7 | RoleName string `json:"roleName" gorm:"size:128;"` // 角色名称
8 | Status string `json:"status" gorm:"size:4;"` //
9 | RoleKey string `json:"roleKey" gorm:"size:128;"` //角色代码
10 | RoleSort int `json:"roleSort" gorm:""` //角色排序
11 | Flag string `json:"flag" gorm:"size:128;"` //
12 | Remark string `json:"remark" gorm:"size:255;"` //备注
13 | Admin bool `json:"admin" gorm:"size:4;"`
14 | DataScope string `json:"dataScope" gorm:"size:128;"`
15 | Params string `json:"params" gorm:"-"`
16 | MenuIds []int `json:"menuIds" gorm:"-"`
17 | DeptIds []int `json:"deptIds" gorm:"-"`
18 | models.ControlBy
19 | models.ModelTime
20 | }
21 |
22 | func (SysRole) TableName() string {
23 | return "sys_role"
24 | }
25 |
--------------------------------------------------------------------------------
/template/migrate.template:
--------------------------------------------------------------------------------
1 | package {{.Package}}
2 |
3 | import (
4 | "gorm.io/gorm"
5 | "runtime"
6 |
7 | "smart-api/cmd/migrate/migration"
8 | common "smart-api/common/models"
9 | )
10 |
11 | func init() {
12 | _, fileName, _, _ := runtime.Caller(0)
13 | migration.Migrate.SetVersion(migration.GetFilename(fileName), _{{.GenerateTime}}Test)
14 | }
15 |
16 | func _{{.GenerateTime}}Test(db *gorm.DB, version string) error {
17 | return db.Transaction(func(tx *gorm.DB) error {
18 |
19 | // TODO: 这里开始写入要变更的内容
20 |
21 | // TODO: 例如 修改表字段 使用过程中请删除此段代码
22 | //err := tx.Migrator().RenameColumn(&models.SysConfig{}, "config_id", "id")
23 | //if err != nil {
24 | // return err
25 | //}
26 |
27 | // TODO: 例如 新增表结构 使用过程中请删除此段代码
28 | //err = tx.Debug().Migrator().AutoMigrate(
29 | // new(models.CasbinRule),
30 | // )
31 | //if err != nil {
32 | // return err
33 | //}
34 |
35 |
36 | return tx.Create(&common.Migration{
37 | Version: version,
38 | }).Error
39 | })
40 | }
41 |
--------------------------------------------------------------------------------
/app/smart/models/order_category.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/13 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type OrderCategory struct {
10 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
11 | Name string `gorm:"column:name;type:varchar(50)" json:"name"`
12 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
13 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
14 | ChineseName string `gorm:"column:chineseName;type:varchar(50)" json:"chineseName"`
15 | FlowTemplates []FlowTemplates `gorm:"foreignKey:CategoryID" json:"flowTemplates"`
16 | models.ControlBy
17 | models.ModelTime
18 | }
19 |
20 | func (*OrderCategory) TableName() string {
21 | return "order_category"
22 | }
23 |
24 | func (e *OrderCategory) Generate() models.ActiveRecord {
25 | o := *e
26 | return &o
27 | }
28 |
29 | func (e *OrderCategory) GetId() interface{} {
30 | return e.ID
31 | }
32 |
--------------------------------------------------------------------------------
/app/jobs/router/router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | )
7 |
8 | var (
9 | routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
10 | routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
11 | )
12 |
13 | // initRouter 路由示例
14 | func initRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
15 |
16 | // 无需认证的路由
17 | noCheckRoleRouter(r)
18 | // 需要认证的路由
19 | checkRoleRouter(r, authMiddleware)
20 |
21 | return r
22 | }
23 |
24 | // noCheckRoleRouter 无需认证的路由示例
25 | func noCheckRoleRouter(r *gin.Engine) {
26 | // 可根据业务需求来设置接口版本
27 | v1 := r.Group("/api/v1")
28 |
29 | for _, f := range routerNoCheckRole {
30 | f(v1)
31 | }
32 | }
33 |
34 | // checkRoleRouter 需要认证的路由示例
35 | func checkRoleRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) {
36 | // 可根据业务需求来设置接口版本
37 | v1 := r.Group("/api/v1")
38 |
39 | for _, f := range routerCheckRole {
40 | f(v1, authMiddleware)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/other/router/router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | )
7 |
8 | var (
9 | routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
10 | routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
11 | )
12 |
13 | // initRouter 路由示例
14 | func initRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
15 |
16 | // 无需认证的路由
17 | noCheckRoleRouter(r)
18 | // 需要认证的路由
19 | checkRoleRouter(r, authMiddleware)
20 |
21 | return r
22 | }
23 |
24 | // noCheckRoleRouter 无需认证的路由示例
25 | func noCheckRoleRouter(r *gin.Engine) {
26 | // 可根据业务需求来设置接口版本
27 | v1 := r.Group("/api/v1")
28 |
29 | for _, f := range routerNoCheckRole {
30 | f(v1)
31 | }
32 | }
33 |
34 | // checkRoleRouter 需要认证的路由示例
35 | func checkRoleRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) {
36 | // 可根据业务需求来设置接口版本
37 | v1 := r.Group("/api/v1")
38 |
39 | for _, f := range routerCheckRole {
40 | f(v1, authMiddleware)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/common/middleware/init.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/go-admin-team/go-admin-core/sdk"
6 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
7 | "smart-api/common/actions"
8 | )
9 |
10 | const (
11 | JwtTokenCheck string = "JwtToken"
12 | RoleCheck string = "AuthCheckRole"
13 | PermissionCheck string = "PermissionAction"
14 | )
15 |
16 | func InitMiddleware(r *gin.Engine) {
17 | r.Use(DemoEvn())
18 | // 数据库链接
19 | r.Use(WithContextDb)
20 | // 日志处理
21 | r.Use(LoggerToFile())
22 | // 自定义错误处理
23 | r.Use(CustomError)
24 | // NoCache is a middleware function that appends headers
25 | r.Use(NoCache)
26 | // 跨域处理
27 | r.Use(Options)
28 | // Secure is a middleware function that appends security
29 | r.Use(Secure)
30 | // 链路追踪
31 | //r.Use(middleware.Trace())
32 | sdk.Runtime.SetMiddleware(JwtTokenCheck, (*jwt.GinJWTMiddleware).MiddlewareFunc)
33 | sdk.Runtime.SetMiddleware(RoleCheck, AuthCheckRole())
34 | sdk.Runtime.SetMiddleware(PermissionCheck, actions.PermissionAction())
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright © 2024 sunwenbo smart swb956721830@163.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/common/middleware/demo.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/go-admin-team/go-admin-core/sdk/config"
6 | "net/http"
7 | )
8 |
9 | func DemoEvn() gin.HandlerFunc {
10 | return func(c *gin.Context) {
11 | method := c.Request.Method
12 | if config.ApplicationConfig.Mode == "demo" {
13 | if method == "GET" ||
14 | method == "OPTIONS" ||
15 | c.Request.RequestURI == "/api/v1/login" ||
16 | c.Request.RequestURI == "/api/v1/logout" {
17 | c.Next()
18 | } else {
19 | // 添加跨域头部
20 | c.Header("Access-Control-Allow-Origin", "*")
21 | c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
22 | c.Header("Access-Control-Allow-Headers", "authorization, origin, content-type, accept, user-agent")
23 | c.Header("Access-Control-Allow-Credentials", "true")
24 | c.JSON(http.StatusOK, gin.H{
25 | "code": 500,
26 | "msg": "谢谢您的参与,但为了大家更好的体验,所以本次提交就算了吧!\U0001F600\U0001F600\U0001F600",
27 | })
28 | c.Abort()
29 | return
30 | }
31 | }
32 | c.Next()
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_job.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysJob struct {
4 | JobId int `json:"jobId" gorm:"primaryKey;autoIncrement"` // 编码
5 | JobName string `json:"jobName" gorm:"size:255;"` // 名称
6 | JobGroup string `json:"jobGroup" gorm:"size:255;"` // 任务分组
7 | JobType int `json:"jobType" gorm:"size:1;"` // 任务类型
8 | CronExpression string `json:"cronExpression" gorm:"size:255;"` // cron表达式
9 | InvokeTarget string `json:"invokeTarget" gorm:"size:255;"` // 调用目标
10 | Args string `json:"args" gorm:"size:255;"` // 目标参数
11 | MisfirePolicy int `json:"misfirePolicy" gorm:"size:255;"` // 执行策略
12 | Concurrent int `json:"concurrent" gorm:"size:1;"` // 是否并发
13 | Status int `json:"status" gorm:"size:1;"` // 状态
14 | EntryId int `json:"entry_id" gorm:"size:11;"` // job启动时返回的id
15 | ModelTime
16 | ControlBy
17 | }
18 |
19 | func (SysJob) TableName() string {
20 | return "sys_job"
21 | }
22 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/flow_templates.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/16 21:14
3 | package models
4 |
5 | import (
6 | models2 "smart-api/cmd/migrate/migration/models"
7 | )
8 |
9 | type FormData map[string]interface{}
10 |
11 | type FlowTemplates struct {
12 | ID uint `gorm:"primaryKey;autoIncrement"`
13 | Name string `gorm:"column:name;type:varchar(100)" json:"name"`
14 | Description string `gorm:"column:description;type:varchar(200)" json:"description"`
15 | BindCount int `gorm:"column:bindCount" json:"bindCount"`
16 | FormData FormData `gorm:"type:json" json:"formData"`
17 | CategoryID uint `gorm:"column:categoryId" json:"categoryId"`
18 | BindFlow uint `gorm:"column:bindFlow" json:"bindFlow"`
19 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
20 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
21 | models2.ControlBy
22 | models2.ModelTime
23 | }
24 |
25 | func (FlowTemplates) TableName() string {
26 | return "flow_templates"
27 | }
28 |
--------------------------------------------------------------------------------
/app/smart/router/router.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:42
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | )
9 |
10 | var (
11 | routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
12 | routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
13 | )
14 |
15 | // initRouter 路由示例
16 | func initRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
17 |
18 | // 无需认证的路由
19 | noCheckRoleRouter(r)
20 | // 需要认证的路由
21 | checkRoleRouter(r, authMiddleware)
22 |
23 | return r
24 | }
25 |
26 | // noCheckRoleRouter 无需认证的路由示例
27 | func noCheckRoleRouter(r *gin.Engine) {
28 | // 可根据业务需求来设置接口版本
29 | v1 := r.Group("/api/v1")
30 |
31 | for _, f := range routerNoCheckRole {
32 | f(v1)
33 | }
34 | }
35 |
36 | // checkRoleRouter 需要认证的路由示例
37 | func checkRoleRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) {
38 | // 可根据业务需求来设置接口版本
39 | v1 := r.Group("/api/v1/")
40 |
41 | for _, f := range routerCheckRole {
42 | f(v1, authMiddleware)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/system/router/router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | _ "github.com/gin-gonic/gin"
6 | "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | )
9 |
10 | var (
11 | routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
12 | routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
13 | )
14 |
15 | func InitSmartApiRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
16 | // 无需认证的路由
17 | smartApiNoCheckRoleRouter(r)
18 | // 需要认证的路由
19 | smartApiCheckRoleRouter(r, authMiddleware)
20 | return r
21 | }
22 |
23 | // 无需认证的路由示例
24 | func smartApiNoCheckRoleRouter(r *gin.Engine) {
25 | // 可根据业务需求来设置接口版本
26 | v1 := r.Group("/api/v1")
27 | for _, f := range routerNoCheckRole {
28 | f(v1)
29 | }
30 | }
31 |
32 | // 需要认证的路由示例
33 | func smartApiCheckRoleRouter(r *gin.Engine, authMiddleware *jwtauth.GinJWTMiddleware) {
34 | // 可根据业务需求来设置接口版本
35 | v1 := r.Group("/api/v1")
36 | for _, f := range routerCheckRole {
37 | f(v1, authMiddleware)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/order_items.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/13 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type OrderItems struct {
10 | ID uint `gorm:"primaryKey" json:"id"`
11 | Title string `gorm:"column:title;type:varchar(50)" json:"title"` // 订单项标题
12 | BindTempLate string `gorm:"column:bindTempLate;type:varchar(50)" json:"bindTempLate"` // 绑定模板
13 | Description string `gorm:"column:description;type:varchar(256)" json:"description"` // 订单项描述
14 | Icon string `gorm:"column:icon;type:varchar(50)" json:"icon"` // 订单项图标
15 | CategoryID uint `gorm:"column:categoryId" json:"categoryId"`
16 | Link string `gorm:"column:link;type:varchar(256)" json:"link"` // 连接到网页
17 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
18 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
19 | models.ControlBy
20 | models.ModelTime
21 | }
22 |
23 | func (*OrderItems) TableName() string {
24 | return "order_items"
25 | }
26 |
--------------------------------------------------------------------------------
/test/gen_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | //"smart-api/models/tools"
5 | //"os"
6 | "testing"
7 | //"text/template"
8 | )
9 |
10 | func TestGoModelTemplate(t *testing.T) {
11 | //t1, err := template.ParseFiles("model.go.template")
12 | //if err != nil {
13 | // t.Error(err)
14 | //}
15 | //table := tools.SysTables{}
16 | //table.TBName = "sys_tables"
17 | //tab, err := table.Get()
18 | //if err != nil {
19 | // t.Error(err)
20 | //}
21 | //file, err := os.Create("models/" + table.PackageName + ".go")
22 | //if err != nil {
23 | // t.Error(err)
24 | //}
25 | //defer file.Close()
26 | //
27 | //_ = t1.Execute(file, tab)
28 | t.Log("")
29 | }
30 |
31 | func TestGoApiTemplate(t *testing.T) {
32 | //t1, err := template.ParseFiles("api.go.template")
33 | //if err != nil {
34 | // t.Error(err)
35 | //}
36 | //table := tools.SysTables{}
37 | //table.TBName = "sys_tables"
38 | //tab, _ := table.Get()
39 | //file, err := os.Create("apis/" + table.PackageName + ".go")
40 | //if err != nil {
41 | // t.Error(err)
42 | //}
43 | //defer file.Close()
44 | //
45 | //_ = t1.Execute(file, tab)
46 | t.Log("")
47 | }
48 |
--------------------------------------------------------------------------------
/app/system/router/sys_config.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "smart-api/app/system/apis"
5 | "smart-api/common/middleware"
6 |
7 | "github.com/gin-gonic/gin"
8 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
9 | )
10 |
11 | func init() {
12 | routerCheckRole = append(routerCheckRole, registerSysConfigRouter)
13 | }
14 |
15 | // 需认证的路由代码
16 | func registerSysConfigRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
17 | api := apis.SysConfig{}
18 | r := v1.Group("/config").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
19 | {
20 | r.GET("", api.GetPage)
21 | r.GET("/:id", api.Get)
22 | r.POST("", api.Insert)
23 | r.PUT("/:id", api.Update)
24 | r.DELETE("", api.Delete)
25 | }
26 |
27 | r1 := v1.Group("/configKey").Use(authMiddleware.MiddlewareFunc())
28 | {
29 | r1.GET("/:configKey", api.GetSysConfigByKEYForService)
30 | }
31 |
32 | r2 := v1.Group("/app-config")
33 | {
34 | r2.GET("", api.Get2SysApp)
35 | }
36 |
37 | r3 := v1.Group("/set-config").Use(authMiddleware.MiddlewareFunc())
38 | {
39 | r3.PUT("", api.Update2Set)
40 | r3.GET("", api.Get2Set)
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/smart/router/order_task.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | )
11 |
12 | func init() {
13 | routerCheckRole = append(routerCheckRole, registerOrderTaskAuthRouter)
14 | //routerNoCheckRole = append(routerNoCheckRole, registerOrderRouter)
15 | }
16 |
17 | // 注册工单类别路由
18 | func registerOrderTaskAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
19 | api := apis.OrderTask{}
20 |
21 | r := v1.Group("/order-task").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
22 | {
23 | // 查询所有的任务
24 | r.GET("", api.GetPage)
25 | // 根据ID 查询
26 | r.GET("/:id", api.Get)
27 | // 创建任务
28 | r.POST("", api.Insert)
29 | // 更新任务信息
30 | r.PUT("", api.Update)
31 | // 删除任务
32 | r.DELETE("", api.Delete)
33 |
34 | // 查询历史任务
35 | r.GET("/history", api.GetHistoryTaskPage)
36 | // 删除历史执行后的任务
37 | r.DELETE("/history", api.DeleteHistoryTask)
38 |
39 | // 查询历史任务日志
40 | r.GET("/history/:id/logs", api.GetTaskLogsByID)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/template/v4/actions/router_no_check_role.go.template:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 |
6 | "smart-api/app/{{.PackageName}}/middleware"
7 | "smart-api/app/{{.PackageName}}/models"
8 | "smart-api/app/{{.PackageName}}/service/dto"
9 | "smart-api/common/actions"
10 | )
11 |
12 | func init() {
13 | routerNoCheckRole = append(routerNoCheckRole, register{{.ClassName}}Router)
14 | }
15 |
16 | // 无需认证的路由代码
17 | func register{{.ClassName}}Router(v1 *gin.RouterGroup) {
18 | r := v1.Group("/{{.ModuleName}}")
19 | {
20 | model := &models.{{.ClassName}}{}
21 | r.GET("", actions.IndexAction(model, new(dto.{{.ClassName}}Search), func() interface{} {
22 | list := make([]models.{{.ClassName}}, 0)
23 | return &list
24 | }))
25 | r.GET("/:id", actions.ViewAction(new(dto.{{.ClassName}}ById), nil))
26 | r.POST("", actions.CreateAction(new(dto.{{.ClassName}}Control)))
27 | r.PUT("/:id", actions.UpdateAction(new(dto.{{.ClassName}}Control)))
28 | r.DELETE("", actions.DeleteAction(new(dto.{{.ClassName}}ById)))
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_dict_data.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type DictData struct {
4 | DictCode int `gorm:"primaryKey;autoIncrement;" json:"dictCode" example:"1"` //字典编码
5 | DictSort int `gorm:"" json:"dictSort"` //显示顺序
6 | DictLabel string `gorm:"size:128;" json:"dictLabel"` //数据标签
7 | DictValue string `gorm:"size:255;" json:"dictValue"` //数据键值
8 | DictType string `gorm:"size:64;" json:"dictType"` //字典类型
9 | CssClass string `gorm:"size:128;" json:"cssClass"` //
10 | ListClass string `gorm:"size:128;" json:"listClass"` //
11 | IsDefault string `gorm:"size:8;" json:"isDefault"` //
12 | Status int `gorm:"size:4;" json:"status"` //状态
13 | Default string `gorm:"size:8;" json:"default"` //
14 | Remark string `gorm:"size:255;" json:"remark"` //备注
15 | ControlBy
16 | ModelTime
17 | }
18 |
19 | func (DictData) TableName() string {
20 | return "sys_dict_data"
21 | }
22 |
--------------------------------------------------------------------------------
/common/middleware/auth.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "time"
5 |
6 | "github.com/go-admin-team/go-admin-core/sdk/config"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/common/middleware/handler"
9 | )
10 |
11 | // AuthInit jwt验证new
12 | func AuthInit() (*jwt.GinJWTMiddleware, error) {
13 | timeout := time.Hour
14 | if config.ApplicationConfig.Mode == "dev" {
15 | timeout = time.Duration(876010) * time.Hour
16 | } else {
17 | if config.JwtConfig.Timeout != 0 {
18 | timeout = time.Duration(config.JwtConfig.Timeout) * time.Second
19 | }
20 | }
21 | return jwt.New(&jwt.GinJWTMiddleware{
22 | Realm: "test zone",
23 | Key: []byte(config.JwtConfig.Secret),
24 | Timeout: timeout,
25 | MaxRefresh: time.Hour,
26 | PayloadFunc: handler.PayloadFunc,
27 | IdentityHandler: handler.IdentityHandler,
28 | Authenticator: handler.Authenticator,
29 | Authorizator: handler.Authorizator,
30 | Unauthorized: handler.Unauthorized,
31 | TokenLookup: "header: Authorization, query: token, cookie: jwt",
32 | TokenHeadName: "Bearer",
33 | TimeFunc: time.Now,
34 | })
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/template/v4/js.go.template:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request'
2 |
3 | // 查询{{.ClassName}}列表
4 | export function list{{.ClassName}}(query) {
5 | return request({
6 | url: '/api/v1/{{.ModuleName}}',
7 | method: 'get',
8 | params: query
9 | })
10 | }
11 |
12 | // 查询{{.ClassName}}详细
13 | export function get{{.ClassName}} ({{.PkJsonField}}) {
14 | return request({
15 | url: '/api/v1/{{.ModuleName}}/' + {{.PkJsonField}},
16 | method: 'get'
17 | })
18 | }
19 |
20 |
21 | // 新增{{.ClassName}}
22 | export function add{{.ClassName}}(data) {
23 | return request({
24 | url: '/api/v1/{{.ModuleName}}',
25 | method: 'post',
26 | data: data
27 | })
28 | }
29 |
30 | // 修改{{.ClassName}}
31 | export function update{{.ClassName}}(data) {
32 | return request({
33 | url: '/api/v1/{{.ModuleName}}/'+data.{{.PkJsonField}},
34 | method: 'put',
35 | data: data
36 | })
37 | }
38 |
39 | // 删除{{.ClassName}}
40 | export function del{{.ClassName}}(data) {
41 | return request({
42 | url: '/api/v1/{{.ModuleName}}',
43 | method: 'delete',
44 | data: data
45 | })
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_login_log.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type SysLoginLog struct {
8 | Model
9 | Username string `json:"username" gorm:"type:varchar(128);comment:用户名"`
10 | Status string `json:"status" gorm:"type:varchar(4);comment:状态"`
11 | Ipaddr string `json:"ipaddr" gorm:"type:varchar(255);comment:ip地址"`
12 | LoginLocation string `json:"loginLocation" gorm:"type:varchar(255);comment:归属地"`
13 | Browser string `json:"browser" gorm:"type:varchar(255);comment:浏览器"`
14 | Os string `json:"os" gorm:"type:varchar(255);comment:系统"`
15 | Platform string `json:"platform" gorm:"type:varchar(255);comment:固件"`
16 | LoginTime time.Time `json:"loginTime" gorm:"type:timestamp;comment:登录时间"`
17 | Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"`
18 | Msg string `json:"msg" gorm:"type:varchar(255);comment:信息"`
19 | CreatedAt time.Time `json:"createdAt" gorm:"comment:创建时间"`
20 | UpdatedAt time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
21 | ControlBy
22 | }
23 |
24 | func (SysLoginLog) TableName() string {
25 | return "sys_login_log"
26 | }
27 |
--------------------------------------------------------------------------------
/common/file_store/initialize.go:
--------------------------------------------------------------------------------
1 | package file_store
2 |
3 | import "fmt"
4 |
5 | type OXS struct {
6 | // Endpoint 访问域名
7 | Endpoint string
8 | // AccessKeyID AK
9 | AccessKeyID string
10 | // AccessKeySecret AKS
11 | AccessKeySecret string
12 | // BucketName 桶名称
13 | BucketName string
14 | }
15 |
16 | // Setup 配置文件存储driver
17 | func (e *OXS) Setup(driver DriverType, options ...ClientOption) FileStoreType {
18 | fileStoreType := driver
19 | var fileStore FileStoreType
20 | switch fileStoreType {
21 | case AliYunOSS:
22 | fileStore = new(ALiYunOSS)
23 | err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
24 | if err != nil {
25 | fmt.Println(err)
26 | }
27 | return fileStore
28 | case HuaweiOBS:
29 | fileStore = new(HuaWeiOBS)
30 | err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
31 | if err != nil {
32 | fmt.Println(err)
33 | }
34 | return fileStore
35 | case QiNiuKodo:
36 | fileStore = new(QiNiuKODO)
37 | err := fileStore.Setup(e.Endpoint, e.AccessKeyID, e.AccessKeySecret, e.BucketName)
38 | if err != nil {
39 | fmt.Println(err)
40 | }
41 | return fileStore
42 | }
43 |
44 | return nil
45 | }
46 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_menu.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysMenu struct {
4 | MenuId int `json:"menuId" gorm:"primaryKey;autoIncrement"`
5 | MenuName string `json:"menuName" gorm:"size:128;"`
6 | Title string `json:"title" gorm:"size:128;"`
7 | Icon string `json:"icon" gorm:"size:128;"`
8 | Path string `json:"path" gorm:"size:128;"`
9 | Paths string `json:"paths" gorm:"size:128;"`
10 | MenuType string `json:"menuType" gorm:"size:1;"`
11 | Action string `json:"action" gorm:"size:16;"`
12 | Permission string `json:"permission" gorm:"size:255;"`
13 | ParentId int `json:"parentId" gorm:"size:11;"`
14 | NoCache bool `json:"noCache" gorm:"size:8;"`
15 | Breadcrumb string `json:"breadcrumb" gorm:"size:255;"`
16 | Component string `json:"component" gorm:"size:255;"`
17 | Sort int `json:"sort" gorm:"size:4;"`
18 | Visible string `json:"visible" gorm:"size:1;"`
19 | IsFrame string `json:"isFrame" gorm:"size:1;DEFAULT:0;"`
20 | SysApi []SysApi `json:"sysApi" gorm:"many2many:sys_menu_api_rule"`
21 | ControlBy
22 | ModelTime
23 | }
24 |
25 | func (SysMenu) TableName() string {
26 | return "sys_menu"
27 | }
--------------------------------------------------------------------------------
/common/models/user.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "gorm.io/gorm"
5 |
6 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
7 | )
8 |
9 | // BaseUser 密码登录基础用户
10 | type BaseUser struct {
11 | Username string `json:"username" gorm:"type:varchar(100);comment:用户名"`
12 | Salt string `json:"-" gorm:"type:varchar(255);comment:加盐;<-"`
13 | PasswordHash string `json:"-" gorm:"type:varchar(128);comment:密码hash;<-"`
14 | Password string `json:"password" gorm:"-"`
15 | }
16 |
17 | // SetPassword 设置密码
18 | func (u *BaseUser) SetPassword(value string) {
19 | u.Password = value
20 | u.generateSalt()
21 | u.PasswordHash = u.GetPasswordHash()
22 | }
23 |
24 | // GetPasswordHash 获取密码hash
25 | func (u *BaseUser) GetPasswordHash() string {
26 | passwordHash, err := pkg.SetPassword(u.Password, u.Salt)
27 | if err != nil {
28 | return ""
29 | }
30 | return passwordHash
31 | }
32 |
33 | // generateSalt 生成加盐值
34 | func (u *BaseUser) generateSalt() {
35 | u.Salt = pkg.GenerateRandomKey16()
36 | }
37 |
38 | // Verify 验证密码
39 | func (u *BaseUser) Verify(db *gorm.DB, tableName string) bool {
40 | db.Table(tableName).Where("username = ?", u.Username).First(u)
41 | return u.GetPasswordHash() == u.PasswordHash
42 | }
43 |
--------------------------------------------------------------------------------
/common/middleware/handler/login.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import (
4 | log "github.com/go-admin-team/go-admin-core/logger"
5 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
6 | "gorm.io/gorm"
7 | )
8 |
9 | type Login struct {
10 | Username string `form:"UserName" json:"username" binding:"required"`
11 | Password string `form:"Password" json:"password" binding:"required"`
12 | Source string `json:"source" comment:"用户来源" vd:"len($)>0" default:"1"`
13 | Code string `form:"Code" json:"code" binding:"required"`
14 | UUID string `form:"UUID" json:"uuid" binding:"required"`
15 | }
16 |
17 | func (u *Login) GetUser(tx *gorm.DB) (user SysUser, role SysRole, err error) {
18 | err = tx.Table("sys_user").Where("username = ? and status = '2'", u.Username).First(&user).Error
19 | if err != nil {
20 | log.Errorf("get user error, %s", err.Error())
21 | return
22 | }
23 | _, err = pkg.CompareHashAndPassword(user.Password, u.Password)
24 | if err != nil {
25 | log.Errorf("user login error, %s", err.Error())
26 | return
27 | }
28 | err = tx.Table("sys_role").Where("role_id = ? ", user.RoleId).First(&role).Error
29 | if err != nil {
30 | log.Errorf("get role error, %s", err.Error())
31 | return
32 | }
33 | return
34 | }
35 |
--------------------------------------------------------------------------------
/app/system/models/sys_dept.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "smart-api/common/models"
4 |
5 | type SysDept struct {
6 | DeptId int `json:"deptId" gorm:"primaryKey;autoIncrement;"` //部门编码
7 | ParentId int `json:"parentId" gorm:""` //上级部门
8 | DeptPath string `json:"deptPath" gorm:"size:255;"` //
9 | DeptName string `json:"deptName" gorm:"size:128;"` //部门名称
10 | Sort int `json:"sort" gorm:"size:4;"` //排序
11 | Leader string `json:"leader" gorm:"size:128;"` //负责人
12 | Phone string `json:"phone" gorm:"size:11;"` //手机
13 | Email string `json:"email" gorm:"size:64;"` //邮箱
14 | Status int `json:"status" gorm:"size:4;"` //状态
15 | models.ControlBy
16 | models.ModelTime
17 | DataScope string `json:"dataScope" gorm:"-"`
18 | Params string `json:"params" gorm:"-"`
19 | Children []SysDept `json:"children" gorm:"-"`
20 | }
21 |
22 | func (*SysDept) TableName() string {
23 | return "sys_dept"
24 | }
25 |
26 | func (e *SysDept) Generate() models.ActiveRecord {
27 | o := *e
28 | return &o
29 | }
30 |
31 | func (e *SysDept) GetId() interface{} {
32 | return e.DeptId
33 | }
34 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/flow_manage.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/16 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type StrucTure map[string]interface{}
10 | type FlowSliceInt []int
11 |
12 | type FlowManage struct {
13 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
14 | Name string `gorm:"column:name;type:varchar(100)" json:"name"` // 流程名称
15 | CategoryID uint `gorm:"column:categoryId" json:"categoryId"`
16 | Notice FlowSliceInt `gorm:"column:notice;type:json" json:"notice"` // 变为json切片
17 | Comments bool `gorm:"column:comments;default:false" json:"comments"`
18 | Ratings bool `gorm:"column:ratings;default:false" json:"ratings"`
19 | Description string `gorm:"description:des;type:varchar(512)" json:"description"`
20 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
21 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
22 | StrucTure StrucTure `gorm:"column:structure;type:json" json:"structure"`
23 | models.ControlBy
24 | models.ModelTime
25 | }
26 |
27 | func (*FlowManage) TableName() string {
28 | return "flow_manage"
29 | }
30 |
--------------------------------------------------------------------------------
/app/system/models/sys_dict_data.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "smart-api/common/models"
5 | )
6 |
7 | type SysDictData struct {
8 | DictCode int `json:"dictCode" gorm:"primaryKey;column:dict_code;autoIncrement;comment:主键编码"`
9 | DictSort int `json:"dictSort" gorm:"size:20;comment:DictSort"`
10 | DictLabel string `json:"dictLabel" gorm:"size:128;comment:DictLabel"`
11 | DictValue string `json:"dictValue" gorm:"size:255;comment:DictValue"`
12 | DictType string `json:"dictType" gorm:"size:64;comment:DictType"`
13 | CssClass string `json:"cssClass" gorm:"size:128;comment:CssClass"`
14 | ListClass string `json:"listClass" gorm:"size:128;comment:ListClass"`
15 | IsDefault string `json:"isDefault" gorm:"size:8;comment:IsDefault"`
16 | Status int `json:"status" gorm:"size:4;comment:Status"`
17 | Default string `json:"default" gorm:"size:8;comment:Default"`
18 | Remark string `json:"remark" gorm:"size:255;comment:Remark"`
19 | models.ControlBy
20 | models.ModelTime
21 | }
22 |
23 | func (*SysDictData) TableName() string {
24 | return "sys_dict_data"
25 | }
26 |
27 | func (e *SysDictData) Generate() models.ActiveRecord {
28 | o := *e
29 | return &o
30 | }
31 |
32 | func (e *SysDictData) GetId() interface{} {
33 | return e.DictCode
34 | }
35 |
--------------------------------------------------------------------------------
/app/smart/models/order_items.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/13 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type OrderItems struct {
10 | ID uint `gorm:"primaryKey" json:"id"`
11 | Title string `gorm:"column:title;type:varchar(50)" json:"title"` // 订单项标题
12 | BindTempLate string `gorm:"column:bindTempLate;type:varchar(50)" json:"bindTempLate"` // 绑定模板
13 | Description string `gorm:"column:description;type:varchar(256)" json:"description"` // 订单项描述
14 | Icon string `gorm:"column:icon;type:varchar(50)" json:"icon"` // 订单项图标
15 | CategoryID uint `gorm:"column:categoryId" json:"categoryId"`
16 | Link string `gorm:"column:link;type:varchar(256)" json:"link"` // 连接到网页
17 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
18 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
19 | models.ControlBy
20 | models.ModelTime
21 | }
22 |
23 | func (*OrderItems) TableName() string {
24 | return "order_items"
25 | }
26 |
27 | func (e *OrderItems) Generate() models.ActiveRecord {
28 | o := *e
29 | return &o
30 | }
31 |
32 | func (e *OrderItems) GetId() interface{} {
33 | return e.ID
34 | }
35 |
--------------------------------------------------------------------------------
/cmd/cobra.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "errors"
5 | "fmt"
6 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
7 | "os"
8 | "smart-api/cmd/api"
9 | "smart-api/cmd/migrate"
10 | "smart-api/common/global"
11 |
12 | "github.com/spf13/cobra"
13 | )
14 |
15 | var rootCmd = &cobra.Command{
16 | Use: "smart",
17 | Short: "smart",
18 | SilenceUsage: true,
19 | Long: `smart`,
20 | Args: func(cmd *cobra.Command, args []string) error {
21 | if len(args) < 1 {
22 | tip()
23 | return errors.New(pkg.Red("requires at least one arg"))
24 | }
25 | return nil
26 | },
27 | PersistentPreRunE: func(*cobra.Command, []string) error { return nil },
28 | Run: func(cmd *cobra.Command, args []string) {
29 | tip()
30 | },
31 | }
32 |
33 | func tip() {
34 | usageStr := `欢迎使用 ` + pkg.Green(`smart `+global.Version) + ` 可以使用 ` + pkg.Red(`-h`) + ` 查看命令`
35 | usageStr1 := `https://blog.csdn.net/weixin_43798031?spm=1000.2115.3001.5343`
36 | fmt.Printf("%s\n", usageStr)
37 | fmt.Printf("%s\n", usageStr1)
38 | }
39 |
40 | func init() {
41 | rootCmd.AddCommand(api.StartCmd)
42 | rootCmd.AddCommand(migrate.StartCmd)
43 | }
44 |
45 | // Execute : apply commands
46 | func Execute() {
47 | if err := rootCmd.Execute(); err != nil {
48 | os.Exit(-1)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/system/router/sys_dict.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/middleware"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, registerDictRouter)
12 | }
13 |
14 | func registerDictRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
15 | dictApi := apis.SysDictType{}
16 | dataApi := apis.SysDictData{}
17 | dicts := v1.Group("/dict").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
18 | {
19 |
20 | dicts.GET("/data", dataApi.GetPage)
21 | dicts.GET("/data/:dictCode", dataApi.Get)
22 | dicts.POST("/data", dataApi.Insert)
23 | dicts.PUT("/data/:dictCode", dataApi.Update)
24 | dicts.DELETE("/data", dataApi.Delete)
25 |
26 | dicts.GET("/type-option-select", dictApi.GetAll)
27 | dicts.GET("/type", dictApi.GetPage)
28 | dicts.GET("/type/:id", dictApi.Get)
29 | dicts.POST("/type", dictApi.Insert)
30 | dicts.PUT("/type/:id", dictApi.Update)
31 | dicts.DELETE("/type", dictApi.Delete)
32 | }
33 | opSelect := v1.Group("/dict-data").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
34 | {
35 | opSelect.GET("/option-select", dataApi.GetAll)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/system/router/sys_user.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/system/apis"
7 | "smart-api/common/actions"
8 | "smart-api/common/middleware"
9 | )
10 |
11 | func init() {
12 | routerCheckRole = append(routerCheckRole, registerSysUserRouter)
13 | }
14 |
15 | // 需认证的路由代码
16 | func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
17 | api := apis.SysUser{}
18 | r := v1.Group("/sys-user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()).Use(actions.PermissionAction())
19 | {
20 | r.GET("", api.GetPage)
21 | r.GET("/specify-user", api.GetSpecify)
22 | r.GET("/:id", api.Get)
23 | r.POST("", api.Insert)
24 | r.PUT("", api.Update)
25 | r.DELETE("", api.Delete)
26 | }
27 |
28 | user := v1.Group("/user").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()).Use(actions.PermissionAction())
29 | {
30 | user.GET("/profile", api.GetProfile)
31 | user.POST("/avatar", api.InsetAvatar)
32 | user.PUT("/pwd/set", api.UpdatePwd)
33 | user.PUT("/pwd/reset", api.ResetPwd)
34 | user.PUT("/status", api.UpdateStatus)
35 | }
36 | v1auth := v1.Group("").Use(authMiddleware.MiddlewareFunc())
37 | {
38 | v1auth.GET("/getinfo", api.GetInfo)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/common/actions/create.go:
--------------------------------------------------------------------------------
1 | package actions
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gin-gonic/gin"
7 | "github.com/go-admin-team/go-admin-core/sdk/api"
8 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
9 | "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
10 | "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
11 |
12 | "smart-api/common/dto"
13 | "smart-api/common/models"
14 | )
15 |
16 | // CreateAction 通用新增动作
17 | func CreateAction(control dto.Control) gin.HandlerFunc {
18 | return func(c *gin.Context) {
19 | log := api.GetRequestLogger(c)
20 | db, err := pkg.GetOrm(c)
21 | if err != nil {
22 | log.Error(err)
23 | return
24 | }
25 |
26 | //新增操作
27 | req := control.Generate()
28 | err = req.Bind(c)
29 | if err != nil {
30 | response.Error(c, http.StatusUnprocessableEntity, err, err.Error())
31 | return
32 | }
33 | var object models.ActiveRecord
34 | object, err = req.GenerateM()
35 | if err != nil {
36 | response.Error(c, 500, err, "模型生成失败")
37 | return
38 | }
39 | object.SetCreateBy(user.GetUserId(c))
40 | err = db.WithContext(c).Create(object).Error
41 | if err != nil {
42 | log.Errorf("Create error: %s", err)
43 | response.Error(c, 500, err, "创建失败")
44 | return
45 | }
46 | response.OK(c, object.GetId(), "创建成功")
47 | c.Next()
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/common/middleware/customerror.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "runtime"
7 | "strconv"
8 | "strings"
9 | "time"
10 |
11 | "github.com/gin-gonic/gin"
12 | )
13 |
14 | func CustomError(c *gin.Context) {
15 | defer func() {
16 | if err := recover(); err != nil {
17 |
18 | if c.IsAborted() {
19 | c.Status(200)
20 | }
21 | switch errStr := err.(type) {
22 | case string:
23 | p := strings.Split(errStr, "#")
24 | if len(p) == 3 && p[0] == "CustomError" {
25 | statusCode, e := strconv.Atoi(p[1])
26 | if e != nil {
27 | break
28 | }
29 | c.Status(statusCode)
30 | fmt.Println(
31 | time.Now().Format("2006-01-02 15:04:05"),
32 | "[ERROR]",
33 | c.Request.Method,
34 | c.Request.URL,
35 | statusCode,
36 | c.Request.RequestURI,
37 | c.ClientIP(),
38 | p[2],
39 | )
40 | c.JSON(http.StatusOK, gin.H{
41 | "code": statusCode,
42 | "msg": p[2],
43 | })
44 | } else {
45 | c.JSON(http.StatusOK, gin.H{
46 | "code": 500,
47 | "msg": errStr,
48 | })
49 | }
50 | case runtime.Error:
51 | c.JSON(http.StatusOK, gin.H{
52 | "code": 500,
53 | "msg": errStr.Error(),
54 | })
55 | default:
56 | panic(err)
57 | }
58 | }
59 | }()
60 | c.Next()
61 | }
62 |
--------------------------------------------------------------------------------
/common/file_store/oss.go:
--------------------------------------------------------------------------------
1 | package file_store
2 |
3 | import (
4 | "github.com/aliyun/aliyun-oss-go-sdk/oss"
5 | "log"
6 | )
7 |
8 | type ALiYunOSS struct {
9 | Client interface{}
10 | BucketName string
11 | }
12 |
13 | //Setup 装载
14 | //endpoint sss
15 | func (e *ALiYunOSS) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
16 | client, err := oss.New(endpoint, accessKeyID, accessKeySecret)
17 | if err != nil {
18 | log.Println("Error:", err)
19 | return err
20 | }
21 | e.Client = client
22 | e.BucketName = BucketName
23 |
24 | return nil
25 | }
26 |
27 | // UpLoad 文件上传
28 | func (e *ALiYunOSS) UpLoad(yourObjectName string, localFile interface{}) error {
29 | // 获取存储空间。
30 | bucket, err := e.Client.(*oss.Client).Bucket(e.BucketName)
31 | if err != nil {
32 | log.Println("Error:", err)
33 | return err
34 | }
35 | // 设置分片大小为100 KB,指定分片上传并发数为3,并开启断点续传上传。
36 | // 其中与objectKey是同一概念,表示断点续传上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
37 | // "LocalFile"为filePath,100*1024为partSize。
38 | err = bucket.UploadFile(yourObjectName, localFile.(string), 100*1024, oss.Routines(3), oss.Checkpoint(true, ""))
39 | if err != nil {
40 | log.Println("Error:", err)
41 | return err
42 | }
43 | return nil
44 | }
45 |
46 | func (e *ALiYunOSS) GetTempToken() (string, error) {
47 | return "", nil
48 | }
49 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/version/1653638869132_migrate.go:
--------------------------------------------------------------------------------
1 | package version
2 |
3 | import (
4 | "gorm.io/gorm"
5 | "runtime"
6 | "smart-api/cmd/migrate/migration/models"
7 | common "smart-api/common/models"
8 | "strconv"
9 |
10 | "smart-api/cmd/migrate/migration"
11 | )
12 |
13 | func init() {
14 | _, fileName, _, _ := runtime.Caller(0)
15 | migration.Migrate.SetVersion(migration.GetFilename(fileName), _1653638869132Test)
16 | }
17 |
18 | func _1653638869132Test(db *gorm.DB, version string) error {
19 | return db.Transaction(func(tx *gorm.DB) error {
20 | var list []models.SysMenu
21 | err := tx.Model(&models.SysMenu{}).Order("parent_id,menu_id").Find(&list).Error
22 | if err != nil {
23 | return err
24 | }
25 | for _, v := range list {
26 | if v.ParentId == 0 {
27 | v.Paths = "/0/" + strconv.Itoa(v.MenuId)
28 | } else {
29 | var e models.SysMenu
30 | err = tx.Model(&models.SysMenu{}).Where("menu_id=?", v.ParentId).First(&e).Error
31 | if err != nil {
32 | if err == gorm.ErrRecordNotFound {
33 | continue
34 | }
35 | return err
36 | }
37 | v.Paths = e.Paths + "/" + strconv.Itoa(v.MenuId)
38 | }
39 | err = tx.Model(&v).Update("paths", v.Paths).Error
40 | if err != nil {
41 | return err
42 | }
43 | }
44 | return tx.Create(&common.Migration{
45 | Version: version,
46 | }).Error
47 | })
48 | }
49 |
--------------------------------------------------------------------------------
/template/v4/actions/router_check_role.go.template:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 |
7 | "smart-api/app/{{.PackageName}}/models"
8 | "smart-api/app/{{.PackageName}}/service/dto"
9 | "smart-api/common/actions"
10 | "smart-api/common/middleware"
11 | )
12 |
13 | func init() {
14 | routerCheckRole = append(routerCheckRole, register{{.ClassName}}Router)
15 | }
16 |
17 | // 需认证的路由代码
18 | func register{{.ClassName}}Router(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
19 | r := v1.Group("/{{.ModuleName}}").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
20 | {
21 | model := &models.{{.ClassName}}{}
22 | r.GET("", actions.PermissionAction(), actions.IndexAction(model, new(dto.{{.ClassName}}Search), func() interface{} {
23 | list := make([]models.{{.ClassName}}, 0)
24 | return &list
25 | }))
26 | r.GET("/:id", actions.PermissionAction(), actions.ViewAction(new(dto.{{.ClassName}}ById), nil))
27 | r.POST("", actions.CreateAction(new(dto.{{.ClassName}}Control)))
28 | r.PUT("/:id", actions.PermissionAction(), actions.UpdateAction(new(dto.{{.ClassName}}Control)))
29 | r.DELETE("", actions.PermissionAction(), actions.DeleteAction(new(dto.{{.ClassName}}ById)))
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/common/storage/initialize.go:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: lwnmengjing
3 | * @Date: 2021/6/10 3:39 下午
4 | * @Last Modified by: lwnmengjing
5 | * @Last Modified time: 2021/6/10 3:39 下午
6 | */
7 |
8 | package storage
9 |
10 | import (
11 | "log"
12 |
13 | "github.com/go-admin-team/go-admin-core/sdk"
14 | "github.com/go-admin-team/go-admin-core/sdk/config"
15 | "github.com/go-admin-team/go-admin-core/sdk/pkg/captcha"
16 | )
17 |
18 | // Setup 配置storage组件
19 | func Setup() {
20 | //4. 设置缓存
21 | cacheAdapter, err := config.CacheConfig.Setup()
22 | if err != nil {
23 | log.Fatalf("cache setup error, %s\n", err.Error())
24 | }
25 | sdk.Runtime.SetCacheAdapter(cacheAdapter)
26 | //5. 设置验证码store
27 | captcha.SetStore(captcha.NewCacheStore(cacheAdapter, 600))
28 |
29 | //6. 设置队列
30 | if !config.QueueConfig.Empty() {
31 | if q := sdk.Runtime.GetQueueAdapter(); q != nil {
32 | q.Shutdown()
33 | }
34 | queueAdapter, err := config.QueueConfig.Setup()
35 | if err != nil {
36 | log.Fatalf("queue setup error, %s\n", err.Error())
37 | }
38 | sdk.Runtime.SetQueueAdapter(queueAdapter)
39 | defer func() {
40 | go queueAdapter.Run()
41 | }()
42 | }
43 |
44 | //7. 设置分布式锁
45 | if !config.LockerConfig.Empty() {
46 | lockerAdapter, err := config.LockerConfig.Setup()
47 | if err != nil {
48 | log.Fatalf("locker setup error, %s\n", err.Error())
49 | }
50 | sdk.Runtime.SetLockerAdapter(lockerAdapter)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/common/utils/encrypt.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/8/30 19:19
3 | package utils
4 |
5 | import (
6 | "crypto/aes"
7 | "crypto/cipher"
8 | "crypto/rand"
9 | "encoding/base64"
10 | "errors"
11 | "io"
12 | )
13 |
14 | // Encrypt encrypts plain text string into base64 encoded string
15 | func Encrypt(plainText, key string) (string, error) {
16 | block, err := aes.NewCipher([]byte(key))
17 | if err != nil {
18 | return "", err
19 | }
20 | ciphertext := make([]byte, aes.BlockSize+len(plainText))
21 | iv := ciphertext[:aes.BlockSize]
22 | if _, err := io.ReadFull(rand.Reader, iv); err != nil {
23 | return "", err
24 | }
25 | stream := cipher.NewCFBEncrypter(block, iv)
26 | stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(plainText))
27 | return base64.URLEncoding.EncodeToString(ciphertext), nil
28 | }
29 |
30 | // Decrypt decrypts base64 encoded string into plain text string
31 | func Decrypt(cipherText, key string) (string, error) {
32 | ciphertext, _ := base64.URLEncoding.DecodeString(cipherText)
33 | block, err := aes.NewCipher([]byte(key))
34 | if err != nil {
35 | return "", err
36 | }
37 | if len(ciphertext) < aes.BlockSize {
38 | return "", errors.New("ciphertext too short")
39 | }
40 | iv := ciphertext[:aes.BlockSize]
41 | ciphertext = ciphertext[aes.BlockSize:]
42 | stream := cipher.NewCFBDecrypter(block, iv)
43 | stream.XORKeyStream(ciphertext, ciphertext)
44 | return string(ciphertext), nil
45 | }
46 |
--------------------------------------------------------------------------------
/app/jobs/router/sys_job.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/jobs/apis"
7 | models2 "smart-api/app/jobs/models"
8 | dto2 "smart-api/app/jobs/service/dto"
9 | "smart-api/common/actions"
10 | "smart-api/common/middleware"
11 | )
12 |
13 | func init() {
14 | routerCheckRole = append(routerCheckRole, registerSysJobRouter)
15 | }
16 |
17 | // 需认证的路由代码
18 | func registerSysJobRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
19 |
20 | r := v1.Group("/sysjob").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
21 | {
22 | sysJob := &models2.SysJob{}
23 | r.GET("", actions.PermissionAction(), actions.IndexAction(sysJob, new(dto2.SysJobSearch), func() interface{} {
24 | list := make([]models2.SysJob, 0)
25 | return &list
26 | }))
27 | r.GET("/:id", actions.PermissionAction(), actions.ViewAction(new(dto2.SysJobById), func() interface{} {
28 | return &dto2.SysJobItem{}
29 | }))
30 | r.POST("", actions.CreateAction(new(dto2.SysJobControl)))
31 | r.PUT("", actions.PermissionAction(), actions.UpdateAction(new(dto2.SysJobControl)))
32 | r.DELETE("", actions.PermissionAction(), actions.DeleteAction(new(dto2.SysJobById)))
33 | }
34 | sysJob := apis.SysJob{}
35 |
36 | v1.GET("/job/remove/:id", sysJob.RemoveJobForService)
37 | v1.GET("/job/start/:id", sysJob.StartJobForService)
38 | }
39 |
--------------------------------------------------------------------------------
/static/form-generator/preview.html:
--------------------------------------------------------------------------------
1 | form-generator-preview
--------------------------------------------------------------------------------
/cmd/migrate/migration/version/1599190683659_tables.go:
--------------------------------------------------------------------------------
1 | package version
2 |
3 | import (
4 | "github.com/go-admin-team/go-admin-core/sdk/config"
5 | "runtime"
6 |
7 | "smart-api/cmd/migrate/migration"
8 | "smart-api/cmd/migrate/migration/models"
9 | common "smart-api/common/models"
10 |
11 | "gorm.io/gorm"
12 | )
13 |
14 | func init() {
15 | _, fileName, _, _ := runtime.Caller(0)
16 | migration.Migrate.SetVersion(migration.GetFilename(fileName), _1599190683659Tables)
17 | }
18 |
19 | func _1599190683659Tables(db *gorm.DB, version string) error {
20 | return db.Transaction(func(tx *gorm.DB) error {
21 | if config.DatabaseConfig.Driver == "mysql" {
22 | tx = tx.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4")
23 | }
24 | err := tx.Migrator().AutoMigrate(
25 | new(models.SysDept),
26 | new(models.SysConfig),
27 | new(models.SysTables),
28 | new(models.SysColumns),
29 | new(models.SysMenu),
30 | new(models.SysLoginLog),
31 | new(models.SysOperaLog),
32 | new(models.SysRoleDept),
33 | new(models.SysUser),
34 | new(models.SysRole),
35 | new(models.SysPost),
36 | new(models.DictData),
37 | new(models.DictType),
38 | new(models.SysJob),
39 | new(models.SysConfig),
40 | new(models.SysApi),
41 | new(models.TbDemo),
42 | )
43 | if err != nil {
44 | return err
45 | }
46 |
47 | return tx.Create(&common.Migration{
48 | Version: version,
49 | }).Error
50 | })
51 | }
52 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/init.go:
--------------------------------------------------------------------------------
1 | package migration
2 |
3 | import (
4 | "log"
5 | "path/filepath"
6 | "sort"
7 | "sync"
8 |
9 | "gorm.io/gorm"
10 | )
11 |
12 | var Migrate = &Migration{
13 | version: make(map[string]func(db *gorm.DB, version string) error),
14 | }
15 |
16 | type Migration struct {
17 | db *gorm.DB
18 | version map[string]func(db *gorm.DB, version string) error
19 | mutex sync.Mutex
20 | }
21 |
22 | func (e *Migration) GetDb() *gorm.DB {
23 | return e.db
24 | }
25 |
26 | func (e *Migration) SetDb(db *gorm.DB) {
27 | e.db = db
28 | }
29 |
30 | func (e *Migration) SetVersion(k string, f func(db *gorm.DB, version string) error) {
31 | e.mutex.Lock()
32 | defer e.mutex.Unlock()
33 | e.version[k] = f
34 | }
35 |
36 | func (e *Migration) Migrate() {
37 | versions := make([]string, 0)
38 | for k := range e.version {
39 | versions = append(versions, k)
40 | }
41 | if !sort.StringsAreSorted(versions) {
42 | sort.Strings(versions)
43 | }
44 | var err error
45 | var count int64
46 | for _, v := range versions {
47 | err = e.db.Table("sys_migration").Where("version = ?", v).Count(&count).Error
48 | if err != nil {
49 | log.Fatalln(err)
50 | }
51 | if count > 0 {
52 | log.Println(count)
53 | count = 0
54 | continue
55 | }
56 | err = (e.version[v])(e.db.Debug(), v)
57 | if err != nil {
58 | log.Fatalln(err)
59 | }
60 | }
61 | }
62 |
63 | func GetFilename(s string) string {
64 | s = filepath.Base(s)
65 | return s[:13]
66 | }
67 |
--------------------------------------------------------------------------------
/app/jobs/examples.go:
--------------------------------------------------------------------------------
1 | package jobs
2 |
3 | import (
4 | "fmt"
5 | "github.com/go-admin-team/go-admin-core/sdk"
6 | "smart-api/common/utils"
7 | "time"
8 | )
9 |
10 | // InitJob
11 | // 需要将定义的struct 添加到字典中;
12 | // 字典 key 可以配置到 自动任务 调用目标 中;
13 | func InitJob() {
14 | host := ""
15 | db := sdk.Runtime.GetDbByKey(host)
16 |
17 | jobList = map[string]JobExec{
18 | "ExamplesOne": ExamplesOne{},
19 | "CheckAllMachines": CheckAllMachinesJob{
20 | MachineService: &utils.MachineService{
21 | Orm: db, // 使用指定的 DB 实例
22 | },
23 | },
24 | }
25 | }
26 |
27 | // ExamplesOne
28 | // 新添加的job 必须按照以下格式定义,并实现Exec函数
29 | type ExamplesOne struct {
30 | }
31 |
32 | // CheckAllMachinesJob 用于检查所有机器状态的定时任务
33 | type CheckAllMachinesJob struct {
34 | MachineService *utils.MachineService // 传入你定义的服务
35 | }
36 |
37 | func (t CheckAllMachinesJob) Exec(arg interface{}) error {
38 | // 调用 CheckAllMachines 方法
39 | t.MachineService.CheckAllMachines()
40 | return nil
41 | }
42 |
43 | func (t ExamplesOne) Exec(arg interface{}) error {
44 | str := time.Now().Format(timeFormat) + " [INFO] JobCore ExamplesOne exec success"
45 | // TODO: 这里需要注意 Examples 传入参数是 string 所以 arg.(string);请根据对应的类型进行转化;
46 | switch arg.(type) {
47 |
48 | case string:
49 | if arg.(string) != "" {
50 | fmt.Println("string", arg.(string))
51 | fmt.Println(str, arg.(string))
52 | } else {
53 | fmt.Println("arg is nil")
54 | fmt.Println(str, "arg is nil")
55 | }
56 | break
57 | }
58 |
59 | return nil
60 | }
61 |
--------------------------------------------------------------------------------
/common/file_store/obs.go:
--------------------------------------------------------------------------------
1 | package file_store
2 |
3 | import (
4 | "fmt"
5 | "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
6 | "log"
7 | )
8 |
9 | type HuaWeiOBS struct {
10 | Client interface{}
11 | BucketName string
12 | }
13 |
14 | func (e *HuaWeiOBS) Setup(endpoint, accessKeyID, accessKeySecret, BucketName string, options ...ClientOption) error {
15 | // 创建ObsClient结构体
16 | client, err := obs.New(accessKeyID, accessKeySecret, endpoint)
17 | if err != nil {
18 | log.Println("Error:", err)
19 | return err
20 | }
21 | e.Client = client
22 | e.BucketName = BucketName
23 | return nil
24 | }
25 |
26 | // UpLoad 文件上传
27 | // yourObjectName 文件路径名称,与objectKey是同一概念,表示断点续传上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg
28 | func (e *HuaWeiOBS) UpLoad(yourObjectName string, localFile interface{}) error {
29 | // 获取存储空间。
30 | input := &obs.PutFileInput{}
31 | input.Bucket = e.BucketName
32 | input.Key = yourObjectName
33 | input.SourceFile = localFile.(string)
34 | output, err := e.Client.(*obs.ObsClient).PutFile(input)
35 |
36 | if err == nil {
37 | fmt.Printf("RequestId:%s\n", output.RequestId)
38 | fmt.Printf("ETag:%s, StorageClass:%s\n", output.ETag, output.StorageClass)
39 | } else {
40 | if obsError, ok := err.(obs.ObsError); ok {
41 | fmt.Println(obsError.Code)
42 | fmt.Println(obsError.Message)
43 | } else {
44 | fmt.Println(err)
45 | }
46 | }
47 | return nil
48 | }
49 |
50 | func (e *HuaWeiOBS) GetTempToken() (string, error) {
51 | return "", nil
52 | }
53 |
--------------------------------------------------------------------------------
/app/system/models/initdb.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "fmt"
5 | "gorm.io/gorm"
6 | "io/ioutil"
7 | "log"
8 | "smart-api/common/global"
9 | "strings"
10 | )
11 |
12 | func InitDb(db *gorm.DB) (err error) {
13 | filePath := "config/db.sql"
14 | err = ExecSql(db, filePath)
15 | if global.Driver == "postgres" {
16 | filePath = "config/pg.sql"
17 | err = ExecSql(db, filePath)
18 | }
19 | return err
20 | }
21 |
22 | func ExecSql(db *gorm.DB, filePath string) error {
23 | sql, err := Ioutil(filePath)
24 | if err != nil {
25 | fmt.Println("数据库基础数据初始化脚本读取失败!原因:", err.Error())
26 | return err
27 | }
28 | sqlList := strings.Split(sql, ";")
29 | for i := 0; i < len(sqlList)-1; i++ {
30 | if strings.Contains(sqlList[i], "--") {
31 | fmt.Println(sqlList[i])
32 | continue
33 | }
34 | sql := strings.Replace(sqlList[i]+";", "\n", "", -1)
35 | sql = strings.TrimSpace(sql)
36 | if err = db.Exec(sql).Error; err != nil {
37 | log.Printf("error sql: %s", sql)
38 | if !strings.Contains(err.Error(), "Query was empty") {
39 | return err
40 | }
41 | }
42 | }
43 | return nil
44 | }
45 |
46 | func Ioutil(filePath string) (string, error) {
47 | if contents, err := ioutil.ReadFile(filePath); err == nil {
48 | //因为contents是[]byte类型,直接转换成string类型后会多一行空格,需要使用strings.Replace替换换行符
49 | result := strings.Replace(string(contents), "\n", "", 1)
50 | fmt.Println("Use ioutil.ReadFile to read a file:", result)
51 | return result, nil
52 | } else {
53 | return "", err
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/common/middleware/handler/user.go:
--------------------------------------------------------------------------------
1 | package handler
2 |
3 | import (
4 | "gorm.io/gorm"
5 | "smart-api/common/models"
6 | )
7 |
8 | type SysUser struct {
9 | UserId int `gorm:"primaryKey;autoIncrement;comment:编码" json:"userId"`
10 | Username string `json:"username" gorm:"size:64;comment:用户名"`
11 | Password string `json:"-" gorm:"size:128;comment:密码"`
12 | NickName string `json:"nickName" gorm:"size:128;comment:昵称"`
13 | Phone string `json:"phone" gorm:"size:11;comment:手机号"`
14 | RoleId int `json:"roleId" gorm:"size:20;comment:角色ID"`
15 | Salt string `json:"-" gorm:"size:255;comment:加盐"`
16 | Avatar string `json:"avatar" gorm:"size:255;comment:头像"`
17 | Sex string `json:"sex" gorm:"size:255;comment:性别"`
18 | Email string `json:"email" gorm:"size:128;comment:邮箱"`
19 | DeptId int `json:"deptId" gorm:"size:20;comment:部门"`
20 | PostId int `json:"postId" gorm:"size:20;comment:岗位"`
21 | Remark string `json:"remark" gorm:"size:255;comment:备注"`
22 | Status string `json:"status" gorm:"size:4;comment:状态"`
23 | DeptIds []int `json:"deptIds" gorm:"-"`
24 | PostIds []int `json:"postIds" gorm:"-"`
25 | RoleIds []int `json:"roleIds" gorm:"-"`
26 | //Dept *SysDept `json:"dept"`
27 | models.ControlBy
28 | models.ModelTime
29 | }
30 |
31 | func (*SysUser) TableName() string {
32 | return "sys_user"
33 | }
34 |
35 | func (e *SysUser) AfterFind(_ *gorm.DB) error {
36 | e.DeptIds = []int{e.DeptId}
37 | e.PostIds = []int{e.PostId}
38 | e.RoleIds = []int{e.RoleId}
39 | return nil
40 | }
41 |
--------------------------------------------------------------------------------
/common/utils/tasklog.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/10/22 16:41
3 | package utils
4 |
5 | import (
6 | "fmt"
7 | "os"
8 | "time"
9 | )
10 |
11 | // TaskLogger 用于记录任务执行的日志
12 | type TaskLogger struct {
13 | logFile *os.File
14 | }
15 |
16 | // NewTaskLogger 创建一个新的 TaskLogger 实例
17 | func NewTaskLogger(orderTitle string, hisTaskUUId string) (*TaskLogger, error) {
18 | // 指定日志文件路径
19 | logDir := "./logs/task-log"
20 |
21 | // 获取当前日期并格式化为字符串
22 | currentDateTime := time.Now().Format("200601021504") // YYYYMMDDHHMM 格式
23 |
24 | logFilePath := fmt.Sprintf("%s/%s-%s_%s.log", logDir, orderTitle, currentDateTime, hisTaskUUId)
25 |
26 | // 确保日志目录存在,如果不存在则创建
27 | if err := os.MkdirAll(logDir, 0755); err != nil {
28 | return nil, fmt.Errorf("failed to create log directory: %v", err)
29 | }
30 |
31 | // 打开日志文件,确保以追加模式打开
32 | logFile, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
33 | if err != nil {
34 | return nil, fmt.Errorf("failed to open log file: %v", err)
35 | }
36 |
37 | return &TaskLogger{logFile: logFile}, nil
38 | }
39 |
40 | // Log 写入日志信息
41 | func (t *TaskLogger) Log(message string) {
42 | // 使用更高精度的时间戳
43 | _, err := t.logFile.WriteString(fmt.Sprintf("%s: %s\n", time.Now().Format("2006-01-02 15:04:05.000000"), message))
44 | if err != nil {
45 | fmt.Printf("Failed to write log: %v\n", err)
46 | }
47 | }
48 |
49 | // Close 关闭日志文件
50 | func (t *TaskLogger) Close() {
51 | if err := t.logFile.Close(); err != nil {
52 | fmt.Printf("Failed to close log file: %v\n", err)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/version/1730013300607_migrate.go:
--------------------------------------------------------------------------------
1 | package version
2 |
3 | import (
4 | "github.com/go-admin-team/go-admin-core/sdk/config"
5 | "gorm.io/gorm"
6 | "runtime"
7 | "smart-api/app/smart/models"
8 | "smart-api/cmd/migrate/migration"
9 | models2 "smart-api/cmd/migrate/migration/models"
10 | common "smart-api/common/models"
11 | )
12 |
13 | func init() {
14 | _, fileName, _, _ := runtime.Caller(0)
15 | migration.Migrate.SetVersion(migration.GetFilename(fileName), _1730013300607Test)
16 | }
17 |
18 | // 添加自定义的表,为系统表
19 | func _1730013300607Test(db *gorm.DB, version string) error {
20 | return db.Transaction(func(tx *gorm.DB) error {
21 | if config.DatabaseConfig.Driver == "mysql" {
22 | tx = tx.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4")
23 | }
24 | // 先进行自动迁移,创建表
25 | err := tx.Migrator().AutoMigrate(
26 | new(models.OrderCategory),
27 | new(models.OrderItems),
28 | new(models.ExecMachine),
29 | new(models.ExecutionHistoryTask),
30 | new(models.FlowManage),
31 | new(models.FlowTemplates),
32 | new(models.OperationHistory),
33 | new(models.OrderComment),
34 | new(models.OrderRating),
35 | new(models.OrderTask),
36 | new(models.OrderWorks),
37 | new(models.UserFavorites),
38 | new(models.WorksNotify),
39 | )
40 | if err != nil {
41 | return err
42 | }
43 | // 确保初始化数据库模型
44 | if err := models2.InitDb(tx); err != nil {
45 | return err
46 | }
47 |
48 | return tx.Create(&common.Migration{
49 | Version: version,
50 | }).Error
51 |
52 | })
53 | }
54 |
--------------------------------------------------------------------------------
/app/system/models/sys_role.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "smart-api/common/models"
4 |
5 | type SysRole struct {
6 | RoleId int `json:"roleId" gorm:"primaryKey;autoIncrement"` // 角色编码
7 | RoleName string `json:"roleName" gorm:"size:128;"` // 角色名称
8 | Status string `json:"status" gorm:"size:4;"` // 状态 1禁用 2正常
9 | RoleKey string `json:"roleKey" gorm:"size:128;"` //角色代码
10 | RoleSort int `json:"roleSort" gorm:""` //角色排序
11 | Flag string `json:"flag" gorm:"size:128;"` //
12 | Remark string `json:"remark" gorm:"size:255;"` //备注
13 | Admin bool `json:"admin" gorm:"size:4;"`
14 | DataScope string `json:"dataScope" gorm:"size:128;"`
15 | Params string `json:"params" gorm:"-"`
16 | MenuIds []int `json:"menuIds" gorm:"-"`
17 | DeptIds []int `json:"deptIds" gorm:"-"`
18 | SysDept []SysDept `json:"sysDept" gorm:"many2many:sys_role_dept;foreignKey:RoleId;joinForeignKey:role_id;references:DeptId;joinReferences:dept_id;"`
19 | SysMenu *[]SysMenu `json:"sysMenu" gorm:"many2many:sys_role_menu;foreignKey:RoleId;joinForeignKey:role_id;references:MenuId;joinReferences:menu_id;"`
20 | models.ControlBy
21 | models.ModelTime
22 | }
23 |
24 | func (*SysRole) TableName() string {
25 | return "sys_role"
26 | }
27 |
28 | func (e *SysRole) Generate() models.ActiveRecord {
29 | o := *e
30 | return &o
31 | }
32 |
33 | func (e *SysRole) GetId() interface{} {
34 | return e.RoleId
35 | }
36 |
--------------------------------------------------------------------------------
/common/actions/index.go:
--------------------------------------------------------------------------------
1 | package actions
2 |
3 | import (
4 | "errors"
5 | "net/http"
6 |
7 | "github.com/gin-gonic/gin"
8 | log "github.com/go-admin-team/go-admin-core/logger"
9 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
10 | "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
11 | "gorm.io/gorm"
12 |
13 | "smart-api/common/dto"
14 | "smart-api/common/models"
15 | )
16 |
17 | // IndexAction 通用查询动作
18 | func IndexAction(m models.ActiveRecord, d dto.Index, f func() interface{}) gin.HandlerFunc {
19 | return func(c *gin.Context) {
20 | db, err := pkg.GetOrm(c)
21 | if err != nil {
22 | log.Error(err)
23 | return
24 | }
25 |
26 | msgID := pkg.GenerateMsgIDFromContext(c)
27 | list := f()
28 | object := m.Generate()
29 | req := d.Generate()
30 | var count int64
31 |
32 | //查询列表
33 | err = req.Bind(c)
34 | if err != nil {
35 | response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
36 | return
37 | }
38 |
39 | //数据权限检查
40 | p := GetPermissionFromContext(c)
41 |
42 | err = db.WithContext(c).Model(object).
43 | Scopes(
44 | dto.MakeCondition(req.GetNeedSearch()),
45 | dto.Paginate(req.GetPageSize(), req.GetPageIndex()),
46 | Permission(object.TableName(), p),
47 | ).
48 | Find(list).Limit(-1).Offset(-1).
49 | Count(&count).Error
50 | if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
51 | log.Errorf("MsgID[%s] Index error: %s", msgID, err)
52 | response.Error(c, 500, err, "查询失败")
53 | return
54 | }
55 | response.PageOK(c, list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功")
56 | c.Next()
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/common/actions/update.go:
--------------------------------------------------------------------------------
1 | package actions
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gin-gonic/gin"
7 | log "github.com/go-admin-team/go-admin-core/logger"
8 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
9 | "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
10 | "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
11 |
12 | "smart-api/common/dto"
13 | "smart-api/common/models"
14 | )
15 |
16 | // UpdateAction 通用更新动作
17 | func UpdateAction(control dto.Control) gin.HandlerFunc {
18 | return func(c *gin.Context) {
19 | db, err := pkg.GetOrm(c)
20 | if err != nil {
21 | log.Error(err)
22 | return
23 | }
24 |
25 | msgID := pkg.GenerateMsgIDFromContext(c)
26 | req := control.Generate()
27 | //更新操作
28 | err = req.Bind(c)
29 | if err != nil {
30 | response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
31 | return
32 | }
33 | var object models.ActiveRecord
34 | object, err = req.GenerateM()
35 | if err != nil {
36 | response.Error(c, 500, err, "模型生成失败")
37 | return
38 | }
39 | object.SetUpdateBy(user.GetUserId(c))
40 |
41 | //数据权限检查
42 | p := GetPermissionFromContext(c)
43 |
44 | db = db.WithContext(c).Scopes(
45 | Permission(object.TableName(), p),
46 | ).Where(req.GetId()).Updates(object)
47 | if err = db.Error; err != nil {
48 | log.Errorf("MsgID[%s] Update error: %s", msgID, err)
49 | response.Error(c, 500, err, "更新失败")
50 | return
51 | }
52 | if db.RowsAffected == 0 {
53 | response.Error(c, http.StatusForbidden, nil, "无权更新该数据")
54 | return
55 | }
56 | response.OK(c, object.GetId(), "更新成功")
57 | c.Next()
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/template/v4/model.go.template:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | {{- $bb := false -}}
5 | {{- range .Columns -}}
6 | {{- $z := .IsQuery -}}
7 | {{- if ($z) -}}
8 | {{- if eq .GoType "time.Time" -}}{{- $bb = true -}}{{- end -}}
9 | {{- end -}}
10 | {{- end -}}
11 | {{- range .Columns -}}
12 | {{- if eq .GoField "CreatedAt" -}}
13 | {{- else if eq .GoField "UpdatedAt" -}}
14 | {{- else if eq .GoField "DeletedAt" -}}
15 | {{- else -}}
16 | {{- if eq .GoType "time.Time" -}}{{- $bb = true -}}{{- end -}}
17 | {{- end -}}
18 | {{- end -}}
19 | {{- if eq $bb true }}
20 | "time"
21 | {{- end }}
22 |
23 | "smart-api/common/models"
24 |
25 | )
26 |
27 | type {{.ClassName}} struct {
28 | models.Model
29 | {{ range .Columns -}}
30 | {{$x := .Pk}}
31 | {{- if ($x) }}
32 | {{- else if eq .GoField "CreatedAt" -}}
33 | {{- else if eq .GoField "UpdatedAt" -}}
34 | {{- else if eq .GoField "DeletedAt" -}}
35 | {{- else if eq .GoField "CreateBy" -}}
36 | {{- else if eq .GoField "UpdateBy" -}}
37 | {{- else }}
38 | {{.GoField}} {{.GoType}} `json:"{{.JsonField}}" gorm:"type:{{.ColumnType}};comment:{{- if eq .ColumnComment "" -}}{{.GoField}}{{- else -}}{{.ColumnComment}}{{end -}}"` {{end -}}
39 | {{- end }}
40 | models.ModelTime
41 | models.ControlBy
42 | }
43 |
44 | func ({{.ClassName}}) TableName() string {
45 | return "{{.TBName}}"
46 | }
47 |
48 | func (e *{{.ClassName}}) Generate() models.ActiveRecord {
49 | o := *e
50 | return &o
51 | }
52 |
53 | func (e *{{.ClassName}}) GetId() interface{} {
54 | return e.{{.PkGoField}}
55 | }
56 |
--------------------------------------------------------------------------------
/app/jobs/apis/sys_job.go:
--------------------------------------------------------------------------------
1 | package apis
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gin-gonic/gin"
7 | "github.com/go-admin-team/go-admin-core/sdk"
8 | "github.com/go-admin-team/go-admin-core/sdk/api"
9 |
10 | "smart-api/app/jobs/service"
11 | "smart-api/common/dto"
12 | )
13 |
14 | type SysJob struct {
15 | api.Api
16 | }
17 |
18 | // RemoveJobForService 调用service实现
19 | func (e SysJob) RemoveJobForService(c *gin.Context) {
20 | v := dto.GeneralDelDto{}
21 | s := service.SysJob{}
22 | err := e.MakeContext(c).
23 | MakeOrm().
24 | Bind(&v).
25 | MakeService(&s.Service).
26 | Errors
27 | if err != nil {
28 | e.Logger.Error(err)
29 | return
30 | }
31 |
32 | s.Cron = sdk.Runtime.GetCrontabKey(c.Request.Host)
33 | err = s.RemoveJob(&v)
34 | if err != nil {
35 | e.Logger.Errorf("RemoveJob error, %s", err.Error())
36 | e.Error(500, err, "")
37 | return
38 | }
39 | e.OK(nil, s.Msg)
40 | }
41 |
42 | // StartJobForService 启动job service实现
43 | func (e SysJob) StartJobForService(c *gin.Context) {
44 | e.MakeContext(c)
45 | log := e.GetLogger()
46 | db, err := e.GetOrm()
47 | if err != nil {
48 | log.Error(err)
49 | return
50 | }
51 | var v dto.GeneralGetDto
52 | err = c.BindUri(&v)
53 | if err != nil {
54 | log.Warnf("参数验证错误, error: %s", err)
55 | e.Error(http.StatusUnprocessableEntity, err, "参数验证失败")
56 | return
57 | }
58 | s := service.SysJob{}
59 | s.Orm = db
60 | s.Log = log
61 | s.Cron = sdk.Runtime.GetCrontabKey(c.Request.Host)
62 | err = s.StartJob(&v)
63 | if err != nil {
64 | log.Errorf("GetCrontabKey error, %s", err.Error())
65 | e.Error(500, err, err.Error())
66 | return
67 | }
68 | e.OK(nil, s.Msg)
69 | }
70 |
--------------------------------------------------------------------------------
/app/smart/service/dto/order_rating.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "smart-api/app/smart/models"
5 | common "smart-api/common/models"
6 | )
7 |
8 | type OrderRatingInsertReq struct {
9 | OrderID int `json:"orderID" comment:"工单ID"` // 工单ID
10 | Ratings int `json:"ratings" comment:"评分"` // 评分
11 | common.ControlBy
12 | }
13 |
14 | // Generate 生成 OrderRating 模型实例
15 | func (s *OrderRatingInsertReq) Generate(model *models.OrderRating) {
16 | model.OrderID = s.OrderID
17 | model.Ratings = s.Ratings
18 | model.ControlBy = s.ControlBy
19 | }
20 |
21 | // GetId 获取数据对应的 ID
22 | func (s *OrderRatingInsertReq) GetId() interface{} {
23 | return s.OrderID
24 | }
25 |
26 | type OrderRatingUpdateReq struct {
27 | ID int `uri:"id" comment:"ID"` // 评分ID
28 | OrderID int `json:"orderID" comment:"工单ID"` // 工单ID
29 | Ratings int `json:"ratings" comment:"评分"` // 评分
30 | common.ControlBy
31 | common.ModelTime
32 | }
33 |
34 | // Generate 生成 OrderRating 模型实例
35 | func (s *OrderRatingUpdateReq) Generate(model *models.OrderRating) {
36 | model.ID = s.ID
37 | model.OrderID = s.OrderID
38 | model.Ratings = s.Ratings
39 | model.ControlBy = s.ControlBy
40 | }
41 |
42 | // GetId 获取数据对应的 ID
43 | func (s *OrderRatingUpdateReq) GetId() interface{} {
44 | return s.ID
45 | }
46 |
47 | type OrderRatingGetReq struct {
48 | OrderId int `uri:"orderID" comment:"工单ID"` // 评分ID
49 | }
50 |
51 | // GetId 获取数据对应的 ID
52 | func (s *OrderRatingGetReq) GetId() interface{} {
53 | return s.OrderId
54 | }
55 |
56 | type OrderRatingDeleteReq struct {
57 | ID int `json:"id" comment:"ID"` // 评分ID
58 | }
59 |
60 | // GetId 获取数据对应的 ID
61 | func (s *OrderRatingDeleteReq) GetId() interface{} {
62 | return s.ID
63 | }
64 |
--------------------------------------------------------------------------------
/common/actions/delete.go:
--------------------------------------------------------------------------------
1 | package actions
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gin-gonic/gin"
7 | log "github.com/go-admin-team/go-admin-core/logger"
8 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
9 | "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
10 | "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
11 |
12 | "smart-api/common/dto"
13 | "smart-api/common/models"
14 | )
15 |
16 | // DeleteAction 通用删除动作
17 | func DeleteAction(control dto.Control) gin.HandlerFunc {
18 | return func(c *gin.Context) {
19 | db, err := pkg.GetOrm(c)
20 | if err != nil {
21 | log.Error(err)
22 | return
23 | }
24 |
25 | msgID := pkg.GenerateMsgIDFromContext(c)
26 | //删除操作
27 | req := control.Generate()
28 | err = req.Bind(c)
29 | if err != nil {
30 | log.Errorf("MsgID[%s] Bind error: %s", msgID, err)
31 | response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
32 | return
33 | }
34 | var object models.ActiveRecord
35 | object, err = req.GenerateM()
36 | if err != nil {
37 | response.Error(c, 500, err, "模型生成失败")
38 | return
39 | }
40 |
41 | object.SetUpdateBy(user.GetUserId(c))
42 |
43 | //数据权限检查
44 | p := GetPermissionFromContext(c)
45 |
46 | db = db.WithContext(c).Scopes(
47 | Permission(object.TableName(), p),
48 | ).Where(req.GetId()).Delete(object)
49 | if err = db.Error; err != nil {
50 | log.Errorf("MsgID[%s] Delete error: %s", msgID, err)
51 | response.Error(c, 500, err, "删除失败")
52 | return
53 | }
54 | if db.RowsAffected == 0 {
55 | response.Error(c, http.StatusForbidden, nil, "无权删除该数据")
56 | return
57 | }
58 | response.OK(c, object.GetId(), "删除成功")
59 | c.Next()
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/other/apis/tools/db_columns.go:
--------------------------------------------------------------------------------
1 | package tools
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
6 | _ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
7 |
8 | "smart-api/app/other/models/tools"
9 | )
10 |
11 | // GetDBColumnList 分页列表数据
12 | // @Summary 分页列表数据 / page list data
13 | // @Description 数据库表列分页列表 / database table column page list
14 | // @Tags 工具 / 生成工具
15 | // @Param tableName query string false "tableName / 数据表名称"
16 | // @Param pageSize query int false "pageSize / 页条数"
17 | // @Param pageIndex query int false "pageIndex / 页码"
18 | // @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
19 | // @Router /api/v1/db/columns/page [get]
20 | func (e Gen) GetDBColumnList(c *gin.Context) {
21 | e.Context = c
22 | log := e.GetLogger()
23 | var data tools.DBColumns
24 | var err error
25 | var pageSize = 10
26 | var pageIndex = 1
27 |
28 | if size := c.Request.FormValue("pageSize"); size != "" {
29 | pageSize, err = pkg.StringToInt(size)
30 | }
31 |
32 | if index := c.Request.FormValue("pageIndex"); index != "" {
33 | pageIndex, err = pkg.StringToInt(index)
34 | }
35 |
36 | db, err := pkg.GetOrm(c)
37 | if err != nil {
38 | log.Errorf("get db connection error, %s", err.Error())
39 | e.Error(500, err, "数据库连接获取失败")
40 | return
41 | }
42 |
43 | data.TableName = c.Request.FormValue("tableName")
44 | pkg.Assert(data.TableName == "", "table name cannot be empty!", 500)
45 | result, count, err := data.GetPage(db, pageSize, pageIndex)
46 | if err != nil {
47 | log.Errorf("GetPage error, %s", err.Error())
48 | e.Error(500, err, "")
49 | return
50 | }
51 | e.PageOK(result, count, pageIndex, pageSize, "查询成功")
52 | }
53 |
--------------------------------------------------------------------------------
/common/actions/view.go:
--------------------------------------------------------------------------------
1 | package actions
2 |
3 | import (
4 | "errors"
5 | "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
6 | "net/http"
7 |
8 | "github.com/gin-gonic/gin"
9 | log "github.com/go-admin-team/go-admin-core/logger"
10 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
11 | "gorm.io/gorm"
12 |
13 | "smart-api/common/dto"
14 | "smart-api/common/models"
15 | )
16 |
17 | // ViewAction 通用详情动作
18 | func ViewAction(control dto.Control, f func() interface{}) gin.HandlerFunc {
19 | return func(c *gin.Context) {
20 | db, err := pkg.GetOrm(c)
21 | if err != nil {
22 | log.Error(err)
23 | return
24 | }
25 |
26 | msgID := pkg.GenerateMsgIDFromContext(c)
27 | //查看详情
28 | req := control.Generate()
29 | err = req.Bind(c)
30 | if err != nil {
31 | response.Error(c, http.StatusUnprocessableEntity, err, "参数验证失败")
32 | return
33 | }
34 | var object models.ActiveRecord
35 | object, err = req.GenerateM()
36 | if err != nil {
37 | response.Error(c, 500, err, "模型生成失败")
38 | return
39 | }
40 |
41 | var rsp interface{}
42 | if f != nil {
43 | rsp = f()
44 | } else {
45 | rsp, _ = req.GenerateM()
46 | }
47 |
48 | //数据权限检查
49 | p := GetPermissionFromContext(c)
50 |
51 | err = db.Model(object).WithContext(c).Scopes(
52 | Permission(object.TableName(), p),
53 | ).Where(req.GetId()).First(rsp).Error
54 |
55 | if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
56 | response.Error(c, http.StatusNotFound, nil, "查看对象不存在或无权查看")
57 | return
58 | }
59 | if err != nil {
60 | log.Errorf("MsgID[%s] View error: %s", msgID, err)
61 | response.Error(c, 500, err, "查看失败")
62 | return
63 | }
64 | response.OK(c, rsp, "查询成功")
65 | c.Next()
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/smart/models/flow_templates.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/13 21:14
3 | package models
4 |
5 | import (
6 | "database/sql/driver"
7 | "encoding/json"
8 | "errors"
9 | "smart-api/common/models"
10 | )
11 |
12 | type FormData map[string]interface{}
13 |
14 | // vform模板管理表
15 | type FlowTemplates struct {
16 | ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
17 | Name string `gorm:"column:name;type:varchar(100)" json:"name"`
18 | Description string `gorm:"column:description;type:varchar(200)" json:"description"`
19 | BindCount int `gorm:"column:bindCount" json:"bindCount"`
20 | FormData FormData `gorm:"type:json" json:"formData"`
21 | CategoryID uint `gorm:"column:categoryId" json:"categoryId"`
22 | BindFlow uint `gorm:"column:bindFlow" json:"bindFlow"`
23 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
24 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
25 | models.ControlBy
26 | models.ModelTime
27 | }
28 |
29 | func (*FlowTemplates) TableName() string {
30 | return "flow_templates"
31 | }
32 |
33 | func (e *FlowTemplates) Generate() models.ActiveRecord {
34 | o := *e
35 | return &o
36 | }
37 |
38 | func (e *FlowTemplates) GetId() interface{} {
39 | return e.ID
40 | }
41 |
42 | // FormData 的 Scan 和 Value 方法
43 | func (e *FormData) Scan(value interface{}) error {
44 | bytes, ok := value.([]byte)
45 | if !ok {
46 | return errors.New("Scan source is not []byte")
47 | }
48 | return json.Unmarshal(bytes, &e)
49 | }
50 |
51 | func (e FormData) Value() (driver.Value, error) {
52 | bytes, err := json.Marshal(e)
53 | if err != nil {
54 | return nil, err
55 | }
56 | return string(bytes), nil
57 | }
58 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_user.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "golang.org/x/crypto/bcrypt"
5 | "gorm.io/gorm"
6 | )
7 |
8 | type SysUser struct {
9 | UserId int `gorm:"primaryKey;autoIncrement;comment:编码" json:"userId"`
10 | Username string `json:"username" gorm:"type:varchar(64);comment:用户名"`
11 | Password string `json:"-" gorm:"type:varchar(128);comment:密码"`
12 | NickName string `json:"nickName" gorm:"type:varchar(128);comment:昵称"`
13 | Phone string `json:"phone" gorm:"type:varchar(11);comment:手机号"`
14 | RoleId int `json:"roleId" gorm:"type:bigint;comment:角色ID"`
15 | Salt string `json:"-" gorm:"type:varchar(255);comment:加盐"`
16 | Avatar string `json:"avatar" gorm:"type:varchar(255);comment:头像"`
17 | Sex string `json:"sex" gorm:"type:varchar(255);comment:性别"`
18 | Email string `json:"email" gorm:"type:varchar(128);comment:邮箱"`
19 | DeptId int `json:"deptId" gorm:"type:bigint;comment:部门"`
20 | PostId int `json:"postId" gorm:"type:bigint;comment:岗位"`
21 | Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"`
22 | Status string `json:"status" gorm:"type:varchar(4);comment:状态"`
23 | Source string `json:"source" gorm:"size:255;comment:用户来源"`
24 | ControlBy
25 | ModelTime
26 | }
27 |
28 | func (*SysUser) TableName() string {
29 | return "sys_user"
30 | }
31 |
32 | // Encrypt 加密
33 | func (e *SysUser) Encrypt() (err error) {
34 | if e.Password == "" {
35 | return
36 | }
37 |
38 | var hash []byte
39 | if hash, err = bcrypt.GenerateFromPassword([]byte(e.Password), bcrypt.DefaultCost); err != nil {
40 | return
41 | } else {
42 | e.Password = string(hash)
43 | return
44 | }
45 | }
46 |
47 | func (e *SysUser) BeforeCreate(_ *gorm.DB) error {
48 | return e.Encrypt()
49 | }
50 |
--------------------------------------------------------------------------------
/app/smart/router/order_works.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/12 20:28
3 | package router
4 |
5 | import (
6 | "github.com/gin-gonic/gin"
7 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
8 | "smart-api/app/smart/apis"
9 | "smart-api/common/middleware"
10 | "smart-api/common/utils"
11 | )
12 |
13 | func init() {
14 | routerCheckRole = append(routerCheckRole, registerOrderWorksAuthRouter)
15 | }
16 |
17 | // 注册工单类别路由
18 | func registerOrderWorksAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
19 | api := apis.OrderWorksAPI{}
20 | hisApi := apis.OperationHistory{}
21 | notifyApi := apis.WorksNotify{}
22 |
23 | r := v1.Group("/order-works").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
24 |
25 | ws := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
26 |
27 | {
28 | // 查询所有的工单
29 | r.GET("", api.GetPage)
30 | // 根据ID 查询
31 | r.GET("/:id", api.Get)
32 | // 我的待办
33 | r.GET("/myBacklog", api.MyBacklogGet)
34 | // 我创建的
35 | r.GET("/createdByMe", api.CreatedByMe)
36 | // 与我相关的
37 | r.GET("/relatedToMe", api.RelatedToMe)
38 | // 创建工单
39 | r.POST("", api.Insert)
40 | // 更新工单信息、生成更新记录
41 | r.PUT("", api.Update)
42 | // 工单处理,更新工单当前节点、当前处理人
43 | r.PUT("/handle", api.Handle)
44 | // 删除工单
45 | r.DELETE("", api.Delete)
46 | }
47 | {
48 | // 获取历史变更信息
49 | r.GET("/history", hisApi.GetOperationHistory)
50 | }
51 | {
52 | // 获取通知消息
53 | r.GET("/notify", notifyApi.GetNotify)
54 |
55 | // 发送通知消息
56 | r.POST("/notify", notifyApi.CreateNotify)
57 |
58 | // 处理通知消息
59 | r.PUT("/notify", notifyApi.UpdateNotify)
60 |
61 | }
62 |
63 | {
64 | // 自定义WebSocket处理程序
65 | ws.GET("/ws/task/:id", utils.WsHandler)
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PROJECT:=smart-api
2 |
3 | .PHONY: build
4 | build:
5 | CGO_ENABLED=0 go build -ldflags="-w -s" -a -installsuffix "" -o smart-api .
6 |
7 | # make build-linux
8 | build-linux:
9 | @docker build -t smart-api:latest .
10 | @echo "build successful"
11 |
12 | build-sqlite:
13 | go build -tags sqlite3 -ldflags="-w -s" -a -installsuffix -o smart-api .
14 |
15 | # make run
16 | run:
17 | # delete smart-api-api container
18 | @if [ $(shell docker ps -aq --filter name=smart-api --filter publish=8000) ]; then docker rm -f smart-api; fi
19 |
20 | # 启动方法一 run smart-api-api container docker-compose 启动方式
21 | # 进入到项目根目录 执行 make run 命令
22 | @docker-compose up -d
23 |
24 | # 启动方式二 docker run 这里注意-v挂载的宿主机的地址改为部署时的实际决对路径
25 | #@docker run --name=smart-api -p 8000:8000 -v /home/code/go/src/smart-api/smart-api/config:/smart-api-api/config -v /home/code/go/src/smart-api/smart-api-api/static:/smart-api/static -v /home/code/go/src/smart-api/smart-api/temp:/smart-api-api/temp -d --restart=always smart-api:latest
26 |
27 | @echo "smart-api service is running..."
28 |
29 | # delete Tag= 的镜像
30 | @docker image prune -f
31 | @docker ps -a | grep "smart-api"
32 |
33 | stop:
34 | # delete smart-api-api container
35 | @if [ $(shell docker ps -aq --filter name=smart-api --filter publish=8000) ]; then docker-compose down; fi
36 | #@if [ $(shell docker ps -aq --filter name=smart-api --filter publish=8000) ]; then docker rm -f smart-api; fi
37 | #@echo "smart-api stop success"
38 |
39 |
40 | #.PHONY: test
41 | #test:
42 | # go test -v ./... -cover
43 |
44 | #.PHONY: docker
45 | #docker:
46 | # docker build . -t smart-api:latest
47 |
48 | # make deploy
49 | deploy:
50 |
51 | #@git checkout master
52 | #@git pull origin master
53 | make build-linux
54 | make run
55 |
--------------------------------------------------------------------------------
/app/smart/service/dto/order_comment.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "smart-api/app/smart/models"
5 | common "smart-api/common/models"
6 | )
7 |
8 | type OrderCommentInsertReq struct {
9 | OrderID int `json:"orderID" comment:"工单ID"` // 工单ID
10 | ParentID *int `json:"parentID" comment:"父留言ID"` // 父留言ID
11 | Comments string `json:"comments" comment:"留言"` // 留言
12 | common.ControlBy
13 | }
14 |
15 | func (s *OrderCommentInsertReq) Generate(model *models.OrderComment) {
16 | model.OrderID = s.OrderID
17 | model.ParentID = s.ParentID
18 | model.Comments = s.Comments
19 | model.ControlBy = s.ControlBy
20 | }
21 |
22 | func (s *OrderCommentInsertReq) GetId() interface{} {
23 | return s.OrderID
24 | }
25 |
26 | type OrderCommentUpdateReq struct {
27 | ID int `uri:"id" comment:"ID"` // 留言ID
28 | OrderID int `json:"orderID" comment:"工单ID"` // 工单ID
29 | ParentID *int `json:"parentID" comment:"父留言ID"`
30 | Comments string `json:"comments" comment:"留言"` // 留言内容
31 | common.ControlBy
32 | common.ModelTime
33 | }
34 |
35 | func (s *OrderCommentUpdateReq) Generate(model *models.OrderComment) {
36 | model.ID = s.ID
37 | model.OrderID = s.OrderID
38 | model.ParentID = s.ParentID
39 | model.Comments = s.Comments
40 | model.ControlBy = s.ControlBy
41 | }
42 |
43 | func (s *OrderCommentUpdateReq) GetId() interface{} {
44 | return s.ID
45 | }
46 |
47 | type OrderCommentGetReq struct {
48 | OrderID int `uri:"orderID" comment:"工单ID"` // 工单ID
49 | }
50 |
51 | // GetId 获取留言的 ID
52 | func (s *OrderCommentGetReq) GetId() interface{} {
53 | return s.OrderID
54 | }
55 |
56 | type OrderCommentDeleteReq struct {
57 | ID int `json:"id" comment:"留言ID"` // 留言ID
58 | }
59 |
60 | // GetId 获取留言的 ID
61 | func (s *OrderCommentDeleteReq) GetId() interface{} {
62 | return s.ID
63 | }
64 |
--------------------------------------------------------------------------------
/app/system/service/sys_login_log.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "errors"
5 |
6 | "github.com/go-admin-team/go-admin-core/sdk/service"
7 | "gorm.io/gorm"
8 |
9 | "smart-api/app/system/models"
10 | "smart-api/app/system/service/dto"
11 | cDto "smart-api/common/dto"
12 | )
13 |
14 | type SysLoginLog struct {
15 | service.Service
16 | }
17 |
18 | // GetPage 获取SysLoginLog列表
19 | func (e *SysLoginLog) GetPage(c *dto.SysLoginLogGetPageReq, list *[]models.SysLoginLog, count *int64) error {
20 | var err error
21 | var data models.SysLoginLog
22 |
23 | err = e.Orm.Model(&data).
24 | Scopes(
25 | cDto.MakeCondition(c.GetNeedSearch()),
26 | cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
27 | ).
28 | Find(list).Limit(-1).Offset(-1).
29 | Count(count).Error
30 | if err != nil {
31 | e.Log.Errorf("db error:%s", err)
32 | return err
33 | }
34 | return nil
35 | }
36 |
37 | // Get 获取SysLoginLog对象
38 | func (e *SysLoginLog) Get(d *dto.SysLoginLogGetReq, model *models.SysLoginLog) error {
39 | var err error
40 | db := e.Orm.First(model, d.GetId())
41 | err = db.Error
42 | if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
43 | err = errors.New("查看对象不存在或无权查看")
44 | e.Log.Errorf("db error:%s", err)
45 | return err
46 | }
47 | if err = db.Error; err != nil {
48 | e.Log.Errorf("db error:%s", err)
49 | return err
50 | }
51 | return nil
52 | }
53 |
54 | // Remove 删除SysLoginLog
55 | func (e *SysLoginLog) Remove(c *dto.SysLoginLogDeleteReq) error {
56 | var err error
57 | var data models.SysLoginLog
58 |
59 | db := e.Orm.Delete(&data, c.GetId())
60 | if err = db.Error; err != nil {
61 | err = db.Error
62 | e.Log.Errorf("Delete error: %s", err)
63 | return err
64 | }
65 | if db.RowsAffected == 0 {
66 | err = errors.New("无权删除该数据")
67 | return err
68 | }
69 | return nil
70 | }
71 |
--------------------------------------------------------------------------------
/common/middleware/header.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "net/http"
5 | "time"
6 |
7 | "github.com/gin-gonic/gin"
8 | )
9 |
10 | // NoCache is a middleware function that appends headers
11 | // to prevent the client from caching the HTTP response.
12 | func NoCache(c *gin.Context) {
13 | c.Header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
14 | c.Header("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
15 | c.Header("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
16 | c.Next()
17 | }
18 |
19 | // Options is a middleware function that appends headers
20 | // for options requests and aborts then exits the middleware
21 | // chain and ends the request.
22 | func Options(c *gin.Context) {
23 | if c.Request.Method != "OPTIONS" {
24 | c.Next()
25 | } else {
26 | c.Header("Access-Control-Allow-Origin", "*")
27 | c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
28 | c.Header("Access-Control-Allow-Headers", "authorization, origin, content-type, accept, user-agent")
29 | c.Header("Access-Control-Allow-Credentials", "true")
30 | c.Header("Allow", "HEAD,GET,POST,PUT,PATCH,DELETE,OPTIONS")
31 | c.Header("Content-Type", "application/json")
32 | c.AbortWithStatus(200)
33 | }
34 | }
35 |
36 | // Secure is a middleware function that appends security
37 | // and resource access headers.
38 | func Secure(c *gin.Context) {
39 | c.Header("Access-Control-Allow-Origin", "*")
40 | //c.Header("X-Frame-Options", "DENY")
41 | c.Header("X-Content-Type-Options", "nosniff")
42 | c.Header("X-XSS-Protection", "1; mode=block")
43 | if c.Request.TLS != nil {
44 | c.Header("Strict-Transport-Security", "max-age=31536000")
45 | }
46 |
47 | // Also consider adding Content-Security-Policy headers
48 | // c.Header("Content-Security-Policy", "script-src 'self' https://cdnjs.cloudflare.com")
49 | }
50 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/order_works.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/17 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type BindFlowData map[string]interface{}
10 |
11 | type OrderWorks struct {
12 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
13 | Title string `gorm:"column:title;type:varchar(100)" json:"title"` // 工单标题
14 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
15 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
16 | CurrentNode string `gorm:"column:currentNode;type:varchar(50)" json:"currentNode"` // 当前节点
17 | CurrentHandler string `gorm:"column:currentHandler;type:varchar(50)" json:"currentHandler"` // 当前处理人
18 | CurrentHandlerID int `gorm:"column:currentHandlerId" json:"currentHandlerID"` // 当前处理人ID
19 | Process string `gorm:"column:process;type:varchar(50)" json:"process"` // 流程
20 | Priority string `gorm:"column:priority;type:varchar(20)" json:"priority"` // 优先级
21 | Status string `gorm:"column:status;type:varchar(20)" json:"status"` // 状态
22 | Department string `gorm:"column:department;type:varchar(50)" json:"department"` // 部门
23 | Description string `gorm:"description:des;type:varchar(512)" json:"description"`
24 | Template string `gorm:"column:template;type:varchar(50)" json:"template"` // 模板
25 | FormData FormData `gorm:"type:json" json:"formData"`
26 | BindFlowData BindFlowData `gorm:"column:bindFlowData;type:json" json:"bindFlowData"`
27 | models.ControlBy
28 | models.ModelTime
29 | }
30 |
31 | func (OrderWorks) TableName() string {
32 | return "order_works"
33 | }
34 |
--------------------------------------------------------------------------------
/app/other/router/gen_router.go:
--------------------------------------------------------------------------------
1 | package router
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
6 | "smart-api/app/other/apis/tools"
7 | "smart-api/app/system/apis"
8 | )
9 |
10 | func init() {
11 | routerCheckRole = append(routerCheckRole, sysNoCheckRoleRouter, registerDBRouter, registerSysTableRouter)
12 | }
13 |
14 | func sysNoCheckRoleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
15 | r1 := v1.Group("")
16 | {
17 | sys := apis.System{}
18 | r1.GET("/captcha", sys.GenerateCaptchaHandler)
19 | }
20 |
21 | r := v1.Group("").Use(authMiddleware.MiddlewareFunc())
22 | {
23 | gen := tools.Gen{}
24 | r.GET("/gen/preview/:tableId", gen.Preview)
25 | r.GET("/gen/toproject/:tableId", gen.GenCode)
26 | r.GET("/gen/apitofile/:tableId", gen.GenApiToFile)
27 | r.GET("/gen/todb/:tableId", gen.GenMenuAndApi)
28 | sysTable := tools.SysTable{}
29 | r.GET("/gen/tabletree", sysTable.GetSysTablesTree)
30 | }
31 | }
32 |
33 | func registerDBRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
34 | db := v1.Group("/db").Use(authMiddleware.MiddlewareFunc())
35 | {
36 | gen := tools.Gen{}
37 | db.GET("/tables/page", gen.GetDBTableList)
38 | db.GET("/columns/page", gen.GetDBColumnList)
39 | }
40 | }
41 |
42 | func registerSysTableRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
43 | tables := v1.Group("/sys/tables")
44 | {
45 | sysTable := tools.SysTable{}
46 | tables.Group("").Use(authMiddleware.MiddlewareFunc()).GET("/page", sysTable.GetPage)
47 | tablesInfo := tables.Group("/info").Use(authMiddleware.MiddlewareFunc())
48 | {
49 | tablesInfo.POST("", sysTable.Insert)
50 | tablesInfo.PUT("", sysTable.Update)
51 | tablesInfo.DELETE("/:tableId", sysTable.Delete)
52 | tablesInfo.GET("/:tableId", sysTable.Get)
53 | tablesInfo.GET("", sysTable.GetSysTablesInfo)
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_opera_log.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type SysOperaLog struct {
8 | Model
9 | Title string `json:"title" gorm:"type:varchar(255);comment:操作模块"`
10 | BusinessType string `json:"businessType" gorm:"type:varchar(128);comment:操作类型"`
11 | BusinessTypes string `json:"businessTypes" gorm:"type:varchar(128);comment:BusinessTypes"`
12 | Method string `json:"method" gorm:"type:varchar(128);comment:函数"`
13 | RequestMethod string `json:"requestMethod" gorm:"type:varchar(128);comment:请求方式: GET POST PUT DELETE"`
14 | OperatorType string `json:"operatorType" gorm:"type:varchar(128);comment:操作类型"`
15 | OperName string `json:"operName" gorm:"type:varchar(128);comment:操作者"`
16 | DeptName string `json:"deptName" gorm:"type:varchar(128);comment:部门名称"`
17 | OperUrl string `json:"operUrl" gorm:"type:varchar(255);comment:访问地址"`
18 | OperIp string `json:"operIp" gorm:"type:varchar(128);comment:客户端ip"`
19 | OperLocation string `json:"operLocation" gorm:"type:varchar(128);comment:访问位置"`
20 | OperParam string `json:"operParam" gorm:"type:text;comment:请求参数"`
21 | Status string `json:"status" gorm:"type:varchar(4);comment:操作状态 1:正常 2:关闭"`
22 | OperTime time.Time `json:"operTime" gorm:"type:timestamp;comment:操作时间"`
23 | JsonResult string `json:"jsonResult" gorm:"type:varchar(255);comment:返回数据"`
24 | Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"`
25 | LatencyTime string `json:"latencyTime" gorm:"type:varchar(128);comment:耗时"`
26 | UserAgent string `json:"userAgent" gorm:"type:varchar(255);comment:ua"`
27 | CreatedAt time.Time `json:"createdAt" gorm:"comment:创建时间"`
28 | UpdatedAt time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
29 | ControlBy
30 | }
31 |
32 | func (SysOperaLog) TableName() string {
33 | return "sys_opera_log"
34 | }
35 |
--------------------------------------------------------------------------------
/template/router.template:
--------------------------------------------------------------------------------
1 | package router
2 |
3 |
4 | import (
5 | "github.com/gin-gonic/gin"
6 | _ "github.com/gin-gonic/gin"
7 | log "github.com/go-admin-team/go-admin-core/logger"
8 | "github.com/go-admin-team/go-admin-core/sdk"
9 | // "github.com/go-admin-team/go-admin-core/sdk/pkg"
10 | "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
11 | jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
12 | common "smart-api/common/middleware"
13 | "os"
14 | )
15 |
16 | var (
17 | routerNoCheckRole = make([]func(*gin.RouterGroup), 0)
18 | routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
19 | )
20 |
21 | // InitRouter 路由初始化
22 | func InitRouter() {
23 | var r *gin.Engine
24 | h := sdk.Runtime.GetEngine()
25 | if h == nil {
26 | h = gin.New()
27 | sdk.Runtime.SetEngine(h)
28 | }
29 | switch h.(type) {
30 | case *gin.Engine:
31 | r = h.(*gin.Engine)
32 | default:
33 | log.Fatal("not support other engine")
34 | os.Exit(-1)
35 | }
36 |
37 | // the jwt middleware
38 | authMiddleware, err := common.AuthInit()
39 | if err != nil {
40 | log.Fatalf("JWT Init Error, %s", err.Error())
41 | }
42 |
43 | // 注册业务路由
44 | InitBusinessRouter(r, authMiddleware)
45 | }
46 |
47 | func InitBusinessRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
48 |
49 | // 无需认证的路由
50 | noCheckRoleRouter(r)
51 | // 需要认证的路由
52 | checkRoleRouter(r, authMiddleware)
53 |
54 | return r
55 | }
56 |
57 | // noCheckRoleRouter 无需认证的路由
58 | func noCheckRoleRouter(r *gin.Engine) {
59 | // 可根据业务需求来设置接口版本
60 | v := r.Group("/api/v1")
61 |
62 | for _, f := range routerNoCheckRole {
63 | f(v)
64 | }
65 | }
66 |
67 | // checkRoleRouter 需要认证的路由
68 | func checkRoleRouter(r *gin.Engine, authMiddleware *jwtauth.GinJWTMiddleware) {
69 | // 可根据业务需求来设置接口版本
70 | v := r.Group("/api/v1")
71 |
72 | for _, f := range routerCheckRole {
73 | f(v, authMiddleware)
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/other/apis/tools/db_tables.go:
--------------------------------------------------------------------------------
1 | package tools
2 |
3 | import (
4 | "errors"
5 | "github.com/gin-gonic/gin"
6 | "github.com/go-admin-team/go-admin-core/sdk/config"
7 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
8 | _ "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
9 |
10 | "smart-api/app/other/models/tools"
11 | )
12 |
13 | // GetDBTableList 分页列表数据
14 | // @Summary 分页列表数据 / page list data
15 | // @Description 数据库表分页列表 / database table page list
16 | // @Tags 工具 / 生成工具
17 | // @Param tableName query string false "tableName / 数据表名称"
18 | // @Param pageSize query int false "pageSize / 页条数"
19 | // @Param pageIndex query int false "pageIndex / 页码"
20 | // @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
21 | // @Router /api/v1/db/tables/page [get]
22 | func (e Gen) GetDBTableList(c *gin.Context) {
23 | //var res response.Response
24 | var data tools.DBTables
25 | var err error
26 | var pageSize = 10
27 | var pageIndex = 1
28 | e.Context = c
29 | log := e.GetLogger()
30 | if config.DatabaseConfig.Driver == "sqlite3" || config.DatabaseConfig.Driver == "postgres" {
31 | err = errors.New("对不起,sqlite3 或 postgres 不支持代码生成!")
32 | log.Warn(err)
33 | e.Error(403, err, "")
34 | return
35 | }
36 |
37 | if size := c.Request.FormValue("pageSize"); size != "" {
38 | pageSize, err = pkg.StringToInt(size)
39 | }
40 |
41 | if index := c.Request.FormValue("pageIndex"); index != "" {
42 | pageIndex, err = pkg.StringToInt(index)
43 | }
44 |
45 | db, err := pkg.GetOrm(c)
46 | if err != nil {
47 | log.Errorf("get db connection error, %s", err.Error())
48 | e.Error(500, err, "数据库连接获取失败")
49 | return
50 | }
51 |
52 | data.TableName = c.Request.FormValue("tableName")
53 | result, count, err := data.GetPage(db, pageSize, pageIndex)
54 | if err != nil {
55 | log.Errorf("GetPage error, %s", err.Error())
56 | e.Error(500, err, "")
57 | return
58 | }
59 | e.PageOK(result, count, pageIndex, pageSize, "查询成功")
60 | }
61 |
--------------------------------------------------------------------------------
/app/smart/service/dto/order_category.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "smart-api/app/smart/models"
5 | common "smart-api/common/models"
6 | )
7 |
8 | type OrderCategoryInsertReq struct {
9 | ID int `uri:"id" comment:"编码"` // 编码
10 | Name string `json:"name" comment:"标题"` // 标题
11 | Creator string `json:"creator" comment:"创建人"` // 创建人
12 | ChineseName string `json:"chineseName" comment:"中文名称"` //中文名称
13 | common.ControlBy
14 | }
15 |
16 | func (s *OrderCategoryInsertReq) Generate(model *models.OrderCategory) {
17 | if s.ID != 0 {
18 | model.ID = s.ID
19 | }
20 | model.Name = s.Name
21 | model.Creator = s.Creator
22 | model.ChineseName = s.ChineseName
23 | model.ControlBy = s.ControlBy
24 | }
25 |
26 | // GetId 获取数据对应的ID
27 | func (s *OrderCategoryInsertReq) GetId() interface{} {
28 | return s.ID
29 | }
30 |
31 | type OrderCategoryUpdateReq struct {
32 | ID int `uri:"id" comment:"编码"` // 编码
33 | Name string `json:"name" comment:"标题"` // 标题
34 | Regenerator string `json:"regenerator" comment:"更新人"` // 更新人
35 | ChineseName string `json:"chineseName" comment:"中文名称"` //中文名称
36 | common.ControlBy
37 | }
38 |
39 | // Generate 结构体数据转化 从 SysDeptControl 至 SysDept 对应的模型
40 | func (s *OrderCategoryUpdateReq) Generate(model *models.OrderCategory) {
41 | if s.ID != 0 {
42 | model.ID = s.ID
43 | }
44 | model.Name = s.Name
45 | model.Regenerator = s.Regenerator
46 | model.ChineseName = s.ChineseName
47 | model.ControlBy = s.ControlBy
48 | }
49 |
50 | // GetId 获取数据对应的ID
51 | func (s *OrderCategoryUpdateReq) GetId() interface{} {
52 | return s.ID
53 | }
54 |
55 | type OrderCategoryGetReq struct {
56 | Id int `uri:"id"`
57 | }
58 |
59 | func (s *OrderCategoryGetReq) GetId() interface{} {
60 | return s.Id
61 | }
62 |
63 | type OrderCategoryDeleteReq struct {
64 | Id int `json:"id"`
65 | }
66 |
67 | func (s *OrderCategoryDeleteReq) GetId() interface{} {
68 | return s.Id
69 | }
70 |
--------------------------------------------------------------------------------
/common/utils/machinehealth.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "fmt"
5 | "gorm.io/gorm"
6 | "gorm.io/gorm/logger"
7 | "smart-api/app/smart/models"
8 | "time"
9 | )
10 |
11 | type MachineService struct {
12 | Orm *gorm.DB
13 | }
14 |
15 | // 测试机器连接并更新心跳字段
16 | func (s *MachineService) TestMachine(machine *models.ExecMachine) error {
17 | var err error
18 |
19 | // 使用 TCP 端口探测
20 | connTest := MachineConn{}
21 | err = connTest.testTCPPort(machine.Ip, machine.Port)
22 | if err != nil {
23 | // 连接失败,更新机器状态为 2
24 | updateErr := s.Orm.Model(machine).UpdateColumns(map[string]interface{}{
25 | "status": 2, // 2 表示连接失败
26 | }).Error
27 | if updateErr != nil {
28 | return fmt.Errorf("failed to update status for machine ID '%v' after connection failure: %v", machine.ID, updateErr)
29 | }
30 | // 返回连接失败错误
31 | return fmt.Errorf("TCP connection test failed: %v", err)
32 | }
33 |
34 | // 连接成功,更新心跳时间和状态为正常
35 | err = s.Orm.Model(machine).UpdateColumns(map[string]interface{}{
36 | "heartbeat": time.Now(), // 更新心跳时间
37 | "status": 1, // 1 表示连接正常
38 | }).Error
39 | if err != nil {
40 | return fmt.Errorf("failed to update heartbeat for machine ID '%v': %v", machine.ID, err)
41 | }
42 |
43 | return nil
44 | }
45 |
46 | // 检测所有机器状态
47 | func (s *MachineService) CheckAllMachines() {
48 | // 暂时禁用日志
49 | s.Orm = s.Orm.Session(&gorm.Session{
50 | Logger: logger.Default.LogMode(logger.Silent),
51 | })
52 |
53 | var machines []models.ExecMachine
54 | // 从数据库中获取所有机器
55 | err := s.Orm.Find(&machines).Error
56 | if err != nil {
57 | fmt.Printf("failed to retrieve machines: %v\n", err)
58 | return
59 | }
60 |
61 | // 逐台机器进行状态检查
62 | for _, machine := range machines {
63 | err = s.TestMachine(&machine)
64 | if err != nil {
65 | fmt.Printf("failed to test connection for machine ID '%v': %v\n", machine.ID, err)
66 | }
67 | }
68 | // 如果需要恢复日志输出,可重新设置
69 | // s.Orm = s.Orm.Session(&gorm.Session{Logger: logger.Default.LogMode(logger.Info)})
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/common/middleware/permission.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "github.com/casbin/casbin/v2/util"
5 | "net/http"
6 |
7 | "github.com/gin-gonic/gin"
8 | "github.com/go-admin-team/go-admin-core/sdk"
9 | "github.com/go-admin-team/go-admin-core/sdk/api"
10 | "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
11 | "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
12 | )
13 |
14 | // AuthCheckRole 权限检查中间件
15 | func AuthCheckRole() gin.HandlerFunc {
16 | return func(c *gin.Context) {
17 | log := api.GetRequestLogger(c)
18 | data, _ := c.Get(jwtauth.JwtPayloadKey)
19 | v := data.(jwtauth.MapClaims)
20 | e := sdk.Runtime.GetCasbinKey(c.Request.Host)
21 | // 不用鉴权的接口信息 settings.go
22 | var res, casbinExclude bool
23 | var err error
24 | //检查权限
25 | if v["rolekey"] == "admin" {
26 | res = true
27 | c.Next()
28 | return
29 | }
30 | // 不做验证的接口信息
31 | for _, i := range CasbinExclude {
32 | if util.KeyMatch2(c.Request.URL.Path, i.Url) && c.Request.Method == i.Method {
33 | casbinExclude = true
34 | break
35 | }
36 | }
37 | if casbinExclude {
38 | log.Infof("Casbin exclusion, no validation method:%s path:%s", c.Request.Method, c.Request.URL.Path)
39 | c.Next()
40 | return
41 | }
42 | res, err = e.Enforce(v["rolekey"], c.Request.URL.Path, c.Request.Method)
43 | if err != nil {
44 | log.Errorf("AuthCheckRole error:%s method:%s path:%s", err, c.Request.Method, c.Request.URL.Path)
45 | response.Error(c, 500, err, "")
46 | return
47 | }
48 |
49 | if res {
50 | log.Infof("isTrue: %v role: %s method: %s path: %s", res, v["rolekey"], c.Request.Method, c.Request.URL.Path)
51 | c.Next()
52 | } else {
53 | log.Warnf("isTrue: %v role: %s method: %s path: %s message: %s", res, v["rolekey"], c.Request.Method, c.Request.URL.Path, "当前request无权限,请管理员确认!")
54 | c.JSON(http.StatusOK, gin.H{
55 | "code": 403,
56 | "msg": "对不起,您没有该接口访问权限,请联系管理员",
57 | })
58 | c.Abort()
59 | return
60 | }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/initdb.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "fmt"
5 | "io/ioutil"
6 | "log"
7 | "smart-api/common/global"
8 | "strings"
9 |
10 | "gorm.io/gorm"
11 | )
12 |
13 | func InitDb(db *gorm.DB) (err error) {
14 | filePath := "config/db.sql"
15 | if global.Driver == "postgres" {
16 | filePath := "config/db.sql"
17 | if err = ExecSql(db, filePath); err != nil {
18 | return err
19 | }
20 | filePath = "config/pg.sql"
21 | err = ExecSql(db, filePath)
22 | } else if global.Driver == "mysql" {
23 | filePath = "config/db-begin-mysql.sql"
24 | if err = ExecSql(db, filePath); err != nil {
25 | return err
26 | }
27 | filePath = "config/db.sql"
28 | if err = ExecSql(db, filePath); err != nil {
29 | return err
30 | }
31 | filePath = "config/db-end-mysql.sql"
32 | err = ExecSql(db, filePath)
33 | } else {
34 | err = ExecSql(db, filePath)
35 | }
36 | return err
37 | }
38 |
39 | func ExecSql(db *gorm.DB, filePath string) error {
40 | sql, err := Ioutil(filePath)
41 | if err != nil {
42 | fmt.Println("数据库基础数据初始化脚本读取失败!原因:", err.Error())
43 | return err
44 | }
45 | sqlList := strings.Split(sql, ";")
46 | for i := 0; i < len(sqlList)-1; i++ {
47 | if strings.Contains(sqlList[i], "--") {
48 | fmt.Println(sqlList[i])
49 | continue
50 | }
51 | sql := strings.Replace(sqlList[i]+";", "\n", "", -1)
52 | sql = strings.TrimSpace(sql)
53 | if err = db.Exec(sql).Error; err != nil {
54 | log.Printf("error sql: %s", sql)
55 | if !strings.Contains(err.Error(), "Query was empty") {
56 | return err
57 | }
58 | }
59 | }
60 | return nil
61 | }
62 |
63 | func Ioutil(filePath string) (string, error) {
64 | if contents, err := ioutil.ReadFile(filePath); err == nil {
65 | //因为contents是[]byte类型,直接转换成string类型后会多一行空格,需要使用strings.Replace替换换行符
66 | result := strings.Replace(string(contents), "\n", "", 1)
67 | fmt.Println("Use ioutil.ReadFile to read a file:", result)
68 | return result, nil
69 | } else {
70 | return "", err
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/exec_machine.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/8/17 19:48
3 | package models
4 |
5 | import (
6 | "smart-api/cmd/migrate/migration/models"
7 | models2 "smart-api/common/models"
8 | )
9 |
10 | type ExecMachine struct {
11 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
12 | Ip string `gorm:"column:ip; type: varchar(15)" json:"ip" form:"ip"` // IP地址
13 | HostName string `gorm:"column:hostname; type: varchar(45)" json:"hostName" form:"hostName"` // 主机名
14 | UserName string `gorm:"column:username;type: varchar(45)" json:"userName" form:"username"` // 用户名
15 | PassWord string `gorm:"column:password;type: varchar(100)" json:"passWord" form:"password"` // 密码
16 | Port int `gorm:"column:port;" json:"port" form:"port"` // 端口
17 | Heartbeat models2.JSONTime `gorm:"column:heartbeat;type:timestamp;default:NULL" json:"heartbeat" form:"heartbeat"` // 最近一次心跳时间
18 | Status int `gorm:"column:status;" json:"status" form:"status"` // 状态
19 | AuthType string `gorm:"column:auth_type;type:varchar(10)" json:"authType" form:"authType"` // 认证方式:1=用户名密码,2=公私钥
20 | PrivateKey string `gorm:"column:private_key;type:varchar(4096)" json:"privateKey" form:"privateKey"` // 私钥内容
21 | Creator string `gorm:"column:creator; type: varchar(45)" json:"creator" form:"creator"` // 创建者
22 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
23 | Description string `gorm:"column:description; type: longtext" json:"description" form:"description"` // 描述信息
24 | models.ControlBy
25 | models.ModelTime
26 | }
27 |
28 | func (*ExecMachine) TableName() string {
29 | return "exec_machine"
30 | }
31 |
--------------------------------------------------------------------------------
/app/system/models/sys_menu.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import "smart-api/common/models"
4 |
5 | type SysMenu struct {
6 | MenuId int `json:"menuId" gorm:"primaryKey;autoIncrement"`
7 | MenuName string `json:"menuName" gorm:"size:128;"`
8 | Title string `json:"title" gorm:"size:128;"`
9 | Icon string `json:"icon" gorm:"size:128;"`
10 | Path string `json:"path" gorm:"size:128;"`
11 | Paths string `json:"paths" gorm:"size:128;"`
12 | MenuType string `json:"menuType" gorm:"size:1;"`
13 | Action string `json:"action" gorm:"size:16;"`
14 | Permission string `json:"permission" gorm:"size:255;"`
15 | ParentId int `json:"parentId" gorm:"size:11;"`
16 | NoCache bool `json:"noCache" gorm:"size:8;"`
17 | Breadcrumb string `json:"breadcrumb" gorm:"size:255;"`
18 | Component string `json:"component" gorm:"size:255;"`
19 | Sort int `json:"sort" gorm:"size:4;"`
20 | Visible string `json:"visible" gorm:"size:1;"`
21 | IsFrame string `json:"isFrame" gorm:"size:1;DEFAULT:0;"`
22 | SysApi []SysApi `json:"sysApi" gorm:"many2many:sys_menu_api_rule"`
23 | Apis []int `json:"apis" gorm:"-"`
24 | DataScope string `json:"dataScope" gorm:"-"`
25 | Params string `json:"params" gorm:"-"`
26 | RoleId int `gorm:"-"`
27 | Children []SysMenu `json:"children,omitempty" gorm:"-"`
28 | IsSelect bool `json:"is_select" gorm:"-"`
29 | models.ControlBy
30 | models.ModelTime
31 | }
32 |
33 | type SysMenuSlice []SysMenu
34 |
35 | func (x SysMenuSlice) Len() int { return len(x) }
36 | func (x SysMenuSlice) Less(i, j int) bool { return x[i].Sort < x[j].Sort }
37 | func (x SysMenuSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
38 |
39 | func (*SysMenu) TableName() string {
40 | return "sys_menu"
41 | }
42 |
43 | func (e *SysMenu) Generate() models.ActiveRecord {
44 | o := *e
45 | return &o
46 | }
47 |
48 | func (e *SysMenu) GetId() interface{} {
49 | return e.MenuId
50 | }
51 |
--------------------------------------------------------------------------------
/app/smart/service/dto/order_statistics.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/9/25 20:28
3 | package dto
4 |
5 | type OrderStatisticsResponse struct {
6 | TotalOrders int `json:"totalOrders"` // 总工单数
7 | TotalOrdersWeekOverWeek float64 `json:"totalOrdersWeekOverWeek"` // 总工单数周同比
8 | TotalOrdersDayOverDay float64 `json:"totalOrdersDayOverDay"` // 总工单数日同比
9 | CompletedOrders int `json:"completedOrders"` // 已完结工单
10 | CompletionRate int `json:"completionRate"` // 完成率
11 | PendingOrders int `json:"pendingOrders"` // 待办工单
12 | CurrentHandlerOrders int `json:"currentHandlerOrders"` // 当前处理的工单
13 | CurrentHandlerWeekOverWeek float64 `json:"currentHandlerWeekOverWeek"` // 当前处理工单周同比
14 | CurrentHandlerDayOverDay float64 `json:"currentHandlerDayOverDay"` // 当前处理工单日同比
15 | DailyAverage int64 `json:"dailyAverage"` // 日均工单数
16 | }
17 |
18 | type OrderCountByPeriodResponse struct {
19 | OrderStats []OrderCountStat `json:"orderStats"` // 工单统计
20 | SubmissionRanking []SubmissionRanking `json:"submissionRanking"` // 个人提交排行榜
21 | }
22 |
23 | type OrderCountStat struct {
24 | Date string `json:"date"` // 日期
25 | Total int `json:"total"` // 所有
26 | Completed int `json:"completed"` // 已完成的
27 | UnderWay int `json:"underWay"` // 进行中的
28 | }
29 |
30 | type SubmissionRanking struct {
31 | Name string `json:"name"` // 创建人
32 | Total int `json:"total"` // 提交数量
33 | }
34 |
35 | type OrderRatingsResponse struct {
36 | RatingsStats []RatingStat `json:"ratingsStats"` // 评分统计
37 | RatingRanking []RatingRanking `json:"ratingRanking"` // 个人评分排行榜
38 | }
39 |
40 | type RatingStat struct {
41 | Date string `json:"date"` // 日期
42 | Average float64 `json:"average"` // 平均评分
43 | }
44 |
45 | type RatingRanking struct {
46 | Name string `json:"name"` // 评价人
47 | Score float64 `json:"score"` // 平均评分
48 | }
49 |
--------------------------------------------------------------------------------
/common/dto/search.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "github.com/go-admin-team/go-admin-core/tools/search"
5 | "gorm.io/gorm"
6 | "smart-api/common/global"
7 | )
8 |
9 | type GeneralDelDto struct {
10 | Id int `uri:"id" json:"id" validate:"required"`
11 | Ids []int `json:"ids"`
12 | }
13 |
14 | func (g GeneralDelDto) GetIds() []int {
15 | ids := make([]int, 0)
16 | if g.Id != 0 {
17 | ids = append(ids, g.Id)
18 | }
19 | if len(g.Ids) > 0 {
20 | for _, id := range g.Ids {
21 | if id > 0 {
22 | ids = append(ids, id)
23 | }
24 | }
25 | } else {
26 | if g.Id > 0 {
27 | ids = append(ids, g.Id)
28 | }
29 | }
30 | if len(ids) <= 0 {
31 | //方式全部删除
32 | ids = append(ids, 0)
33 | }
34 | return ids
35 | }
36 |
37 | type GeneralGetDto struct {
38 | Id int `uri:"id" json:"id" validate:"required"`
39 | }
40 |
41 | func MakeCondition(q interface{}) func(db *gorm.DB) *gorm.DB {
42 | return func(db *gorm.DB) *gorm.DB {
43 | condition := &search.GormCondition{
44 | GormPublic: search.GormPublic{},
45 | Join: make([]*search.GormJoin, 0),
46 | }
47 |
48 | search.ResolveSearchQuery(global.Driver, q, condition)
49 | for _, join := range condition.Join {
50 | if join == nil {
51 | continue
52 | }
53 | db = db.Joins(join.JoinOn)
54 | for k, v := range join.Where {
55 | db = db.Where(k, v...)
56 | }
57 | for k, v := range join.Or {
58 | db = db.Or(k, v...)
59 | }
60 | for _, o := range join.Order {
61 | db = db.Order(o)
62 | }
63 | }
64 | for k, v := range condition.Where {
65 | db = db.Where(k, v...)
66 | }
67 | for k, v := range condition.Or {
68 | db = db.Or(k, v...)
69 | }
70 | for _, o := range condition.Order {
71 | db = db.Order(o)
72 | }
73 | return db
74 | }
75 | }
76 |
77 | func Paginate(pageSize, pageIndex int) func(db *gorm.DB) *gorm.DB {
78 | return func(db *gorm.DB) *gorm.DB {
79 | offset := (pageIndex - 1) * pageSize
80 | if offset < 0 {
81 | offset = 0
82 | }
83 | return db.Offset(offset).Limit(pageSize)
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/common/database/initialize.go:
--------------------------------------------------------------------------------
1 | package database
2 |
3 | import (
4 | "time"
5 |
6 | log "github.com/go-admin-team/go-admin-core/logger"
7 | "github.com/go-admin-team/go-admin-core/sdk"
8 | toolsConfig "github.com/go-admin-team/go-admin-core/sdk/config"
9 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
10 | mycasbin "github.com/go-admin-team/go-admin-core/sdk/pkg/casbin"
11 | toolsDB "github.com/go-admin-team/go-admin-core/tools/database"
12 | . "github.com/go-admin-team/go-admin-core/tools/gorm/logger"
13 | "gorm.io/gorm"
14 | "gorm.io/gorm/logger"
15 | "gorm.io/gorm/schema"
16 |
17 | "smart-api/common/global"
18 | )
19 |
20 | // Setup 配置数据库
21 | func Setup() {
22 | for k := range toolsConfig.DatabasesConfig {
23 | setupSimpleDatabase(k, toolsConfig.DatabasesConfig[k])
24 | }
25 | }
26 |
27 | func setupSimpleDatabase(host string, c *toolsConfig.Database) {
28 | if global.Driver == "" {
29 | global.Driver = c.Driver
30 | }
31 | log.Infof("%s => %s", host, pkg.Green(c.Source))
32 | registers := make([]toolsDB.ResolverConfigure, len(c.Registers))
33 | for i := range c.Registers {
34 | registers[i] = toolsDB.NewResolverConfigure(
35 | c.Registers[i].Sources,
36 | c.Registers[i].Replicas,
37 | c.Registers[i].Policy,
38 | c.Registers[i].Tables)
39 | }
40 | resolverConfig := toolsDB.NewConfigure(c.Source, c.MaxIdleConns, c.MaxOpenConns, c.ConnMaxIdleTime, c.ConnMaxLifeTime, registers)
41 | db, err := resolverConfig.Init(&gorm.Config{
42 | NamingStrategy: schema.NamingStrategy{
43 | SingularTable: true,
44 | },
45 | Logger: New(
46 | logger.Config{
47 | SlowThreshold: time.Second,
48 | Colorful: true,
49 | LogLevel: logger.LogLevel(
50 | log.DefaultLogger.Options().Level.LevelForGorm()),
51 | },
52 | ),
53 | }, opens[c.Driver])
54 |
55 | if err != nil {
56 | log.Fatal(pkg.Red(c.Driver+" connect error :"), err)
57 | } else {
58 | log.Info(pkg.Green(c.Driver + " connect success !"))
59 | }
60 |
61 | e := mycasbin.Setup(db, "")
62 |
63 | sdk.Runtime.SetDb(host, db)
64 | sdk.Runtime.SetCasbin(host, e)
65 | }
66 |
--------------------------------------------------------------------------------
/app/smart/models/exec_machine.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/8/27 21:14
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | )
8 |
9 | type ExecMachine struct {
10 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
11 | Ip string `gorm:"column:ip; type: varchar(15)" json:"ip" form:"ip"` // IP地址
12 | HostName string `gorm:"column:hostname; type: varchar(45)" json:"hostName" form:"hostName"` // 主机名
13 | UserName string `gorm:"column:username;type: varchar(45)" json:"userName" form:"username"` // 用户名
14 | PassWord string `gorm:"column:password;type: varchar(100)" json:"passWord" form:"password"` // 密码
15 | Port int `gorm:"column:port;" json:"port" form:"port"` // 端口
16 | Status int `gorm:"column:status;" json:"status" form:"status"` // 状态 1 为在线 2为离线
17 | AuthType string `gorm:"column:auth_type;type:varchar(10)" json:"authType" form:"authType"` // 认证方式:1=用户名密码,2=公私钥
18 | PrivateKey string `gorm:"column:private_key;type:varchar(4096)" json:"privateKey" form:"privateKey"` // 私钥内容
19 | Creator string `gorm:"column:creator; type: varchar(45)" json:"creator" form:"creator"` // 创建者
20 | Heartbeat models.JSONTime `gorm:"column:heartbeat;type:timestamp;default:NULL" json:"heartbeat" form:"heartbeat"` // 最近一次心跳时间
21 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
22 | Description string `gorm:"column:description; type: longtext" json:"description" form:"description"` // 描述信息
23 | models.ControlBy
24 | models.ModelTime
25 | }
26 |
27 | func (*ExecMachine) TableName() string {
28 | return "exec_machine"
29 | }
30 |
31 | func (e *ExecMachine) Generate() models.ActiveRecord {
32 | o := *e
33 | return &o
34 | }
35 |
36 | func (e *ExecMachine) GetId() interface{} {
37 | return e.ID
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/app/jobs/models/sys_job.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "gorm.io/gorm"
5 | "smart-api/common/models"
6 | )
7 |
8 | type SysJob struct {
9 | JobId int `json:"jobId" gorm:"primaryKey;autoIncrement"` // 编码
10 | JobName string `json:"jobName" gorm:"size:255;"` // 名称
11 | JobGroup string `json:"jobGroup" gorm:"size:255;"` // 任务分组
12 | JobType int `json:"jobType" gorm:"size:1;"` // 任务类型
13 | CronExpression string `json:"cronExpression" gorm:"size:255;"` // cron表达式
14 | InvokeTarget string `json:"invokeTarget" gorm:"size:255;"` // 调用目标
15 | Args string `json:"args" gorm:"size:255;"` // 目标参数
16 | MisfirePolicy int `json:"misfirePolicy" gorm:"size:255;"` // 执行策略
17 | Concurrent int `json:"concurrent" gorm:"size:1;"` // 是否并发
18 | Status int `json:"status" gorm:"size:1;"` // 状态
19 | EntryId int `json:"entry_id" gorm:"size:11;"` // job启动时返回的id
20 | models.ControlBy
21 | models.ModelTime
22 |
23 | DataScope string `json:"dataScope" gorm:"-"`
24 | }
25 |
26 | func (*SysJob) TableName() string {
27 | return "sys_job"
28 | }
29 |
30 | func (e *SysJob) Generate() models.ActiveRecord {
31 | o := *e
32 | return &o
33 | }
34 |
35 | func (e *SysJob) GetId() interface{} {
36 | return e.JobId
37 | }
38 |
39 | func (e *SysJob) SetCreateBy(createBy int) {
40 | e.CreateBy = createBy
41 | }
42 |
43 | func (e *SysJob) SetUpdateBy(updateBy int) {
44 | e.UpdateBy = updateBy
45 | }
46 |
47 | func (e *SysJob) GetList(tx *gorm.DB, list interface{}) (err error) {
48 | return tx.Table(e.TableName()).Where("status = ?", 2).Find(list).Error
49 | }
50 |
51 | // Update 更新SysJob
52 | func (e *SysJob) Update(tx *gorm.DB, id interface{}) (err error) {
53 | return tx.Table(e.TableName()).Where(id).Updates(&e).Error
54 | }
55 |
56 | func (e *SysJob) RemoveAllEntryID(tx *gorm.DB) (update SysJob, err error) {
57 | if err = tx.Table(e.TableName()).Where("entry_id > ?", 0).Update("entry_id", 0).Error; err != nil {
58 | return
59 | }
60 | return
61 | }
62 |
--------------------------------------------------------------------------------
/common/middleware/settings.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | type UrlInfo struct {
4 | Url string
5 | Method string
6 | }
7 |
8 | // CasbinExclude casbin 排除的路由列表
9 | var CasbinExclude = []UrlInfo{
10 | {Url: "/api/v1/dict/type-option-select", Method: "GET"},
11 | {Url: "/api/v1/dict-data/option-select", Method: "GET"},
12 | {Url: "/api/v1/deptTree", Method: "GET"},
13 | {Url: "/api/v1/db/tables/page", Method: "GET"},
14 | {Url: "/api/v1/db/columns/page", Method: "GET"},
15 | {Url: "/api/v1/gen/toproject/:tableId", Method: "GET"},
16 | {Url: "/api/v1/gen/todb/:tableId", Method: "GET"},
17 | {Url: "/api/v1/gen/tabletree", Method: "GET"},
18 | {Url: "/api/v1/gen/preview/:tableId", Method: "GET"},
19 | {Url: "/api/v1/gen/apitofile/:tableId", Method: "GET"},
20 | {Url: "/api/v1/getCaptcha", Method: "GET"},
21 | {Url: "/api/v1/getinfo", Method: "GET"},
22 | {Url: "/api/v1/menuTreeselect", Method: "GET"},
23 | {Url: "/api/v1/menurole", Method: "GET"},
24 | {Url: "/api/v1/menuids", Method: "GET"},
25 | {Url: "/api/v1/roleMenuTreeselect/:roleId", Method: "GET"},
26 | {Url: "/api/v1/roleDeptTreeselect/:roleId", Method: "GET"},
27 | {Url: "/api/v1/refresh_token", Method: "GET"},
28 | {Url: "/api/v1/configKey/:configKey", Method: "GET"},
29 | {Url: "/api/v1/app-config", Method: "GET"},
30 | {Url: "/api/v1/user/profile", Method: "GET"},
31 | {Url: "/info", Method: "GET"},
32 | {Url: "/api/v1/login", Method: "POST"},
33 | {Url: "/api/v1/logout", Method: "POST"},
34 | {Url: "/api/v1/user/avatar", Method: "POST"},
35 | {Url: "/api/v1/user/pwd", Method: "PUT"},
36 | {Url: "/api/v1/metrics", Method: "GET"},
37 | {Url: "/api/v1/health", Method: "GET"},
38 | {Url: "/", Method: "GET"},
39 | {Url: "/api/v1/server-monitor", Method: "GET"},
40 | {Url: "/api/v1/public/uploadFile", Method: "POST"},
41 | {Url: "/api/v1/user/pwd/set", Method: "PUT"},
42 | {Url: "/api/v1/sys-user", Method: "PUT"},
43 | {Url: "/api/v1/post", Method: "GET"},
44 | {Url: "/api/v1/statistics/orders", Method: "GET"},
45 | {Url: "/api/v1/statistics/orders/count", Method: "GET"},
46 | {Url: "/api/v1/statistics/ratings", Method: "GET"},
47 | {Url: "/api/v1/favorite", Method: "GET"},
48 | }
49 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | env:
10 | IMAGE_NAME: registry.ap-northeast-1.aliyuncs.com/smart/smart-api # 镜像名称
11 | TAG: ${{ github.sha }}
12 | IMAGE_NAME_TAG: registry.ap-northeast-1.aliyuncs.com/smart/smart-api:${{ github.sha }}
13 |
14 | jobs:
15 |
16 | build:
17 | runs-on: ubuntu-latest
18 | steps:
19 | - uses: actions/checkout@v3
20 |
21 | - name: Set up Go
22 | uses: actions/setup-go@v3
23 | with:
24 | go-version: 1.24.2
25 | cache: true
26 |
27 | - name: Tidy
28 | run: go mod tidy
29 |
30 | - name: Build
31 | run: env CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -tags "sqlite3,json1" --ldflags "-extldflags -static" -o main .
32 |
33 | - name: Build the Docker image and push
34 | run: |
35 | docker login --username=${{ secrets.DOCKER_USERNAME }} registry.ap-northeast-1.aliyuncs.com --password=${{ secrets.DOCKER_PASSWORD }}
36 | echo "************ docker login end"
37 | docker build -t smart-api:latest .
38 | echo "************ docker build end"
39 | docker tag smart-api ${{ env.IMAGE_NAME_TAG }}
40 | echo "************ docker tag end"
41 | docker images
42 | echo "************ docker images end"
43 | docker push ${{ env.IMAGE_NAME_TAG }} # 推送
44 | echo "************ docker push end"
45 |
46 | - name: Restart server # 第五步,重启服务
47 | uses: appleboy/ssh-action@master
48 | env:
49 | GITHUB_SHA_X: ${GITHUB_SHA}
50 | with:
51 | host: ${{ secrets.SSH_HOST }} # 下面三个配置与上一步类似
52 | username: ${{ secrets.SSH_USERNAME }}
53 | key: ${{ secrets.DEPLOY_KEY }}
54 | # 重启的脚本,根据自身情况做相应改动,一般要做的是migrate数据库以及重启服务器
55 | script: |
56 | sudo docker rm -f smart-api
57 | sudo docker login --username=${{ secrets.DOCKER_USERNAME }} registry.ap-northeast-1.aliyuncs.com --password=${{ secrets.DOCKER_PASSWORD }}
58 | sudo docker run -d -p 8000:8000 --name smart-api ${{ env.IMAGE_NAME_TAG }}
59 |
--------------------------------------------------------------------------------
/app/system/service/dto/sys_login_log.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | import (
4 | "time"
5 |
6 | "smart-api/common/dto"
7 | )
8 |
9 | type SysLoginLogGetPageReq struct {
10 | dto.Pagination `search:"-"`
11 | Username string `form:"username" search:"type:exact;column:username;table:sys_login_log" comment:"用户名"`
12 | Status string `form:"status" search:"type:exact;column:status;table:sys_login_log" comment:"状态"`
13 | Ipaddr string `form:"ipaddr" search:"type:exact;column:ipaddr;table:sys_login_log" comment:"ip地址"`
14 | LoginLocation string `form:"loginLocation" search:"type:exact;column:login_location;table:sys_login_log" comment:"归属地"`
15 | BeginTime string `form:"beginTime" search:"type:gte;column:ctime;table:sys_login_log" comment:"创建时间"`
16 | EndTime string `form:"endTime" search:"type:lte;column:ctime;table:sys_login_log" comment:"创建时间"`
17 | SysLoginLogOrder
18 | }
19 |
20 | type SysLoginLogOrder struct {
21 | CreatedAtOrder string `search:"type:order;column:created_at;table:sys_login_log" form:"createdAtOrder"`
22 | }
23 |
24 | func (m *SysLoginLogGetPageReq) GetNeedSearch() interface{} {
25 | return *m
26 | }
27 |
28 | type SysLoginLogControl struct {
29 | ID int `uri:"Id" comment:"主键"` // 主键
30 | Username string `json:"username" comment:"用户名"`
31 | Status string `json:"status" comment:"状态"`
32 | Ipaddr string `json:"ipaddr" comment:"ip地址"`
33 | LoginLocation string `json:"loginLocation" comment:"归属地"`
34 | Browser string `json:"browser" comment:"浏览器"`
35 | Os string `json:"os" comment:"系统"`
36 | Platform string `json:"platform" comment:"固件"`
37 | LoginTime time.Time `json:"loginTime" comment:"登录时间"`
38 | Remark string `json:"remark" comment:"备注"`
39 | Msg string `json:"msg" comment:"信息"`
40 | }
41 |
42 | type SysLoginLogGetReq struct {
43 | Id int `uri:"id"`
44 | }
45 |
46 | func (s *SysLoginLogGetReq) GetId() interface{} {
47 | return s.Id
48 | }
49 |
50 | // SysLoginLogDeleteReq 功能删除请求参数
51 | type SysLoginLogDeleteReq struct {
52 | Ids []int `json:"ids"`
53 | }
54 |
55 | func (s *SysLoginLogDeleteReq) GetId() interface{} {
56 | return s.Ids
57 | }
58 |
--------------------------------------------------------------------------------
/app/other/models/tools/db_tables.go:
--------------------------------------------------------------------------------
1 | package tools
2 |
3 | import (
4 | "errors"
5 | "github.com/go-admin-team/go-admin-core/sdk/pkg"
6 |
7 | "gorm.io/gorm"
8 |
9 | config2 "github.com/go-admin-team/go-admin-core/sdk/config"
10 | )
11 |
12 | type DBTables struct {
13 | TableName string `gorm:"column:TABLE_NAME" json:"tableName"`
14 | Engine string `gorm:"column:ENGINE" json:"engine"`
15 | TableRows string `gorm:"column:TABLE_ROWS" json:"tableRows"`
16 | TableCollation string `gorm:"column:TABLE_COLLATION" json:"tableCollation"`
17 | CreateTime string `gorm:"column:CREATE_TIME" json:"createTime"`
18 | UpdateTime string `gorm:"column:UPDATE_TIME" json:"updateTime"`
19 | TableComment string `gorm:"column:TABLE_COMMENT" json:"tableComment"`
20 | }
21 |
22 | func (e *DBTables) GetPage(tx *gorm.DB, pageSize int, pageIndex int) ([]DBTables, int, error) {
23 | var doc []DBTables
24 | table := new(gorm.DB)
25 | var count int64
26 |
27 | if config2.DatabaseConfig.Driver == "mysql" {
28 | table = tx.Table("information_schema.tables")
29 | table = table.Where("TABLE_NAME not in (select table_name from `" + config2.GenConfig.DBName + "`.sys_tables) ")
30 | table = table.Where("table_schema= ? ", config2.GenConfig.DBName)
31 |
32 | if e.TableName != "" {
33 | table = table.Where("TABLE_NAME = ?", e.TableName)
34 | }
35 | if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Offset(-1).Limit(-1).Count(&count).Error; err != nil {
36 | return nil, 0, err
37 | }
38 | } else {
39 | pkg.Assert(true, "目前只支持mysql数据库", 500)
40 | }
41 |
42 | //table.Count(&count)
43 | return doc, int(count), nil
44 | }
45 |
46 | func (e *DBTables) Get(tx *gorm.DB) (DBTables, error) {
47 | var doc DBTables
48 | if config2.DatabaseConfig.Driver == "mysql" {
49 | table := tx.Table("information_schema.tables")
50 | table = table.Where("table_schema= ? ", config2.GenConfig.DBName)
51 | if e.TableName == "" {
52 | return doc, errors.New("table name cannot be empty!")
53 | }
54 | table = table.Where("TABLE_NAME = ?", e.TableName)
55 | if err := table.First(&doc).Error; err != nil {
56 | return doc, err
57 | }
58 | } else {
59 | pkg.Assert(true, "目前只支持mysql数据库", 500)
60 | }
61 | return doc, nil
62 | }
63 |
--------------------------------------------------------------------------------
/app/system/service/sys_opera_log.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "errors"
5 |
6 | "smart-api/app/system/models"
7 | "smart-api/app/system/service/dto"
8 | cDto "smart-api/common/dto"
9 |
10 | "github.com/go-admin-team/go-admin-core/sdk/service"
11 | "gorm.io/gorm"
12 | )
13 |
14 | type SysOperaLog struct {
15 | service.Service
16 | }
17 |
18 | // GetPage 获取SysOperaLog列表
19 | func (e *SysOperaLog) GetPage(c *dto.SysOperaLogGetPageReq, list *[]models.SysOperaLog, count *int64) error {
20 | var err error
21 | var data models.SysOperaLog
22 |
23 | err = e.Orm.Model(&data).
24 | Scopes(
25 | cDto.MakeCondition(c.GetNeedSearch()),
26 | cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
27 | ).
28 | Find(list).Limit(-1).Offset(-1).
29 | Count(count).Error
30 | if err != nil {
31 | e.Log.Errorf("Service GetSysOperaLogPage error:%s", err.Error())
32 | return err
33 | }
34 | return nil
35 | }
36 |
37 | // Get 获取SysOperaLog对象
38 | func (e *SysOperaLog) Get(d *dto.SysOperaLogGetReq, model *models.SysOperaLog) error {
39 | var data models.SysOperaLog
40 |
41 | err := e.Orm.Model(&data).
42 | First(model, d.GetId()).Error
43 | if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
44 | err = errors.New("查看对象不存在或无权查看")
45 | e.Log.Errorf("Service GetSysOperaLog error:%s", err.Error())
46 | return err
47 | }
48 | if err != nil {
49 | e.Log.Errorf("Service GetSysOperaLog error:%s", err.Error())
50 | return err
51 | }
52 | return nil
53 | }
54 |
55 | // Insert 创建SysOperaLog对象
56 | func (e *SysOperaLog) Insert(model *models.SysOperaLog) error {
57 | var err error
58 | var data models.SysOperaLog
59 |
60 | err = e.Orm.Model(&data).
61 | Create(model).Error
62 | if err != nil {
63 | e.Log.Errorf("Service InsertSysOperaLog error:%s", err.Error())
64 | return err
65 | }
66 | return nil
67 | }
68 |
69 | // Remove 删除SysOperaLog
70 | func (e *SysOperaLog) Remove(d *dto.SysOperaLogDeleteReq) error {
71 | var err error
72 | var data models.SysOperaLog
73 |
74 | db := e.Orm.Model(&data).Delete(&data, d.GetId())
75 | if err = db.Error; err != nil {
76 | e.Log.Errorf("Service RemoveSysOperaLog error:%s", err.Error())
77 | return err
78 | }
79 | if db.RowsAffected == 0 {
80 | return errors.New("无权删除该数据")
81 | }
82 | return nil
83 | }
84 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/sys_tables.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | type SysTables struct {
4 | TableId int `gorm:"primaryKey;autoIncrement" json:"tableId"` //表编码
5 | TBName string `gorm:"column:table_name;size:255;" json:"tableName"` //表名称
6 | TableComment string `gorm:"size:255;" json:"tableComment"` //表备注
7 | ClassName string `gorm:"size:255;" json:"className"` //类名
8 | TplCategory string `gorm:"size:255;" json:"tplCategory"` //
9 | PackageName string `gorm:"size:255;" json:"packageName"` //包名
10 | ModuleName string `gorm:"size:255;" json:"moduleName"` //go文件名
11 | ModuleFrontName string `gorm:"size:255;comment:前端文件名;" json:"moduleFrontName"` //前端文件名
12 | BusinessName string `gorm:"size:255;" json:"businessName"` //
13 | FunctionName string `gorm:"size:255;" json:"functionName"` //功能名称
14 | FunctionAuthor string `gorm:"size:255;" json:"functionAuthor"` //功能作者
15 | PkColumn string `gorm:"size:255;" json:"pkColumn"`
16 | PkGoField string `gorm:"size:255;" json:"pkGoField"`
17 | PkJsonField string `gorm:"size:255;" json:"pkJsonField"`
18 | Options string `gorm:"size:255;" json:"options"`
19 | TreeCode string `gorm:"size:255;" json:"treeCode"`
20 | TreeParentCode string `gorm:"size:255;" json:"treeParentCode"`
21 | TreeName string `gorm:"size:255;" json:"treeName"`
22 | Tree bool `gorm:"size:1;default:0;" json:"tree"`
23 | Crud bool `gorm:"size:1;default:1;" json:"crud"`
24 | Remark string `gorm:"size:255;" json:"remark"`
25 | IsDataScope int `gorm:"size:1;" json:"isDataScope"`
26 | IsActions int `gorm:"size:1;" json:"isActions"`
27 | IsAuth int `gorm:"size:1;" json:"isAuth"`
28 | IsLogicalDelete string `gorm:"size:1;" json:"isLogicalDelete"`
29 | LogicalDelete bool `gorm:"size:1;" json:"logicalDelete"`
30 | LogicalDeleteColumn string `gorm:"size:128;" json:"logicalDeleteColumn"`
31 | ModelTime
32 | ControlBy
33 | }
34 |
35 | func (SysTables) TableName() string {
36 | return "sys_tables"
37 | }
38 |
--------------------------------------------------------------------------------
/app/system/models/sys_login_log.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "time"
7 |
8 | log "github.com/go-admin-team/go-admin-core/logger"
9 | "github.com/go-admin-team/go-admin-core/sdk"
10 | "github.com/go-admin-team/go-admin-core/storage"
11 |
12 | "smart-api/common/models"
13 | )
14 |
15 | type SysLoginLog struct {
16 | models.Model
17 | Username string `json:"username" gorm:"size:128;comment:用户名"`
18 | Status string `json:"status" gorm:"size:4;comment:状态"`
19 | Ipaddr string `json:"ipaddr" gorm:"size:255;comment:ip地址"`
20 | LoginLocation string `json:"loginLocation" gorm:"size:255;comment:归属地"`
21 | Browser string `json:"browser" gorm:"size:255;comment:浏览器"`
22 | Os string `json:"os" gorm:"size:255;comment:系统"`
23 | Platform string `json:"platform" gorm:"size:255;comment:固件"`
24 | LoginTime time.Time `json:"loginTime" gorm:"comment:登录时间"`
25 | Remark string `json:"remark" gorm:"size:255;comment:备注"`
26 | Msg string `json:"msg" gorm:"size:255;comment:信息"`
27 | CreatedAt time.Time `json:"createdAt" gorm:"comment:创建时间"`
28 | UpdatedAt time.Time `json:"updatedAt" gorm:"comment:最后更新时间"`
29 | models.ControlBy
30 | }
31 |
32 | func (*SysLoginLog) TableName() string {
33 | return "sys_login_log"
34 | }
35 |
36 | func (e *SysLoginLog) Generate() models.ActiveRecord {
37 | o := *e
38 | return &o
39 | }
40 |
41 | func (e *SysLoginLog) GetId() interface{} {
42 | return e.Id
43 | }
44 |
45 | // SaveLoginLog 从队列中获取登录日志
46 | func SaveLoginLog(message storage.Messager) (err error) {
47 | //准备db
48 | db := sdk.Runtime.GetDbByKey(message.GetPrefix())
49 | if db == nil {
50 | err = errors.New("db not exist")
51 | log.Errorf("host[%s]'s %s", message.GetPrefix(), err.Error())
52 | return err
53 | }
54 | var rb []byte
55 | rb, err = json.Marshal(message.GetValues())
56 | if err != nil {
57 | log.Errorf("json Marshal error, %s", err.Error())
58 | return err
59 | }
60 | var l SysLoginLog
61 | err = json.Unmarshal(rb, &l)
62 | if err != nil {
63 | log.Errorf("json Unmarshal error, %s", err.Error())
64 | return err
65 | }
66 | err = db.Create(&l).Error
67 | if err != nil {
68 | log.Errorf("db create error, %s", err.Error())
69 | return err
70 | }
71 | return nil
72 | }
73 |
--------------------------------------------------------------------------------
/cmd/migrate/migration/models/order/common.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/18 16:45
3 | package models
4 |
5 | import (
6 | "smart-api/common/models"
7 | "time"
8 | )
9 |
10 | type OperationHistory struct {
11 | ID uint `gorm:"primaryKey" json:"id"` // 主键ID
12 | Title string `gorm:"column:title;type:varchar(100)" json:"title"` // 工单标题
13 | NodeName string `gorm:"column:node_name;type:varchar(255)" json:"nodeName"` // 节点名称
14 | Transfer string `gorm:"column:transfer;type:varchar(255)" json:"transfer"` // 流转
15 | Remark string `gorm:"column:remark;type:text" json:"remark"` // 备注
16 | Status string `gorm:"column:status;type:varchar(255)" json:"status"` // 流转状态 1 同意, 0 拒绝, 2 其他
17 | HandlerId int `gorm:"column:handlerId;" json:"handlerId"` // 处理人ID
18 | HandlerName string `gorm:"column:handlerName;type:varchar(125)" json:"handlerName"` // 处理人姓名
19 | HandleTime time.Time `gorm:"column:handleTime" json:"handleTime"` // 处理时间
20 | HandleDuration int64 `gorm:"column:handleDuration;type:bigint" json:"handleDuration"` // 处理时长 (以秒为单位)
21 | models.ModelTime
22 | }
23 |
24 | func (*OperationHistory) TableName() string {
25 | return "operation_history"
26 | }
27 |
28 | // 通知消息
29 | type WorksNotify struct {
30 | ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
31 | Title string `gorm:"column:title;type:varchar(100)" json:"title"`
32 | Department string `gorm:"column:department;type:varchar(50)" json:"department"`
33 | Priority string `gorm:"column:priority;type:varchar(20)" json:"priority"`
34 | Status string `gorm:"column:status;type:varchar(20)" json:"status"`
35 | CurrentHandler int `gorm:"column:currentHandler" json:"currentHandler"`
36 | Message string `gorm:"column:message;type:text" json:"message"` // 通知的详细消息内容。
37 | ReadStatus int `gorm:"column:read_status" json:"readStatus"` // 通知的阅读状态,例如是否已读。 0为未读 1为已读
38 | OrderID uint `gorm:"column:order_id" json:"orderId"` // 关联的工单 ID,方便关联具体的工单。
39 | models.ModelTime
40 | models.ControlBy
41 | }
42 |
43 | func (*WorksNotify) TableName() string {
44 | return "works_notify"
45 | }
46 |
--------------------------------------------------------------------------------
/app/smart/models/flow_manage.go:
--------------------------------------------------------------------------------
1 | // @Author sunwenbo
2 | // 2024/7/13 21:14
3 | package models
4 |
5 | import (
6 | "database/sql/driver"
7 | "encoding/json"
8 | "errors"
9 | "smart-api/common/models"
10 | )
11 |
12 | type StrucTure map[string]interface{}
13 |
14 | type NoticeSlice []interface{}
15 |
16 | type FlowManage struct {
17 | ID int `gorm:"primaryKey;autoIncrement" json:"id"`
18 | Name string `gorm:"column:name;type:varchar(100)" json:"name"` // 流程名称
19 | CategoryID uint `gorm:"column:categoryId" json:"categoryId"`
20 | Notice NoticeSlice `gorm:"column:notice;type:json" json:"notice"` // 变为json切片
21 | Comments bool `gorm:"column:comments;default:false" json:"comments"`
22 | Ratings bool `gorm:"column:ratings;default:false" json:"ratings"`
23 | Description string `gorm:"description:des;type:varchar(512)" json:"description"`
24 | Creator string `gorm:"creator:des;type:varchar(20)" json:"creator"` // 创建人
25 | Regenerator string `gorm:"regenerator:des;type:varchar(20)" json:"regenerator"` // 更新人
26 | StrucTure StrucTure `gorm:"column:structure;type:json" json:"structure"`
27 | models.ControlBy
28 | models.ModelTime
29 | }
30 |
31 | func (*FlowManage) TableName() string {
32 | return "flow_manage"
33 | }
34 |
35 | func (e *FlowManage) Generate() models.ActiveRecord {
36 | o := *e
37 | return &o
38 | }
39 |
40 | func (e *FlowManage) GetId() interface{} {
41 | return e.ID
42 | }
43 |
44 | // FormData 的 Scan 和 Value 方法
45 | func (e *StrucTure) Scan(value interface{}) error {
46 | bytes, ok := value.([]byte)
47 | if !ok {
48 | return errors.New("Scan source is not []byte")
49 | }
50 | return json.Unmarshal(bytes, &e)
51 | }
52 |
53 | func (e StrucTure) Value() (driver.Value, error) {
54 | bytes, err := json.Marshal(e)
55 | if err != nil {
56 | return nil, err
57 | }
58 | return string(bytes), nil
59 | }
60 |
61 | // FormData 的 Scan 和 Value 方法
62 | func (e *NoticeSlice) Scan(value interface{}) error {
63 | bytes, ok := value.([]byte)
64 | if !ok {
65 | return errors.New("scan source is not []byte")
66 | }
67 | return json.Unmarshal(bytes, &e)
68 | }
69 |
70 | func (e NoticeSlice) Value() (driver.Value, error) {
71 | bytes, err := json.Marshal(e)
72 | if err != nil {
73 | return nil, err
74 | }
75 | return string(bytes), nil
76 | }
77 |
--------------------------------------------------------------------------------