项目初始化

This commit is contained in:
wangjian 2023-01-06 10:09:23 +08:00
commit 71b21f8a7a
49 changed files with 3772 additions and 0 deletions

134
cmd/server.go Normal file
View File

@ -0,0 +1,134 @@
package cmd
import (
"context"
"fmt"
"github.com/spf13/cobra"
"go.uber.org/zap"
"hpds-iot-web/config"
router2 "hpds-iot-web/internal/router"
"hpds-iot-web/model"
discover "hpds-iot-web/pkg/discover/consul"
"net/http"
"os"
"os/signal"
"syscall"
)
var (
//consulConfigs chan *discover.ConsulConfig
ConfigFileFlag string = "./config/config.yaml"
ConsulAddress string = "http://localhost:8500"
NodeName string = "main-node"
Mode string = "dev"
)
func must(err error) {
if err != nil {
fmt.Fprint(os.Stderr, err)
os.Exit(1)
}
}
func NewStartCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "Start hpds_web application",
Run: func(cmd *cobra.Command, args []string) {
var (
cfg *config.WebConfig
err error
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
must(err)
configFileFlag, err := cmd.Flags().GetString("c")
if err != nil {
fmt.Println("get local config err: ", err)
return
}
ConsulAddress, err = cmd.Flags().GetString("r")
if err != nil {
fmt.Println("get remote config err: ", err)
return
}
NodeName, err = cmd.Flags().GetString("n")
if err != nil {
fmt.Println("get remote path config err: ", err)
return
}
Mode, err = cmd.Flags().GetString("m")
if err != nil {
fmt.Println("get remote path config err: ", err)
return
}
if len(configFileFlag) > 1 {
cfg, err = config.ParseConfigByFile(configFileFlag)
must(err)
err = config.UpdateRemoteConfig(cfg)
must(err)
ConfigFileFlag = configFileFlag
} else {
//获取consul注册中心的配置文件
cfg, err = config.GetRemoteConfig(ConsulAddress, fmt.Sprintf("hpds-pavement/hpds_web/%s/%s", Mode, NodeName))
must(err)
err = config.UpdateLocalConfig(cfg, ConfigFileFlag)
}
//创建注册对象
tags := make([]string, 1)
tags[0] = "web"
consulCfg, err := discover.NewConsulConfig(cfg.Consul.Host, cfg.Name, cfg.Name, cfg.Consul.Host, cfg.Consul.Port,
tags, 300, 300, 300)
must(err)
//连接数据库
model.New(cfg.Db.DriveName, cfg.Db.Conn)
//连接redis
model.NewCache(cfg.Cache)
// 退出channel
exitChannel := make(chan os.Signal)
defer close(exitChannel)
// 退出信号监听
go func(c chan os.Signal) {
consulCfg.ServiceDeregister()
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
}(exitChannel)
router := router2.InitRouter(zap.L(), model.DB)
// start http service
go func() {
fmt.Printf("Http Server start at port %d \n", cfg.Port)
//启动前执行注册
err = consulCfg.ServiceRegister()
must(err)
err = http.ListenAndServe(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port), router)
must(err)
}()
//服务退出取消注册
//err = consulCfg.ServiceDeregister()
//
//must(err)
//zap.L().Error("发生错误", zap.Error(err))
select {
case <-ctx.Done():
consulCfg.ServiceDeregister()
zap.L().With(
zap.String("web", "exit"),
).Error(ctx.Err().Error())
return
case errs := <-exitChannel:
consulCfg.ServiceDeregister()
zap.L().With(
zap.String("web", "exit"),
).Error(errs.String())
return
}
},
}
cmd.Flags().StringVar(&ConfigFileFlag, "c", "./config/config.yaml", "The configuration file path")
cmd.Flags().StringVar(&ConsulAddress, "r", "http://consul.hpds.cc", "The configuration remote consul address")
cmd.Flags().StringVar(&NodeName, "n", "main-node", "The configuration name")
cmd.Flags().StringVar(&Mode, "m", "dev", "run mode : dev | test | releases")
return cmd
}

98
config/config.go Normal file
View File

@ -0,0 +1,98 @@
package config
import (
"bytes"
"fmt"
"github.com/spf13/viper"
"os"
consulapi "github.com/hashicorp/consul/api"
_ "github.com/spf13/viper/remote"
"gopkg.in/yaml.v3"
)
type WebConfig struct {
Name string `yaml:"name,omitempty"`
Host string `yaml:"host,omitempty"`
Port int `yaml:"port,omitempty"`
Mode string `yaml:"mode,omitempty"`
Consul ConsulConfig `yaml:"consul,omitempty"`
Db DbConfig `yaml:"db"`
Cache CacheConfig `yaml:"cache"`
}
type ConsulConfig struct {
Host string `yaml:"host,omitempty"`
Port int `yaml:"port,omitempty"`
Interval int `yaml:"interval,omitempty"`
Timeout int `yaml:"timeout,omitempty"`
Deregister int `yaml:"deregister,omitempty"`
Tags []string `yaml:"tags,omitempty"`
}
type DbConfig struct {
Conn string `yaml:"conn"`
DriveName string `yaml:"drive_name"`
}
type CacheConfig struct {
Host string `yaml:"host,omitempty"`
Port int `yaml:"port,omitempty"`
Pass string `yaml:"pass,omitempty"`
DB int `yaml:"db,omitempty"`
PoolSize int `yaml:"pool_size,omitempty"`
}
func ParseConfigByFile(path string) (cfg *WebConfig, err error) {
buffer, err := os.ReadFile(path)
if err != nil {
return nil, err
}
return load(buffer)
}
func load(buf []byte) (cfg *WebConfig, err error) {
cViper := viper.New()
cViper.SetConfigType("yaml")
cfg = new(WebConfig)
cViper.ReadConfig(bytes.NewBuffer(buf))
err = cViper.Unmarshal(cfg)
if err != nil {
return nil, err
}
return
}
func UpdateLocalConfig(cfg *WebConfig, fn string) error {
data, err := yaml.Marshal(cfg)
if err != nil {
return err
}
err = os.WriteFile(fn, data, 0600)
return err
}
func UpdateRemoteConfig(cfg *WebConfig) error {
consulClient, err := consulapi.NewClient(&consulapi.Config{Address: fmt.Sprintf("%s:%d", cfg.Consul.Host, cfg.Consul.Port)})
if err != nil {
return err
}
val, err := yaml.Marshal(cfg)
if err != nil {
return err
}
p := &consulapi.KVPair{Key: fmt.Sprintf("hpds-pavement/hpds_web/%s/%s", cfg.Mode, cfg.Name), Value: val}
if _, err = consulClient.KV().Put(p, nil); err != nil {
return err
}
return nil
}
func GetRemoteConfig(remoteAddr, path string) (cfg *WebConfig, err error) {
consulClient, err := consulapi.NewClient(&consulapi.Config{Address: remoteAddr})
if err != nil {
return nil, err
}
kv, _, err := consulClient.KV().Get(path, nil)
if err != nil {
return nil, err
}
return load(kv.Value)
}

20
config/config.yaml Normal file
View File

@ -0,0 +1,20 @@
name: web
host: 0.0.0.0
port: 8088
mode: dev
consul:
host: http://consul.hpds.cc
port: 80
interval: 300
timeout: 5
deregister: 1
db:
conn: root:123456@tcp(127.0.0.1:3306)/hpds_jky?charset=utf8mb4
drive_name: mysql
cache:
host: 127.0.0.1
port: 6379
db: 0
pool_size: 10
functions:
- name: web-sf

95
go.mod Normal file
View File

@ -0,0 +1,95 @@
module hpds-iot-web
go 1.19
require (
git.hpds.cc/Component/gin_valid v0.0.0-20230104142509-f956bce255b6
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gin-contrib/zap v0.1.0
github.com/gin-gonic/gin v1.8.2
github.com/go-redis/redis v6.15.9+incompatible
github.com/go-sql-driver/mysql v1.6.0
github.com/goccy/go-json v0.9.11
github.com/hashicorp/consul/api v1.15.3
github.com/spf13/cobra v0.0.3
github.com/spf13/viper v1.14.0
go.uber.org/zap v1.24.0
gopkg.in/yaml.v3 v3.0.1
xorm.io/xorm v1.3.2
)
require (
cloud.google.com/go v0.104.0 // indirect
cloud.google.com/go/compute v1.12.1 // indirect
cloud.google.com/go/compute/metadata v0.2.1 // indirect
cloud.google.com/go/firestore v1.8.0 // indirect
github.com/armon/go-metrics v0.4.0 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.9.8 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sagikazarmark/crypt v0.8.0 // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
go.etcd.io/etcd/api/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/v2 v2.305.5 // indirect
go.etcd.io/etcd/client/v3 v3.5.5 // indirect
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/otel v1.10.0 // indirect
go.opentelemetry.io/otel/trace v1.10.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.102.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect
google.golang.org/grpc v1.50.1 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
)

45
internal/handler/index.go Normal file
View File

@ -0,0 +1,45 @@
package handler
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"hpds-iot-web/model"
"time"
"xorm.io/xorm"
)
type HandlerService struct {
Engine *xorm.Engine
Logger *zap.Logger
}
func NewHandlerService(engine *xorm.Engine, logger *zap.Logger) *HandlerService {
return &HandlerService{
Engine: engine,
Logger: logger,
}
}
func (s HandlerService) Health(c *gin.Context) (data interface{}, err error) {
return time.Now().Unix(), nil
}
func (s HandlerService) SaveLog(action, category, targetId, oldValue, newValue, operatorId, operatorAddr, operatorDevice string) {
operationLog := &model.OperationLog{
Action: action,
Category: category,
TargetId: targetId,
OldValue: oldValue,
NewValue: newValue,
Operator: operatorId,
OperateAddr: operatorAddr,
OperateDevice: operatorDevice,
}
_, err := s.Engine.Insert(operationLog)
if err != nil {
s.Logger.With(zap.Namespace("DAO"),
zap.String("method", "SaveLog"),
zap.Any("operationLog", operationLog),
).Error(err.Error())
}
}

481
internal/handler/manage.go Normal file
View File

@ -0,0 +1,481 @@
package handler
import (
"fmt"
"github.com/gin-gonic/gin"
"hpds-iot-web/internal/proto"
"hpds-iot-web/internal/service"
"hpds-iot-web/model"
e "hpds-iot-web/pkg/err"
)
func (s HandlerService) OwnerList(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.OwnerRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("OwnerList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
if req.Size < 1 {
req.Size = 20
}
if req.Size > 100 {
req.Size = 100
}
if req.Page < 1 {
req.Page = 1
}
data, err = repo.OwnerList(c, req)
go s.SaveLog("获取业主列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AddOwner(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.OwnerItemReq
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddOwner", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
req.Creator = userInfo.UserId
data, err = repo.AddOwner(c, req)
go s.SaveLog("新增业主", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EditOwner(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.OwnerItemReq
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("EditOwner", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
req.Creator = userInfo.UserId
data, err = repo.EditOwner(c, req)
go s.SaveLog("修改业主", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) DelOwner(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.OwnerItemReq
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("DelOwner", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
req.Creator = userInfo.UserId
data, err = repo.DelOwner(c, req)
go s.SaveLog("删除业主", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) ProjectList(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProjectRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("ProjectList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
if req.Size < 1 {
req.Size = 20
}
if req.Size > 100 {
req.Size = 100
}
if req.Page < 1 {
req.Page = 1
}
data, err = repo.ProjectList(c, req)
go s.SaveLog("获取项目列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AddProject(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProjectItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddProject", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
req.Creator = userInfo.UserId
data, err = repo.AddProject(c, req)
go s.SaveLog("新增项目", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EditProject(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProjectItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("EditProject", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
req.Creator = userInfo.UserId
data, err = repo.EditProject(c, req)
go s.SaveLog("修改项目", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) DelProject(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProjectItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("DelProject", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
req.Creator = userInfo.UserId
data, err = repo.DelProject(c, req)
go s.SaveLog("删除项目", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) ProductList(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("ProductList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
if req.Size < 1 {
req.Size = 20
}
if req.Size > 100 {
req.Size = 100
}
if req.Page < 1 {
req.Page = 1
}
data, err = repo.ProductList(c, req)
go s.SaveLog("产品(物模型)列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AddProduct(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddProduct", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.AddProduct(c, req)
go s.SaveLog("新增产品(物模型)", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EditProduct(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("EditProduct", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.EditProduct(c, req)
go s.SaveLog("修改产品(物模型)", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) DelProduct(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("DelProduct", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.EditProduct(c, req)
go s.SaveLog("删除产品(物模型)", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) CategoryList(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductCategoryRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("CategoryList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
if req.Size < 1 {
req.Size = 20
}
if req.Size > 1000 {
req.Size = 1000
}
if req.Page < 1 {
req.Page = 1
}
data, err = repo.CategoryList(c, req)
go s.SaveLog("产品(物模型)类型列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AddCategory(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductCategoryItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddCategory", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.AddCategory(c, req)
go s.SaveLog("新增产品(物模型)类型", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EditCategory(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductCategoryItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddCategory", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.EditCategory(c, req)
go s.SaveLog("修改产品(物模型)类型", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) DelCategory(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ProductCategoryItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("DelCategory", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.DelCategory(c, req)
go s.SaveLog("删除产品(物模型)类型", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AttributeList(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.AttributeRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("CategoryList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
if req.Size < 1 {
req.Size = 20
}
if req.Size > 1000 {
req.Size = 1000
}
if req.Page < 1 {
req.Page = 1
}
data, err = repo.AttributeList(c, req)
go s.SaveLog("产品(物模型)属性列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AddAttribute(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.AttributeItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddAttribute", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.AddAttribute(c, req)
go s.SaveLog("增加产品(物模型)属性", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EditAttribute(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.AttributeItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("EditAttribute", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.EditAttribute(c, req)
go s.SaveLog("修改产品(物模型)属性", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) DelAttribute(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.AttributeItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("DelAttribute", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.DelAttribute(c, req)
go s.SaveLog("删除产品(物模型)属性", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EventList(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.AttributeRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("EventList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
if req.Size < 1 {
req.Size = 20
}
if req.Size > 1000 {
req.Size = 1000
}
if req.Page < 1 {
req.Page = 1
}
data, err = repo.EventList(c, req)
go s.SaveLog("产品(物模型)事件列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AddEvent(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.EventItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddEvent", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.AddEvent(c, req)
go s.SaveLog("增加产品(物模型)事件", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EditEvent(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.EventItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("EditEvent", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.EditEvent(c, req)
go s.SaveLog("修改产品(物模型)事件", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) DelEvent(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.EventItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("DelEvent", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.DelEvent(c, req)
go s.SaveLog("删除产品(物模型)事件", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) ServiceList(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.AttributeRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("ServiceList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
if req.Size < 1 {
req.Size = 20
}
if req.Size > 1000 {
req.Size = 1000
}
if req.Page < 1 {
req.Page = 1
}
data, err = repo.ServiceList(c, req)
go s.SaveLog("产品(物模型)服务列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) AddService(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ServiceItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddService", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.AddService(c, req)
go s.SaveLog("增加产品(物模型)服务", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) EditService(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ServiceItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("AddService", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.EditService(c, req)
go s.SaveLog("修改产品(物模型)服务", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}
func (s HandlerService) DelService(c *gin.Context) (data interface{}, err error) {
repo := service.NewManageService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userInfo := us.(*model.SystemUser)
var req proto.ServiceItemRequest
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("DelService", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.DelService(c, req)
go s.SaveLog("删除产品(物模型)服务", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "")
return
}

29
internal/handler/user.go Normal file
View File

@ -0,0 +1,29 @@
package handler
import (
"github.com/gin-gonic/gin"
"hpds-iot-web/internal/proto"
"hpds-iot-web/internal/service"
"hpds-iot-web/model"
e "hpds-iot-web/pkg/err"
)
func (s HandlerService) Login(c *gin.Context) (data interface{}, err error) {
repo := service.NewUserService(s.Engine, s.Logger)
var req proto.UserLogin
err = c.ShouldBindJSON(&req)
if err != nil {
go s.SaveLog("UserLogin", "System", "", "", req.ToString(), "", c.Request.RemoteAddr, "")
return nil, e.NewValidErr(err)
}
data, err = repo.Login(c, req.UserName, req.UserPass)
return
}
func (s HandlerService) GetUserInfo(c *gin.Context) (data interface{}, err error) {
repo := service.NewUserService(s.Engine, s.Logger)
us, _ := c.Get("operatorUser")
userinfo := us.(*model.SystemUser)
data, err = repo.GetUserInfo(c, userinfo.UserId)
return
}

View File

@ -0,0 +1,24 @@
package middleware
import (
"net/http"
"github.com/gin-gonic/gin"
)
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
c.Header("Access-Control-Allow-Methods", "POST, GET,DELETE,PUT,OPTIONS")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
// 放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 处理请求
c.Next()
}
}

149
internal/middleware/jwt.go Normal file
View File

@ -0,0 +1,149 @@
package middleware
import (
"encoding/json"
"fmt"
"hpds-iot-web/model"
e "hpds-iot-web/pkg/err"
"net/http"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
var secretKey = []byte("17715d3df8712f0a3b31cfed384f668e95822de4e4a371e4ceaa6f1b279e482a0af32b4615d39f8857d0a1d99d2787f773147a9ed7587b243e0fe1b04076e307")
// 验签使用
var AuthKey = "auth-key"
var AuthSignature = "auth-signature"
// Claims 自定义声明
type Claims struct {
Avatar string `json:"avatar"`
Desc string `json:"desc"`
HomePath string `json:"homePath"`
RealName string `json:"realName"`
Roles []model.SystemRole `json:"roles"`
UserId int64 `json:"userId"`
Token string `json:"token,omitempty"`
Phone string `json:"phone"`
jwt.StandardClaims
}
// Sign 生成token
func Sign(user *model.SystemUser, expires int) (string, error) {
// 过期时间为秒
expAt := time.Now().Add(time.Duration(expires) * time.Second).Unix()
// 创建声明
claims := Claims{
Avatar: user.Avatar,
Desc: user.Desc,
HomePath: user.HomePath,
RealName: user.RealName,
Roles: model.GetRolesByUserId(user.UserId),
UserId: user.UserId,
Phone: user.Phone,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expAt,
Issuer: "交科院",
},
}
var err error
//创建token指定加密算法为HS256
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
claims.Token, err = token.SignedString(secretKey)
//生成token
return claims.Token, err
}
// JwtAuthMiddleware JWT处理中间件
func JwtAuthMiddleware(logger *zap.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
path := c.Request.URL.Path
var (
err error
Cookie *http.Cookie
usClaims *Claims
user *model.SystemUser
)
token := c.GetHeader("token")
// 这里可以过滤不需要进行验证的接口
if path == "/user/login" || path == "/health" {
goto Return
}
if len(token) == 0 {
Cookie, err = c.Request.Cookie("token")
if err != nil {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error(err.Error())
goto Return
}
token = Cookie.Value
}
if len(token) <= 0 {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error("缺少token")
goto Return
}
usClaims, err = GetUserInfoByToken(c, token, logger)
if err != nil {
c.JSON(e.NoAuth, gin.H{"code": e.NoAuth, "msg": "未登录的用户请求"})
c.Abort()
return
}
if err != nil {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error(err.Error())
goto Return
}
user, err = model.GetUserById(usClaims.UserId)
if err != nil {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error(err.Error())
goto Return
}
c.Set("operatorUser", user)
Return:
if err != nil {
c.Header("Content-Type", "application/json")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"status": http.StatusText(http.StatusBadRequest),
"path": path,
"message": "失败",
"error": "token过期/失效,请登录后重试",
"data": nil,
})
return
}
c.Next()
}
}
func GetUserInfoByToken(ctx *gin.Context, token string, logger *zap.Logger) (data *Claims, err error) {
nosql := NewNoSql(logger)
su, err := nosql.Get(ctx, token)
if err != nil {
return nil, err
}
data = new(Claims)
err = json.Unmarshal([]byte(fmt.Sprintf("%s", su)), data)
if err != nil {
return nil, err
}
return data, nil
}

View File

@ -0,0 +1,42 @@
package middleware
import (
"context"
"errors"
"github.com/go-redis/redis"
"hpds-iot-web/model"
"time"
"go.uber.org/zap"
)
type NoSql interface {
Save(ctx context.Context, key string, value []byte, expires time.Duration) (err error)
Get(ctx context.Context, key string) (data interface{}, err error)
}
// noSql 接口实现类
type noSql struct {
rdb *redis.Client
logger *zap.Logger
}
func NewNoSql(logger *zap.Logger) NoSql {
return &noSql{
rdb: model.Redis,
logger: logger,
}
}
func (ns *noSql) Save(ctx context.Context, key string, value []byte, expires time.Duration) (err error) {
return ns.rdb.Set(key, value, expires).Err()
}
func (ns *noSql) Get(ctx context.Context, key string) (data interface{}, err error) {
data, err = ns.rdb.Get(key).Result()
if err == redis.Nil {
return nil, errors.New("键" + key + "不存在")
} else if err != nil {
return nil, err
}
return data, nil
}

219
internal/proto/request.go Normal file
View File

@ -0,0 +1,219 @@
package proto
import "encoding/json"
type BasePageList struct {
Page int64 `json:"pageNum,omitempty" form:"page"`
Size int64 `json:"pageSize,omitempty" form:"pageSize"`
}
type UserLogin struct {
UserName string `json:"username"`
UserPass string `json:"password"`
}
func (us UserLogin) ToString() string {
data, err := json.Marshal(us)
if err != nil {
return ""
}
return string(data)
}
type OwnerRequest struct {
OwnerName string `json:"ownerName"`
BasePageList
}
func (r OwnerRequest) ToString() string {
data, err := json.Marshal(r)
if err != nil {
return ""
}
return string(data)
}
type OwnerItemReq struct {
OwnerId int64 `json:"ownerId"`
OwnerName string `json:"ownerName"`
ChargeUser string `json:"chargeUser"`
Phone string `json:"phone"`
Creator int64 `json:"creator"`
}
func (r OwnerItemReq) ToString() string {
data, err := json.Marshal(r)
if err != nil {
return ""
}
return string(data)
}
type ProjectRequest struct {
LineName string `json:"lineName"`
ProjectName string `json:"projectName"`
BasePageList
}
func (p ProjectRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type ProjectItemRequest struct {
ProjectId int `json:"projectId"`
ProjectName string `json:"projectName"`
OwnerId int `json:"ownerId"`
LineName string `json:"lineName"`
StartName string `json:"startName"`
EndName string `json:"endName"`
FixedDeviceNum int `json:"fixedDeviceNum"`
Direction string `json:"direction"`
LaneNum int `json:"laneNum"`
Lng float64 `json:"lng"`
Lat float64 `json:"lat"`
Creator int64 `json:"creator"`
}
func (p ProjectItemRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type ProductRequest struct {
CategoryId int64 `json:"categoryId"`
ProductName string `json:"productName"`
Protocol int64 `json:"protocol"`
BasePageList
}
func (p ProductRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type ProductItemRequest struct {
MatterId int64 `json:"matterId"`
MatterName string `json:"matterName"`
CategoryId int64 `json:"categoryId"`
Protocol int `json:"protocol"`
UserVersion int64 `json:"userVersion"`
Status int `json:"status"`
}
func (p ProductItemRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type ProductCategoryRequest struct {
CategoryName string `json:"categoryName"`
BasePageList
}
func (p ProductCategoryRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type ProductCategoryItemRequest struct {
CategoryId int64 `json:"categoryId"`
CategoryName string `json:"categoryName"`
CategoryDesc string `json:"categoryDesc"`
Status int `json:"status"`
}
func (p ProductCategoryItemRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type AttributeRequest struct {
MatterId int64 `json:"matterId"`
VersionId int64 `json:"versionId"`
BasePageList
}
func (p AttributeRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type AttributeItemRequest struct {
AttributeId int64 `json:"attributeId"`
MatterId int64 `json:"matterId"`
VersionId int64 `json:"versionId"`
AttributeName string `json:"attributeName"`
AttributeKey string `json:"attributeKey"`
AttributeDesc string `json:"attributeDesc"`
DataType int `json:"dataType"`
MaxValue string `json:"maxValue"`
MinValue string `json:"minValue"`
StepValue string `json:"stepValue"`
Unit string `json:"unit"`
IsOnlyRead int `json:"isOnlyRead"`
}
func (p AttributeItemRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type EventItemRequest struct {
EventId int64 `json:"eventId"`
MatterId int64 `json:"matterId"`
VersionId int64 `json:"versionId"`
EventIdentifier string `json:"eventIdentifier"`
EventType string `json:"eventType"`
EventDesc string `json:"eventDesc"`
}
func (p EventItemRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}
type ServiceItemRequest struct {
ServiceId int64 `json:"serviceId"`
MatterId int64 `json:"matterId"`
VersionId int64 `json:"versionId"`
ServiceName string `json:"serviceName"`
ServiceIdentifier string `json:"serviceIdentifier"`
Calling int `json:"calling"`
ServiceDesc string `json:"serviceDesc"`
}
func (p ServiceItemRequest) ToString() string {
data, err := json.Marshal(p)
if err != nil {
return ""
}
return string(data)
}

View File

@ -0,0 +1,38 @@
package proto
// BaseResponse 基础返回结构
type BaseResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"result,omitempty"`
Status string `json:"type,omitempty"`
Err error `json:"error,omitempty"` // 错误堆栈
Page int64 `json:"page,omitempty"` //当前页码
PageSize int64 `json:"pageSize,omitempty"` // 单页显示记录数--前端参数2
PageCount int64 `json:"totalPage,omitempty"` // 总页数
TotalSize int64 `json:"totalRow,omitempty"` // 总记录数
}
type UserLoginResponse struct {
UserId int64 `json:"userId"`
Token string `json:"token"`
RealName string `json:"realName"`
UserName string `json:"userName"`
Roles []RoleItem `json:"roles"`
Avatar string `json:"avatar"`
Desc string `json:"desc"`
HomePath string `json:"homePath"`
}
type RoleItem struct {
RoleId int64 `json:"roleId"`
RoleName string `json:"roleName"`
Value string `json:"value"`
}
type OwnerItem struct {
OwnerId int `json:"ownerId"`
OwnerName string `json:"ownerName"`
ChargeUser string `json:"chargeUser"`
Phone string `json:"phone"`
}

89
internal/router/router.go Normal file
View File

@ -0,0 +1,89 @@
package router
import (
ginzap "github.com/gin-contrib/zap"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"hpds-iot-web/internal/handler"
"hpds-iot-web/internal/middleware"
"xorm.io/xorm"
e "hpds-iot-web/pkg/err"
)
func InitRouter(logger *zap.Logger, engine *xorm.Engine) *gin.Engine {
hs := handler.NewHandlerService(engine, logger)
gin.SetMode(gin.ReleaseMode)
r := gin.New()
r.Use(ginzap.Ginzap(logger, "2006-01-02 15:04:05.000", true))
r.Use(middleware.Cors())
user := r.Group("/user")
{
user.Use(middleware.JwtAuthMiddleware(logger))
user.POST("/login", e.ErrorWrapper(hs.Login))
user.GET("/getUserInfo", e.ErrorWrapper(hs.GetUserInfo))
}
manage := r.Group("/manage")
{
owner := manage.Group("/owner")
{
owner.Use(middleware.JwtAuthMiddleware(logger))
owner.POST("/list", e.ErrorWrapper(hs.OwnerList))
owner.POST("/add", e.ErrorWrapper(hs.AddOwner))
owner.POST("/edit", e.ErrorWrapper(hs.EditOwner))
owner.POST("/delete", e.ErrorWrapper(hs.DelOwner))
}
project := manage.Group("/project")
{
project.Use(middleware.JwtAuthMiddleware(logger))
project.POST("/list", e.ErrorWrapper(hs.ProjectList))
project.POST("/add", e.ErrorWrapper(hs.AddProject))
project.POST("/edit", e.ErrorWrapper(hs.EditProject))
project.POST("/delete", e.ErrorWrapper(hs.DelProject))
}
product := manage.Group("/product")
{
product.Use(middleware.JwtAuthMiddleware(logger))
product.POST("/list", e.ErrorWrapper(hs.ProductList))
product.POST("/add", e.ErrorWrapper(hs.AddProduct))
product.POST("/edit", e.ErrorWrapper(hs.EditProduct))
product.POST("/delete", e.ErrorWrapper(hs.DelProduct))
category := product.Group("/category")
{
category.Use(middleware.JwtAuthMiddleware(logger))
category.POST("/list", e.ErrorWrapper(hs.CategoryList))
category.POST("/add", e.ErrorWrapper(hs.AddCategory))
category.POST("/edit", e.ErrorWrapper(hs.EditCategory))
category.POST("/delete", e.ErrorWrapper(hs.DelCategory))
}
attribute := product.Group("/attribute")
{
attribute.Use(middleware.JwtAuthMiddleware(logger))
attribute.POST("/list", e.ErrorWrapper(hs.AttributeList))
attribute.POST("/add", e.ErrorWrapper(hs.AddAttribute))
attribute.POST("/edit", e.ErrorWrapper(hs.EditAttribute))
attribute.POST("/delete", e.ErrorWrapper(hs.DelAttribute))
}
event := product.Group("/event")
{
event.Use(middleware.JwtAuthMiddleware(logger))
event.POST("/list", e.ErrorWrapper(hs.EventList))
event.POST("/add", e.ErrorWrapper(hs.AddEvent))
event.POST("/edit", e.ErrorWrapper(hs.EditEvent))
event.POST("/delete", e.ErrorWrapper(hs.DelEvent))
}
service := product.Group("/service")
{
service.Use(middleware.JwtAuthMiddleware(logger))
service.POST("/list", e.ErrorWrapper(hs.ServiceList))
service.POST("/add", e.ErrorWrapper(hs.AddService))
service.POST("/edit", e.ErrorWrapper(hs.EditService))
service.POST("/delete", e.ErrorWrapper(hs.DelService))
}
}
}
return r
}

183
internal/service/index.go Normal file
View File

@ -0,0 +1,183 @@
package service
import (
"context"
"encoding/json"
"fmt"
"go.uber.org/zap"
"hpds-iot-web/internal/middleware"
"hpds-iot-web/internal/proto"
"hpds-iot-web/model"
"hpds-iot-web/pkg/utils"
"net/http"
"time"
"xorm.io/xorm"
)
// FillPaging 填充分页数据
func FillPaging(count int64, pageNum int64, pageSize int64, list interface{}, data *proto.BaseResponse) *proto.BaseResponse {
var tp int64
if count%pageSize > 0 {
tp = count/pageSize + 1
} else {
tp = count / pageSize
}
data.PageSize = pageSize
data.Data = list
data.Page = pageNum
data.PageCount = tp
data.TotalSize = count
return data
}
type repo struct {
engine *xorm.Engine
logger *zap.Logger
}
type UserService interface {
Login(ctx context.Context, userName, pass string) (rsp *proto.BaseResponse, err error)
GetUserInfo(ctx context.Context, userId int64) (rsp *proto.BaseResponse, err error)
}
func NewUserService(engine *xorm.Engine, logger *zap.Logger) UserService {
return &repo{
engine: engine,
logger: logger,
}
}
func (rp *repo) Login(ctx context.Context, userName, pass string) (rsp *proto.BaseResponse, err error) {
rsp = new(proto.BaseResponse)
select {
case <-ctx.Done():
err = fmt.Errorf("超时/取消")
rsp.Code = http.StatusInternalServerError
rsp.Status = http.StatusText(http.StatusInternalServerError)
rsp.Message = "超时/取消"
rsp.Err = ctx.Err()
return rsp, ctx.Err()
default:
//获取用户
us := new(model.SystemUser)
h, err := rp.engine.Where("phone=?", userName).Get(us)
if err != nil {
goto ReturnPoint
}
if !h {
err = fmt.Errorf("未能找到对应的用户")
goto ReturnPoint
}
vPass := utils.GetUserSha1Pass(pass, us.Salt)
if vPass != us.Pass {
err = fmt.Errorf("用户名或者密码不正确")
goto ReturnPoint
}
data := new(proto.UserLoginResponse)
data.UserName = us.Phone
data.RealName = us.RealName
data.UserId = us.UserId
data.Avatar = us.Avatar
data.Desc = us.Desc
data.HomePath = us.HomePath
//生成JWT token
data.Token, err = middleware.Sign(us, 86400)
if err != nil {
goto ReturnPoint
}
body, _ := json.Marshal(us)
err = model.Redis.Set(data.Token, string(body), time.Duration(24)*time.Hour).Err()
if err != nil {
goto ReturnPoint
}
roleList := model.GetRolesByUserId(us.UserId)
data.Roles = make([]proto.RoleItem, len(roleList))
for k, v := range roleList {
data.Roles[k] = proto.RoleItem{
RoleId: v.RoleId,
RoleName: v.RoleName,
Value: v.RoleValue,
}
}
rsp.Code = http.StatusOK
rsp.Status = http.StatusText(http.StatusOK)
rsp.Message = "成功"
rsp.Data = data
rsp.Err = err
return rsp, err
}
ReturnPoint:
if err != nil {
rsp.Code = http.StatusInternalServerError
rsp.Status = http.StatusText(http.StatusInternalServerError)
rsp.Err = err
rsp.Message = "失败"
}
return rsp, err
}
func (rp *repo) GetUserInfo(ctx context.Context, userId int64) (rsp *proto.BaseResponse, err error) {
rsp = new(proto.BaseResponse)
select {
case <-ctx.Done():
err = fmt.Errorf("超时/取消")
rsp.Code = http.StatusInternalServerError
rsp.Status = http.StatusText(http.StatusInternalServerError)
rsp.Message = "超时/取消"
rsp.Err = ctx.Err()
return rsp, ctx.Err()
default:
//获取用户
us := new(model.SystemUser)
h, err := rp.engine.ID(userId).Get(us)
if err != nil {
goto ReturnPoint
}
if !h {
err = fmt.Errorf("未能找到对应的用户")
goto ReturnPoint
}
data := new(proto.UserLoginResponse)
data.UserName = us.Phone
data.RealName = us.RealName
data.UserId = us.UserId
data.Avatar = us.Avatar
data.Desc = us.Desc
data.HomePath = us.HomePath
//生成JWT token
data.Token, err = middleware.Sign(us, 86400)
if err != nil {
goto ReturnPoint
}
body, _ := json.Marshal(us)
err = model.Redis.Set(data.Token, string(body), time.Duration(24)*time.Hour).Err()
if err != nil {
goto ReturnPoint
}
roleList := model.GetRolesByUserId(us.UserId)
data.Roles = make([]proto.RoleItem, len(roleList))
for k, v := range roleList {
data.Roles[k] = proto.RoleItem{
RoleId: v.RoleId,
RoleName: v.RoleName,
Value: v.RoleValue,
}
}
rsp.Code = http.StatusOK
rsp.Status = http.StatusText(http.StatusOK)
rsp.Message = "成功"
rsp.Data = data
rsp.Err = err
return rsp, err
}
ReturnPoint:
if err != nil {
rsp.Code = http.StatusInternalServerError
rsp.Status = http.StatusText(http.StatusInternalServerError)
rsp.Err = err
rsp.Message = "失败"
}
return rsp, err
}

1310
internal/service/manage.go Normal file

File diff suppressed because it is too large Load Diff

27
main.go Normal file
View File

@ -0,0 +1,27 @@
package main
import (
"fmt"
"github.com/spf13/cobra"
"hpds-iot-web/cmd"
"os"
)
var (
rootCmd = &cobra.Command{
Use: "hpds_web",
Long: "hpds_web is a IoT WEB UI",
Version: "0.1",
}
)
func init() {
rootCmd.AddCommand(cmd.NewStartCmd())
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprint(os.Stderr, err.Error())
os.Exit(1)
}
}

11
model/brand.go Normal file
View File

@ -0,0 +1,11 @@
package model
type Brand struct {
BrandId int64 `xorm:"not null pk autoincr INT(11)" json:"brandId"`
BrandName string `xorm:"varchar(200) not null" json:"brandName"`
BrandLogo string `xorm:"varchar(200) " json:"brandLogo"`
BrandWeb string `xorm:"varchar(200) " json:"brandWeb"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
DeleteAt int64 `xorm:"deleted" json:"deleteAt"`
}

12
model/detectionTask.go Normal file
View File

@ -0,0 +1,12 @@
package model
type DetectionTask struct {
TaskId int64 `json:"taskId" xorm:"not null pk autoincr INT(11)"`
TaskCode string `json:"taskCode" xorm:"varchar(64) not null "`
TaskName string `json:"taskName" xorm:"varchar(200) not null "`
ParentTaskId int64 `json:"parentTaskId" xorm:"INT(11) default 0 not null"` //上级任务编号默认为0
TaskStatus int `json:"taskStatus" xorm:"INT(11) default 0 not null"` //任务状态
InitiatorUserId int64 `json:"initiatorUserId" xorm:"INT(11) default 0 not null"` //任务发起人
InitiatorTime int64 `json:"initiatorTime" xorm:"created"` //任务发起时间
CompletionTime int64 `json:"completionTime" xorm:"DATETIME"` //任务完成时间
}

19
model/device.go Normal file
View File

@ -0,0 +1,19 @@
package model
type Device struct {
DeviceId int64 `xorm:"not null pk autoincr INT(11)" json:"deviceId"`
DeviceName string `xorm:"varchar(64) not null" json:"deviceName"`
DeviceBrandId int `xorm:"INT(11) default 0 not null" json:"deviceBrandId"`
DeviceImei string `xorm:"varchar(64) not null" json:"deviceImei"` //设备imei
DeviceSn string `xorm:"varchar(64) not null" json:"deviceSn"` //设备序列号
DeviceTypeId int `xorm:"INT(11) default 0 not null" json:"deviceTypeId"` //设备类型
ButtMatterId int64 `xorm:"INT(11) default 0 not null" json:"buttMatterId"` //对接物模型编号
ButtType int `xorm:"INT(11) default 0 not null" json:"buttType"` //对接类型1直连服务;2:平台对接
ButtAddress string `xorm:"varchar(200) not null" json:"buttAddress"` //对接地址
ButtPort int `xorm:"INT(11) default 0 not null" json:"buttPort"` //对接端口
Longitude float64 `xorm:"decimal(18,6)" json:"longitude"` //经度
Latitude float64 `xorm:"decimal(18,6)" json:"latitude"` //纬度
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
DeleteAt int64 `xorm:"deleted" json:"deleteAt"`
}

11
model/deviceType.go Normal file
View File

@ -0,0 +1,11 @@
package model
type DeviceType struct {
TypeId int64 `xorm:"not null pk autoincr INT(11)" json:"typeId"`
TypeName string `xorm:"varchar(200) not null" json:"typeName"`
TypeDesc string `xorm:"TEXT" json:"typeDesc"`
BizType string `xorm:"varchar(200) not null" json:"bizType"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
DeleteAt int64 `xorm:"deleted" json:"deleteAt"`
}

14
model/disease.go Normal file
View File

@ -0,0 +1,14 @@
package model
// Disease 病害库
type Disease struct {
DiseaseId int64 `xorm:"not null pk autoincr INT(11)" json:"diseaseId"`
DiseaseName string `xorm:"varchar(200) not null " json:"diseaseName"`
DiseaseType int `xorm:"not null SMALLINT default 0" json:"diseaseType"`
DiseaseLevel string `xorm:"varchar(20) not null" json:"diseaseLevel"`
DetectionMethod string `xorm:"varchar(200) not null " json:"detectionMethod"`
DiseaseDesc string `xorm:"TEXT" json:"diseaseDesc"`
Reference string `xorm:"varchar(200) not null " json:"reference"` //参照标准
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

82
model/index.go Normal file
View File

@ -0,0 +1,82 @@
package model
import (
"fmt"
"github.com/go-redis/redis"
_ "github.com/go-sql-driver/mysql"
"go.uber.org/zap"
"hpds-iot-web/config"
"os"
"time"
"xorm.io/xorm"
"xorm.io/xorm/dialects"
)
var (
DB *xorm.Engine
Redis *redis.Client
)
func New(driveName, dsn string) {
DB, _ = NewDbConnection(dsn)
DB.ShowSQL(true)
DB.Dialect().SetQuotePolicy(dialects.QuotePolicyReserved)
err := DB.Sync2(
&Brand{},
&DetectionTask{},
&Device{},
&DeviceType{},
&Disease{},
&MatterAttribute{},
&MatterCategory{},
&MatterEvent{},
&MatterEventParams{},
&MatterModel{},
&MatterService{},
&MatterServiceParams{},
&MatterVersion{},
&Node{},
&OriginalData{},
&Owner{},
&Project{},
&SystemMenu{},
&OperationLog{},
&SystemRoleMenu{},
&SystemRoleRoute{},
&SystemRole{},
&SystemUser{},
)
if err != nil {
zap.L().Error("同步数据库表结构", zap.Error(err))
os.Exit(1)
}
}
func NewDbConnection(dsn string) (db *xorm.Engine, err error) {
db, err = xorm.NewEngine("mysql", dsn)
if err != nil {
zap.L().Error("创建数据库连接", zap.Error(err))
os.Exit(-1)
}
db.SetMaxOpenConns(300)
return
}
func NewCache(c config.CacheConfig) {
Redis = redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", c.Host, c.Port),
Password: c.Pass, // no password set
DB: c.DB, // use default DB
PoolSize: c.PoolSize, // Redis连接池大小
MaxRetries: 3, // 最大重试次数
IdleTimeout: 10 * time.Second, // 空闲链接超时时间
})
pong, err := Redis.Ping().Result()
if err == redis.Nil {
zap.L().Error("访问Redis异常", zap.Error(fmt.Errorf("redis.Nil")))
} else if err != nil {
zap.L().Error("访问Redis异常", zap.Error(err))
} else {
zap.L().Info("Redis连接成功", zap.String("pong", pong))
}
}

20
model/matterAttribute.go Normal file
View File

@ -0,0 +1,20 @@
package model
// MatterAttribute 物模型属性
type MatterAttribute struct {
AttributeId int64 `xorm:"not null pk autoincr INT(11)" json:"attributeId"`
MatterId int64 `xorm:"not null INT(11) index" json:"matterId"`
VersionId int64 `xorm:"not null INT(11) default 0" json:"versionId"`
AttributeName string `xorm:"varchar(200) not null" json:"attributeName"`
AttributeKey string `xorm:"varchar(200) not null" json:"attributeKey"`
AttributeDesc string `xorm:"varchar(200) not null" json:"attributeDesc"`
DataType int `xorm:"not null INT(11) default 0" json:"dataType"`
MaxValue string `xorm:"varchar(200) " json:"maxValue"`
MinValue string `xorm:"varchar(200)" json:"minValue"`
StepValue string `xorm:"varchar(200) " json:"stepValue"`
Unit string `xorm:"varchar(200) " json:"unit"`
IsOnlyRead int `xorm:"not null SMALLINT default 0" json:"isOnlyRead"`
Status int `xorm:"not null SMALLINT default 0" json:"status"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

10
model/matterCategory.go Normal file
View File

@ -0,0 +1,10 @@
package model
type MatterCategory struct {
CategoryId int64 `xorm:"not null pk autoincr INT(11)" json:"categoryId"` //
CategoryName string `xorm:"VARCHAR(40) not null" json:"categoryName"` //
CategoryDesc string `xorm:"VARCHAR(200)" json:"categoryDesc"` //
Status int `xorm:"SMALLINT not null default 0" json:"status"` //
CreateAt int64 `xorm:"created" json:"createAt"` //
UpdateAt int64 `xorm:"updated" json:"updateAt"` //
}

13
model/matterEvent.go Normal file
View File

@ -0,0 +1,13 @@
package model
type MatterEvent struct {
EventId int64 `xorm:"not null pk autoincr INT(11)" json:"eventId"`
MatterId int64 `xorm:"not null INT(11) index" json:"matterId"`
VersionId int64 `xorm:"not null INT(11)" json:"versionId"`
EventIdentifier string `xorm:"varchar(64) not null" json:"eventIdentifier"` //事件标识
EventType string `xorm:"varchar(200) not null" json:"eventType"` //事件类型
EventDesc string `xorm:"varchar(200) not null" json:"eventDesc"` //事件描述
Status int `xorm:"not null SMALLINT default 0" json:"status"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

View File

@ -0,0 +1,17 @@
package model
type MatterEventParams struct {
ParamsId int64 `xorm:"not null pk autoincr INT(11)" json:"paramsId"`
MatterId int64 `xorm:"not null INT(11) default 0" json:"matterId"`
VersionId int64 `xorm:"not null INT(11) default 0" json:"versionId"`
EventId int64 `xorm:"not null INT(11) default 0" json:"eventId"`
ParamName string `xorm:"varchar(200) not null" json:"paramName"` //参数名称
ParamIdentifier string `xorm:"varchar(64) not null" json:"paramIdentifier"` //参数标识符
DataType int `xorm:"not null INT(11) default 0" json:"dataType"` //数据类型
MaxValue string `xorm:"varchar(200) " json:"maxValue"`
MinValue string `xorm:"varchar(200)" json:"minValue"`
StepValue string `xorm:"varchar(200) " json:"stepValue"`
Unit string `xorm:"varchar(200) " json:"unit"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

13
model/matterModel.go Normal file
View File

@ -0,0 +1,13 @@
package model
// MatterModel 物模型
type MatterModel struct {
MatterId int64 `xorm:"not null pk autoincr INT(11)" json:"matterId"`
MatterName string `xorm:"varchar(200) not null" json:"matterName"`
CategoryId int64 `xorm:"not null INT(11) default 0 index" json:"categoryId"`
Protocol int `xorm:"not null INT(11) default 0" json:"protocol"`
UserVersion int64 `xorm:"not null INT(11) default 0" json:"userVersion"`
Status int `xorm:"not null INT(11) default 0" json:"status"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

14
model/matterService.go Normal file
View File

@ -0,0 +1,14 @@
package model
type MatterService struct {
ServiceId int64 `xorm:"not null pk autoincr INT(11)" json:"serviceId"`
MatterId int64 `xorm:"not null INT(11) index" json:"matterId"`
VersionId int64 `xorm:"not null INT(11) default 0" json:"versionId"`
ServiceName string `xorm:"varchar(200) not null" json:"serviceName"`
ServiceIdentifier string `xorm:"varchar(64) not null" json:"serviceIdentifier"`
Calling int `xorm:"not null SMALLINT default 0" json:"calling"` //调用方式, 同步、异步
ServiceDesc string `xorm:"varchar(200) not null" json:"serviceDesc"` //服务描述
Status int `xorm:"not null SMALLINT default 0" json:"status"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

View File

@ -0,0 +1,18 @@
package model
type MatterServiceParams struct {
ParamsId int64 `xorm:"not null pk autoincr INT(11)" json:"paramsId"`
MatterId int64 `xorm:"not null INT(11) default 0" json:"matterId"`
VersionId int64 `xorm:"not null INT(11) default 0" json:"versionId"`
ServiceId int64 `xorm:"not null INT(11) default 0" json:"serviceId"`
ParamsOwnerType int `xorm:"not null SMALLINT default 0" json:"paramsOwnerType"` //参数的所属类型1:服务入参; 2:服务出参
ParamName string `xorm:"varchar(200) not null" json:"paramName"` //参数名称
ParamIdentifier string `xorm:"varchar(64) not null" json:"paramIdentifier"` //参数标识符
DataType int `xorm:"not null INT(11) default 0" json:"dataType"` //数据类型
MaxValue string `xorm:"varchar(200) " json:"maxValue"`
MinValue string `xorm:"varchar(200)" json:"minValue"`
StepValue string `xorm:"varchar(200) " json:"stepValue"`
Unit string `xorm:"varchar(200) " json:"unit"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

11
model/matterVersion.go Normal file
View File

@ -0,0 +1,11 @@
package model
type MatterVersion struct {
VersionId int64 `xorm:"not null pk autoincr INT(11)" json:"versionId"`
MatterId int64 `xorm:"not null INT(11) default 0" json:"matterId"`
Version string `xorm:"varchar(50) not null" json:"version"`
VersionDesc string `xorm:"varchar(200) not null" json:"versionDesc"`
Status int `xorm:"not null SMALLINT default 0" json:"status"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

10
model/model.go Normal file
View File

@ -0,0 +1,10 @@
package model
type Model struct {
ModelId int `xorm:"not null pk autoincr INT(11)" json:"modelId"`
ModelName string `xorm:"varchar(200) not null" json:"modelName"`
ModelVersion string `xorm:"varchar(50) not null" json:"modelVersion"`
ModelDesc string `xorm:"varchar(200) not null" json:"modelDesc"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

12
model/modelVersion.go Normal file
View File

@ -0,0 +1,12 @@
package model
type ModelVersion struct {
ModelId int `xorm:"not null pk autoincr INT(11)" json:"modelId"`
VersionId int `xorm:"not null INT(11) default 0" json:"versionId"`
Version string `xorm:"varchar(50) not null" json:"version"`
ModelDesc string `xorm:"varchar(200) not null" json:"modelDesc"`
UpdateDesc string `xorm:"varchar(200) not null" json:"updateDesc"`
Status int `xorm:"not null SMALLINT default 0" json:"status"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

10
model/node.go Normal file
View File

@ -0,0 +1,10 @@
package model
type Node struct {
NodeId int `xorm:"not null pk autoincr INT(11)" json:"nodeId"`
NodeName string `xorm:"varchar(50) not null" json:"nodeName"`
NodeType int `xorm:"not null SMALLINT default 0" json:"nodeType"`
NodeStatus int `xorm:"not null SMALLINT default 0" json:"nodeStatus"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

12
model/originalData.go Normal file
View File

@ -0,0 +1,12 @@
package model
// OriginalData 原始数据表
type OriginalData struct {
Id int64 `xorm:"not null pk autoincr INT(11)" json:"id"`
EquipmentIp string `xorm:"varchar(50)" json:"equipmentIp"` //来源地址
ReceiptTime int64 `xorm:"varchar(50)" json:"receiptTime"` //接收时间
ReceiptNodeId int64 `xorm:"varchar(50)" json:"receiptNodeId"` //接收节点
ReceiptProtocol int64 `xorm:"varchar(50)" json:"receiptProtocol"` //接收协议
OriginalContent string `xorm:"TEXT" json:"originalContent"` //原始内容
CreateAt int64 `xorm:"created" json:"createAt"` //入库时间
}

13
model/owner.go Normal file
View File

@ -0,0 +1,13 @@
package model
type Owner struct {
OwnerId int `xorm:"not null pk autoincr INT(11)" json:"ownerId"`
OwnerName string `xorm:"varchar(200) not null " json:"ownerName"`
ChargeUser string `xorm:"varchar(200) not null " json:"chargeUser"`
Phone string `xorm:"varchar(100) not null " json:"phone"`
Creator int64 `xorm:"INT(11) default 0" json:"creator"`
Modifier int64 `xorm:"INT(11) default 0" json:"modifier"`
Status int `xorm:"SMALLINT default 1" json:"status"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

20
model/project.go Normal file
View File

@ -0,0 +1,20 @@
package model
type Project struct {
ProjectId int `xorm:"not null pk autoincr INT(11)" json:"projectId"`
ProjectName string `xorm:"varchar(200) not null " json:"projectName"`
OwnerId int `xorm:"not null INT(11) default 0" json:"ownerId"`
LineName string `xorm:"varchar(200) not null " json:"lineName"`
StartName string `xorm:"varchar(200) not null " json:"startName"`
EndName string `xorm:"varchar(200) not null " json:"endName"`
FixedDeviceNum int `xorm:"not null INT(11) default 0" json:"fixedDeviceNum"`
Direction string `xorm:"varchar(200) not null " json:"direction"`
LaneNum int `xorm:"not null INT(4) default 0" json:"laneNum"`
Lng float64 `xorm:"decimal(18,6)" json:"lng"`
Lat float64 `xorm:"decimal(18,6)" json:"lat"`
Status int `xorm:"SMALLINT default 1" json:"status"`
Creator int64 `xorm:"INT(11) default 0" json:"creator"`
Modifier int64 `xorm:"INT(11) default 0" json:"modifier"`
CreateAt int64 `xorm:"created" json:"createAt"`
UpdateAt int64 `xorm:"updated" json:"updateAt"`
}

24
model/systemMenus.go Normal file
View File

@ -0,0 +1,24 @@
package model
// SystemMenu 系统菜单
type SystemMenu struct {
MenuId int64 `xorm:"not null pk autoincr INT(11)" json:"menuId"` //路由ID
MenuName string `xorm:"varchar(64) " json:"menuName"` //路由名
MenuPath string `xorm:"varchar(200) " json:"menuPath"` //路由路径
Component string `xorm:"varchar(64) " json:"component"` //组件名
Redirect string `xorm:"varchar(200) not null default ''" json:"redirect"` //重定向地址
MenuUrl string `xorm:"varchar(200) not null default ''" json:"menuUrl"` //路由地址
MetaTitle string `xorm:"varchar(128) " json:"metaTitle"` //标题
MetaIcon string `xorm:"varchar(200) " json:"metaIcon"` //图标
AlwaysShow int `xorm:"not null INT default 1" json:"alwaysShow"` //状态 0禁用 1启用
MetaAffix int `xorm:"not null INT default 0" json:"metaAffix"` //meta属性 0禁用 1启用
Type int `xorm:"not null INT default 1" json:"type"` //状态 0禁用 1启用
Hidden int `xorm:"not null INT default 0" json:"hidden"` //是否隐藏 0不隐藏 1隐藏
Pid int64 `xorm:"not null INT(11) default 0" json:"pid"` //父节点ID
Sort int `xorm:"not null INT default 0" json:"sort"` //排序
Level int `xorm:"not null INT(4) default 0" json:"level"` //等级
Status int `xorm:"not null SMALLINT default 1" json:"status"` //状态 0禁用 1启用
MetaBreadcrumb int `xorm:"not null INT default 0" json:"metaBreadcrumb"` //隐藏面包屑 0:不隐藏 1:隐藏
CreateAt int64 `xorm:"created" json:"createAt"` //创建时间
UpdateAt int64 `xorm:"updated" json:"updateAt"` //更新时间
}

View File

@ -0,0 +1,15 @@
package model
// OperationLog 操作行为日志表
type OperationLog struct {
Id string `xorm:"not null pk autoincr INT(11)" json:"id"` // 主键
Action string `xorm:"VARCHAR(40) DEFAULT '' NOT NULL" json:"action"` // 操作动作(新增,修改,删除)
Category string `xorm:"VARCHAR(40) DEFAULT '' NOT NULL" json:"category"` // 操作类型(用户/部门/角色/项目……)
TargetId string `xorm:"VARCHAR(40) DEFAULT '' NOT NULL" json:"targetId"` // 操作目标,用户/部门/角色/项目……
OldValue string `xorm:"TEXT NOT NULL" json:"oldValue"` // 操作前旧值
NewValue string `xorm:"TEXT NOT NULL" json:"newValue"` // 操作后新值
Operator string `xorm:"VARCHAR(40) DEFAULT 'SYSDBA' NOT NULL" json:"operator"` // 操作者,默认为系统数据库管理员
OperateAddr string `xorm:"VARCHAR(100) DEFAULT '' NOT NULL" json:"operateIP"` // 操作者IP+端口信息
OperateDevice string `xorm:"VARCHAR(160) DEFAULT '' NOT NULL" json:"operateDevice"` // 操作设备类型
OperateTime int64 `xorm:"created" json:"operateTime"` // 操作时间
}

11
model/systemRoleMenus.go Normal file
View File

@ -0,0 +1,11 @@
package model
// SystemRoleMenu 角色菜单关联表
type SystemRoleMenu struct {
RoleMenuId int64 `xorm:"not null pk autoincr INT(11)" json:"roleMenuId"` //角色菜单ID
RoleId int64 `xorm:"INT(11) default 1" json:"roleId"` //角色ID
MenuId int64 `xorm:"INT(11) default 1" json:"menuId"` //菜单ID
Status int `xorm:"INT default 1" json:"status"` //状态 0禁用 1启用
CreateAt int64 `xorm:"created" json:"createAt"` //创建时间
UpdateAt int64 `xorm:"updated" json:"updateAt"` //更新时间
}

10
model/systemRoleRoutes.go Normal file
View File

@ -0,0 +1,10 @@
package model
// SystemRoleRoute 系统角色路由表
type SystemRoleRoute struct {
RoleId int64 `xorm:"INT(11) default 1 pk" json:"roleId"` //角色ID
RouteId int64 `xorm:"INT(11) default 1 pk" json:"routeId"` //路由ID
Status int `xorm:"INT default 1" json:"status"` //状态 0禁用 1启用
CreateAt int64 `xorm:"created" json:"createAt"` //创建时间
UpdateAt int64 `xorm:"updated" json:"updateAt"` //更新时间
}

13
model/systemRoles.go Normal file
View File

@ -0,0 +1,13 @@
package model
// SystemRole 系统角色表
type SystemRole struct {
RoleId int64 `xorm:"not null pk autoincr INT(11)" json:"roleId"` //角色ID
RoleName string `xorm:"VARCHAR(32)" json:"roleName"` //角色名
RoleValue string `xorm:"VARCHAR(32)" json:"roleValue"` //角色值
AliasName string `xorm:"VARCHAR(32)" json:"aliasName"` //简称
Description string `xorm:"VARCHAR(32)" json:"description"` //说明
Status int `xorm:"int not null default 1" json:"status"` //状态 0禁用 1启用
CreateAt int64 `xorm:"created" json:"createAt"` //创建时间
UpdateAt int64 `xorm:"updated" json:"updateAt"` //更新时间
}

28
model/systemUser.go Normal file
View File

@ -0,0 +1,28 @@
package model
import "fmt"
type SystemUser struct {
UserId int64 `xorm:"not null pk autoincr INT(11)" json:"userId"` //用户编号
Phone string `xorm:"VARCHAR(16)" json:"phone"` //手机号码
Avatar string `xorm:"VARCHAR(200)" json:"avatar"` //头像
Desc string `xorm:"VARCHAR(200)" json:"desc"` //用户描述
HomePath string `xorm:"VARCHAR(200)" json:"homePath"` //进入的首页
Pass string `xorm:"VARCHAR(128) not null" json:"pass"` //密码
Salt string `xorm:"VARCHAR(32) not null" json:"salt"` //盐
RealName string `xorm:"VARCHAR(50)" json:"realName"` //真实姓名
CreateAt int64 `xorm:"created" json:"createAt"` //创建时间
UpdateAt int64 `xorm:"updated" json:"updateAt"` //更新时间
}
func GetUserById(userId int64) (*SystemUser, error) {
us := new(SystemUser)
h, err := DB.ID(userId).Get(us)
if err != nil {
return nil, err
}
if !h {
return nil, fmt.Errorf("未知用户")
}
return us, err
}

33
model/systemUserRoles.go Normal file
View File

@ -0,0 +1,33 @@
package model
type SystemUserRole struct {
UserRoleId int64 `xorm:"not null pk autoincr INT(11)" json:"userRoleId"` //用户编号
UserId int64 `xorm:"INT(11)" json:"userId"` //用户ID
RoleId int64 `xorm:"INT(11)" json:"roleId"` //角色ID
Status int `xorm:"SMALLINT default 0" json:"status"` //状态 0禁用 1启用
CreateAt int64 `xorm:"created" json:"createAt"` //创建时间
UpdateAt int64 `xorm:"updated" json:"updateAt"` //更新时间
}
func GetRolesByUserId(userId int64) []SystemRole {
us := new(SystemUser)
h, err := DB.ID(userId).Get(us)
if err != nil || !h {
return nil
}
roleList := make([]SystemUserRole, 0)
err = DB.Where("user_id = ? and status = 1", us.UserId).Find(&roleList)
if err != nil {
return nil
}
roleIdList := make([]int64, len(roleList))
for k, v := range roleList {
roleIdList[k] = v.RoleId
}
list := make([]SystemRole, 0)
err = DB.In("role_id", roleIdList).Find(&list)
if err != nil {
return nil
}
return list
}

View File

@ -0,0 +1,87 @@
package discover
import (
"fmt"
"github.com/hashicorp/consul/api"
)
type ConsulConfig struct {
Client *api.Client `json:"client"` // consul client
ConsulAddress string `json:"consulAddress"` // consul 服务地址:IP+port
ServiceId string `json:"serviceId"` // 服务ID
ServiceName string `json:"serviceName"` // 服务名称
ServiceIP string `json:"serviceIP"` // 服务IP
ServicePort int `json:"servicePort"` // 服务端口
Tags []string `json:"tags"` // 服务标签列表
DeregisterCriticalServiceAfter int `json:"deregisterCriticalServiceAfter"` // 指定与服务关联的检查应在此时间之后注销
Interval int `json:"interval"` // 指定运行此检查的频率
Timeout int `json:"timeout"` // 在脚本、HTTP、TCP 或 gRPC 检查的情况下指定传出连接的超时时间
}
func NewConsulConfig(consulAddress string,
serviceId string,
serviceName string,
serviceIP string,
servicePort int,
tags []string,
deregisterCriticalServiceAfter int,
interval int,
timeout int) (*ConsulConfig, error) {
// 1.consul配置
config := api.DefaultConfig()
config.Address = consulAddress
// 2.client
client, err := api.NewClient(config)
if err != nil {
return nil, err
}
return &ConsulConfig{
Client: client,
ConsulAddress: consulAddress,
ServiceId: serviceId,
ServiceName: serviceName,
ServiceIP: serviceIP,
ServicePort: servicePort,
Tags: tags,
DeregisterCriticalServiceAfter: deregisterCriticalServiceAfter,
Interval: interval,
Timeout: timeout,
}, nil
}
// ServiceRegister 服务注册
func (cf *ConsulConfig) ServiceRegister() (err error) {
// 注册器
reg := &api.AgentServiceRegistration{
ID: cf.ServiceId,
Name: cf.ServiceName,
Address: cf.ServiceIP,
Port: cf.ServicePort,
Tags: cf.Tags,
Check: &api.AgentServiceCheck{
Interval: fmt.Sprintf("%vs", cf.Interval), // 健康检查间隔
HTTP: fmt.Sprintf("http://%v:%v/health", cf.ServiceIP, cf.ServicePort), // HTTP 支持执行健康检查的地址service 会传到 Health.Check 函数中
Timeout: fmt.Sprintf("%vs", cf.Timeout), // 健康检查超时时间
DeregisterCriticalServiceAfter: fmt.Sprintf("%vs", cf.DeregisterCriticalServiceAfter), // 注销时间,相当于过期时间
Notes: "Consul check service health status.",
},
}
// 注册服务
err = cf.Client.Agent().ServiceRegister(reg)
if err != nil {
return err
}
return nil
}
// ServiceDeregister 服务注销
func (cf *ConsulConfig) ServiceDeregister() error {
return cf.Client.Agent().ServiceDeregister(cf.ServiceId)
}
// ServiceDiscover 服务发现
func (cf *ConsulConfig) ServiceDiscover(service string, tags []string, q *api.QueryOptions) ([]*api.CatalogService, *api.QueryMeta, error) {
return cf.Client.Catalog().ServiceMultipleTags(service, tags, q)
}

83
pkg/err/err_code.go Normal file
View File

@ -0,0 +1,83 @@
package e
import "github.com/goccy/go-json"
const (
UnKnow = 1
ValidErr = 1000
DbErr = 2020
IllegalPhone = 2001
NoAuth = 401
NoUser = 2003
ExistingUserName = 2004
UnmarshalReqErr = 3000
Ordinary = 6666
)
func init() {
m := map[int]string{
UnKnow: "未定义错误",
ValidErr: "无效的请求参数",
DbErr: "数据库错误",
IllegalPhone: "请输入正确的手机号码",
NoAuth: "未授权",
NoUser: "未找到对应用户",
ExistingUserName: "已经存在的用户",
UnmarshalReqErr: "参数类型错误",
}
errMap[UnKnow] = &ApiError{
Status: 500,
Code: UnKnow,
Message: "未定义错误",
}
for k, v := range m {
errMap[k] = &ApiError{
Status: 200,
Code: k,
Message: v,
}
}
}
var errMap = map[int]*ApiError{}
func NewCode(code int) *ApiError {
if e, ok := errMap[code]; ok {
return e
}
return errMap[UnKnow]
}
func NewString(msg string) *ApiError {
return &ApiError{
Status: 200,
Code: Ordinary,
Message: msg,
}
}
func newErr(err *ApiError) *ApiError {
return &(*err)
}
func NewValidErr(err error) error {
if _, ok := err.(*json.UnmarshalTypeError); ok {
return newErr(errMap[UnmarshalReqErr])
}
return err
}
func (e *ApiError) Set(msg string) *ApiError {
r := *e
r.Message = msg
return &r
}
type ApiError struct {
Status int `json:"-"`
Code int `json:"code"`
Message string `json:"msg"`
}
func (e *ApiError) Error() string {
return e.Message
}

58
pkg/err/err_encode.go Normal file
View File

@ -0,0 +1,58 @@
package e
import (
"git.hpds.cc/Component/gin_valid/gin/binding"
validator "git.hpds.cc/Component/gin_valid/go-playground/validator/v10"
"github.com/gin-gonic/gin"
"net/http"
)
type WrapperHandle func(c *gin.Context) (interface{}, error)
func ErrorWrapper(handle WrapperHandle) gin.HandlerFunc {
return func(c *gin.Context) {
data, err := handle(c)
if err != nil {
switch r := err.(type) {
case *ApiError:
c.JSON(r.Status, r)
case validator.ValidationErrors:
msg := r.Translate(binding.ValidTrans).Error()
c.JSON(http.StatusOK, gin.H{"code": "", "msg": msg})
default:
er := NewValidErr(err)
c.JSON(http.StatusOK, gin.H{"code": 500, "msg": er.Error()})
}
return
}
if data != nil {
c.JSON(http.StatusOK, data)
} else {
c.JSON(http.StatusOK, gin.H{"code": 200, "data": data})
}
}
}
func ErrorWeChatWrapper(handle WrapperHandle) gin.HandlerFunc {
return func(c *gin.Context) {
data, err := handle(c)
if err != nil {
switch r := err.(type) {
case *ApiError:
c.JSON(r.Status, r)
case validator.ValidationErrors:
msg := r.Translate(binding.ValidTrans).Error()
c.JSON(http.StatusOK, gin.H{"code": "", "msg": msg})
default:
er := NewValidErr(err)
c.JSON(http.StatusOK, gin.H{"code": 500, "msg": er.Error()})
}
return
}
if data != nil {
c.JSON(http.StatusOK, gin.H{"code": "SUCCESS", "data": data})
} else {
c.JSON(http.StatusOK, gin.H{"code": "SUCCESS", "message": "成功"})
}
}
}

40
pkg/utils/utils.go Normal file
View File

@ -0,0 +1,40 @@
package utils
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"math/rand"
"time"
)
/*
RandomString 产生随机数
- size 随机码的位数
- kind 0 // 纯数字
1 // 小写字母
2 // 大写字母
3 // 数字、大小写字母
*/
func RandomString(size int, kind int) string {
iKind, kinds, rsBytes := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
isAll := kind > 2 || kind < 0
rand.Seed(time.Now().UnixNano())
for i := 0; i < size; i++ {
if isAll { // random iKind
iKind = rand.Intn(3)
}
scope, base := kinds[iKind][0], kinds[iKind][1]
rsBytes[i] = uint8(base + rand.Intn(scope))
}
return string(rsBytes)
}
func GetUserSha1Pass(pass, salt string) string {
key := []byte(salt)
mac := hmac.New(sha1.New, key)
mac.Write([]byte(pass))
//进行base64编码
res := base64.StdEncoding.EncodeToString(mac.Sum(nil))
return res
}

34
test/manage.http Normal file
View File

@ -0,0 +1,34 @@
### 业主列表
POST http://localhost:8088/manage/owner/list
Content-Type: application/json
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdmF0YXIiOiIiLCJkZXNjIjoiIiwiaG9tZVBhdGgiOiIiLCJyZWFsTmFtZSI6IueOi-WJkSIsInJvbGVzIjpudWxsLCJ1c2VySWQiOjEsInBob25lIjoiMTg5MDY1MTc3ODgiLCJleHAiOjE2NzI5NzczODQsImlzcyI6IuS6pOenkemZoiJ9.8Zzp7efRlapptYYpvbc3hpHrKaAov0AJ7gYD8w9BZ2c
{"page": 1,"pageSize": 20}
### 新增业主
POST http://localhost:8088/manage/owner/add
Content-Type: application/json
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdmF0YXIiOiIiLCJkZXNjIjoiIiwiaG9tZVBhdGgiOiIiLCJyZWFsTmFtZSI6IueOi-WJkSIsInJvbGVzIjpudWxsLCJ1c2VySWQiOjEsInBob25lIjoiMTg5MDY1MTc3ODgiLCJleHAiOjE2NzI5NzczODQsImlzcyI6IuS6pOenkemZoiJ9.8Zzp7efRlapptYYpvbc3hpHrKaAov0AJ7gYD8w9BZ2c
{"ownerName": "浙大网新科技",
"chargeUser": "王剑",
"phone": "18906517788"}
### 修改业主
POST http://localhost:8088/manage/owner/edit
Content-Type: application/json
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdmF0YXIiOiIiLCJkZXNjIjoiIiwiaG9tZVBhdGgiOiIiLCJyZWFsTmFtZSI6IueOi-WJkSIsInJvbGVzIjpudWxsLCJ1c2VySWQiOjEsInBob25lIjoiMTg5MDY1MTc3ODgiLCJleHAiOjE2NzI5NzczODQsImlzcyI6IuS6pOenkemZoiJ9.8Zzp7efRlapptYYpvbc3hpHrKaAov0AJ7gYD8w9BZ2c
{"ownerId": 1,
"ownerName": "浙大网新科技有限公司",
"chargeUser": "王剑",
"phone": "13033603311"}
### 删除业主
POST http://localhost:8088/manage/owner/delete
Content-Type: application/json
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdmF0YXIiOiIiLCJkZXNjIjoiIiwiaG9tZVBhdGgiOiIiLCJyZWFsTmFtZSI6IueOi-WJkSIsInJvbGVzIjpudWxsLCJ1c2VySWQiOjEsInBob25lIjoiMTg5MDY1MTc3ODgiLCJleHAiOjE2NzI5NzczODQsImlzcyI6IuS6pOenkemZoiJ9.8Zzp7efRlapptYYpvbc3hpHrKaAov0AJ7gYD8w9BZ2c
{"ownerId": 1}

11
test/user.http Normal file
View File

@ -0,0 +1,11 @@
### 登录
POST http://localhost:8088/user/login
Content-Type: application/json
{"username": "18906517788", "password": "123456"}
### 获取用户信息
GET http://localhost:8088/user/getUserInfo
Content-Type: application/json
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdmF0YXIiOiIiLCJkZXNjIjoiIiwiaG9tZVBhdGgiOiIiLCJyZWFsTmFtZSI6IueOi-WJkSIsInJvbGVzIjpudWxsLCJ1c2VySWQiOjEsInBob25lIjoiMTg5MDY1MTc3ODgiLCJleHAiOjE2NzI5NzczODQsImlzcyI6IuS6pOenkemZoiJ9.8Zzp7efRlapptYYpvbc3hpHrKaAov0AJ7gYD8w9BZ2c