diff --git a/cmd/server.go b/cmd/server.go index 2aa121f..2e9e6fc 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -99,7 +99,7 @@ func NewStartCmd() *cobra.Command { consulCfg.ServiceDeregister() signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) }(exitChannel) - router := router2.InitRouter(logger, model.DB) + router := router2.InitRouter(cfg, logger, model.DB) // start http service go func() { fmt.Printf("Http Server start at port %d \n", cfg.Port) diff --git a/config/config-dev.yaml b/config/config-dev.yaml index f494430..def5d1f 100644 --- a/config/config-dev.yaml +++ b/config/config-dev.yaml @@ -13,6 +13,12 @@ logging: maxBackups: 3000 maxAge: 30 development: true +mineData: + accessKey: f0bda738033e47ffbfbd5d3f865c19e1 +minio: + endpoint: 192.168.0.200:9000 + accessKeyId: root + secretAccessKey: OIxv7QptYBO3 consul: host: http://consul.hpds.cc port: 80 diff --git a/config/config.go b/config/config.go index 38a243b..9a3e4ff 100644 --- a/config/config.go +++ b/config/config.go @@ -12,14 +12,16 @@ import ( ) 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"` - Logging LogOptions `yaml:"logging"` + 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"` + Logging LogOptions `yaml:"logging"` + Minio MinioConfig `yaml:"minio"` + MineData MineDataConfig `yaml:"mineData"` } type ConsulConfig struct { Host string `yaml:"host,omitempty"` @@ -55,6 +57,17 @@ type LogOptions struct { Development bool `yaml:"development" json:"development" toml:"development"` // 是否是开发模式 } +type MinioConfig struct { + Endpoint string `yaml:"endpoint"` + AccessKeyId string `yaml:"accessKeyId"` + SecretAccessKey string `yaml:"secretAccessKey"` + Bucket string `yaml:"bucket"` +} + +type MineDataConfig struct { + AccessKey string `yaml:"accessKey"` +} + func ParseConfigByFile(path string) (cfg *WebConfig, err error) { buffer, err := os.ReadFile(path) if err != nil { diff --git a/config/config.yaml b/config/config.yaml index daf4ddf..3b62f04 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -13,6 +13,12 @@ logging: maxBackups: 3000 maxAge: 30 development: true +mineData: + accessKey: f0bda738033e47ffbfbd5d3f865c19e1 +minio: + endpoint: 127.0.0.1:9000 + accessKeyId: root + secretAccessKey: OIxv7QptYBO3 consul: host: http://consul.hpds.cc port: 80 diff --git a/go.mod b/go.mod index de512e4..352d0ac 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( 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/minio/minio-go/v7 v7.0.46 github.com/spf13/cobra v0.0.3 github.com/spf13/viper v1.14.0 go.uber.org/zap v1.24.0 @@ -27,6 +28,7 @@ require ( 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/dustin/go-humanize v1.0.0 // 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 @@ -38,6 +40,7 @@ require ( 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/google/uuid v1.3.0 // 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 @@ -49,10 +52,14 @@ require ( 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/klauspost/compress v1.15.9 // indirect + github.com/klauspost/cpuid/v2 v2.1.0 // 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/minio/md5-simd v1.1.2 // indirect + github.com/minio/sha256-simd v1.0.0 // 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 @@ -60,7 +67,9 @@ require ( 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/rs/xid v1.4.0 // indirect github.com/sagikazarmark/crypt v0.8.0 // indirect + github.com/sirupsen/logrus v1.9.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 @@ -77,7 +86,7 @@ require ( 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/crypto v0.0.0-20220722155217-630584e8d5aa // 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 diff --git a/internal/handler/file.go b/internal/handler/file.go new file mode 100644 index 0000000..1d4b3b6 --- /dev/null +++ b/internal/handler/file.go @@ -0,0 +1,35 @@ +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) UploadFile(c *gin.Context) (data interface{}, err error) { + repo := service.NewFileService(s.AppConfig, s.Engine, s.Logger) + us, _ := c.Get("operatorUser") + userInfo := us.(*model.SystemUser) + var req proto.UploadFileRequest + form, err := c.MultipartForm() + if err != nil { + go s.SaveLog("UploadFile", "Manage", "", "", userInfo.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + files := form.File["file"] + scene := c.GetString("scene") + if len(scene) < 1 { + scene = "other" + } + req = proto.UploadFileRequest{ + Creator: userInfo.UserId, + Scene: scene, + Files: files, + } + data, err = repo.UploadFile(c, req) + go s.SaveLog("文件上传", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} diff --git a/internal/handler/index.go b/internal/handler/index.go index c909727..e346039 100644 --- a/internal/handler/index.go +++ b/internal/handler/index.go @@ -4,20 +4,23 @@ import ( "git.hpds.cc/Component/logging" "github.com/gin-gonic/gin" "go.uber.org/zap" + "hpds-iot-web/config" "hpds-iot-web/model" "time" "xorm.io/xorm" ) type HandlerService struct { - Engine *xorm.Engine - Logger *logging.Logger + AppConfig *config.WebConfig + Engine *xorm.Engine + Logger *logging.Logger } -func NewHandlerService(engine *xorm.Engine, logger *logging.Logger) *HandlerService { +func NewHandlerService(cfg *config.WebConfig, engine *xorm.Engine, logger *logging.Logger) *HandlerService { return &HandlerService{ - Engine: engine, - Logger: logger, + AppConfig: cfg, + Engine: engine, + Logger: logger, } } diff --git a/internal/handler/manage.go b/internal/handler/manage.go index 3e723ed..c62fbdb 100644 --- a/internal/handler/manage.go +++ b/internal/handler/manage.go @@ -646,3 +646,74 @@ func (s HandlerService) DelServiceParams(c *gin.Context) (data interface{}, err go s.SaveLog("删除产品(物模型)服务参数", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") return } + +func (s HandlerService) DeviceList(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.DeviceRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("DeviceList", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.DeviceList(c, req) + go s.SaveLog("查看设备列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} +func (s HandlerService) DeviceInfo(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.DeviceItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("DeviceInfo", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.DeviceInfo(c, req) + go s.SaveLog("查看设备列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} +func (s HandlerService) AddDevice(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.DeviceItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("AddDevice", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.AddDevice(c, req) + go s.SaveLog("新增设备", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} +func (s HandlerService) EditDevice(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.DeviceItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("AddDevice", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.EditDevice(c, req) + go s.SaveLog("修改设备", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} +func (s HandlerService) DeleteDevice(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.DeviceItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("AddDevice", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.DeleteDevice(c, req) + go s.SaveLog("删除设备", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} diff --git a/internal/handler/system.go b/internal/handler/system.go new file mode 100644 index 0000000..b50e902 --- /dev/null +++ b/internal/handler/system.go @@ -0,0 +1,94 @@ +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) BrandList(c *gin.Context) (data interface{}, err error) { + repo := service.NewSystemService(s.Engine, s.Logger) + us, _ := c.Get("operatorUser") + userInfo := us.(*model.SystemUser) + var req proto.BrandRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("BrandList", "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.BrandList(c, req) + go s.SaveLog("获取品牌列表", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} + +func (s HandlerService) BrandInfo(c *gin.Context) (data interface{}, err error) { + repo := service.NewSystemService(s.Engine, s.Logger) + us, _ := c.Get("operatorUser") + userInfo := us.(*model.SystemUser) + var req proto.BrandItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("BrandInfo", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.BrandInfo(c, req) + go s.SaveLog("获取品牌信息", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} + +func (s HandlerService) AddBrand(c *gin.Context) (data interface{}, err error) { + repo := service.NewSystemService(s.Engine, s.Logger) + us, _ := c.Get("operatorUser") + userInfo := us.(*model.SystemUser) + var req proto.BrandItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("AddBrand", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.AddBrand(c, req) + go s.SaveLog("新增品牌", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} + +func (s HandlerService) EditBrand(c *gin.Context) (data interface{}, err error) { + repo := service.NewSystemService(s.Engine, s.Logger) + us, _ := c.Get("operatorUser") + userInfo := us.(*model.SystemUser) + var req proto.BrandItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("EditBrand", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.EditBrand(c, req) + go s.SaveLog("修改品牌", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} + +func (s HandlerService) DeleteBrand(c *gin.Context) (data interface{}, err error) { + repo := service.NewSystemService(s.Engine, s.Logger) + us, _ := c.Get("operatorUser") + userInfo := us.(*model.SystemUser) + var req proto.BrandItemRequest + err = c.ShouldBindJSON(&req) + if err != nil { + go s.SaveLog("DeleteBrand", "Manage", "", "", req.ToString(), fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return nil, e.NewValidErr(err) + } + data, err = repo.DeleteBrand(c, req) + go s.SaveLog("删除品牌", "Manage", "", "", "", fmt.Sprintf("%d", userInfo.UserId), c.Request.RemoteAddr, "") + return +} diff --git a/internal/proto/request.go b/internal/proto/request.go index de99c41..6c8f0f1 100644 --- a/internal/proto/request.go +++ b/internal/proto/request.go @@ -1,6 +1,9 @@ package proto -import "encoding/json" +import ( + "encoding/json" + "mime/multipart" +) type BasePageList struct { Page int64 `json:"pageNum,omitempty" form:"page"` @@ -329,3 +332,76 @@ func (p ModelItemRequest) ToString() string { } return string(data) } + +type DeviceRequest struct { + Key string `json:"key"` + ProductId int64 `json:"productId"` + DeviceTypeId int `json:"deviceTypeId"` + BasePageList +} + +func (p DeviceRequest) ToString() string { + data, err := json.Marshal(p) + if err != nil { + return "" + } + return string(data) +} + +type DeviceItemRequest struct { + DeviceId int64 `json:"deviceId"` + DeviceName string `json:"deviceName"` + DeviceBrandId int `json:"deviceBrandId"` + DeviceImei string `json:"deviceImei"` + DeviceSn string `json:"deviceSn"` + DeviceTypeId int `json:"deviceTypeId"` + ButtMatterId int64 `json:"buttMatterId"` + ButtType int `json:"buttType"` + ButtAddress string `json:"buttAddress"` + ButtPort int `json:"buttPort"` + Longitude float64 `json:"longitude"` + Latitude float64 `json:"latitude"` + DeviceDesc string `json:"deviceDesc"` +} + +func (p DeviceItemRequest) ToString() string { + data, err := json.Marshal(p) + if err != nil { + return "" + } + return string(data) +} + +type UploadFileRequest struct { + Creator int64 `json:"creator"` + Scene string `json:"scene"` + Files []*multipart.FileHeader `json:"files"` +} + +type BrandRequest struct { + BrandName string `json:"brandName"` + BasePageList +} + +func (p BrandRequest) ToString() string { + data, err := json.Marshal(p) + if err != nil { + return "" + } + return string(data) +} + +type BrandItemRequest struct { + BrandId int64 `json:"brandId"` + BrandName string `json:"brandName"` + BrandLogo string `json:"brandLogo"` + BrandWeb string `json:"brandWeb"` +} + +func (p BrandItemRequest) ToString() string { + data, err := json.Marshal(p) + if err != nil { + return "" + } + return string(data) +} diff --git a/internal/router/router.go b/internal/router/router.go index 30b0775..a2825df 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -4,6 +4,7 @@ import ( "git.hpds.cc/Component/logging" ginzap "github.com/gin-contrib/zap" "github.com/gin-gonic/gin" + "hpds-iot-web/config" "hpds-iot-web/internal/handler" "hpds-iot-web/internal/middleware" "xorm.io/xorm" @@ -11,8 +12,8 @@ import ( e "hpds-iot-web/pkg/err" ) -func InitRouter(logger *logging.Logger, engine *xorm.Engine) *gin.Engine { - hs := handler.NewHandlerService(engine, logger) +func InitRouter(cfg *config.WebConfig, logger *logging.Logger, engine *xorm.Engine) *gin.Engine { + hs := handler.NewHandlerService(cfg, engine, logger) gin.SetMode(gin.ReleaseMode) root := gin.New() root.Use(ginzap.Ginzap(logger.Logger, "2006-01-02 15:04:05.000", true)) @@ -103,6 +104,14 @@ func InitRouter(logger *logging.Logger, engine *xorm.Engine) *gin.Engine { params.POST("/delete", e.ErrorWrapper(hs.DelServiceParams)) } } + device := product.Group("/device") + { + device.POST("/list", e.ErrorWrapper(hs.DeviceList)) + device.POST("/info", e.ErrorWrapper(hs.DeviceInfo)) + device.POST("/add", e.ErrorWrapper(hs.AddDevice)) + device.POST("/edit", e.ErrorWrapper(hs.EditDevice)) + device.POST("/delete", e.ErrorWrapper(hs.DeleteDevice)) + } } } model := r.Group("/model") @@ -113,6 +122,23 @@ func InitRouter(logger *logging.Logger, engine *xorm.Engine) *gin.Engine { model.POST("/edit", e.ErrorWrapper(hs.EditModel)) model.POST("/delete", e.ErrorWrapper(hs.DelModel)) } + file := r.Group("/file") + { + file.Use(middleware.JwtAuthMiddleware(logger.Logger)) + file.POST("/upload", e.ErrorWrapper(hs.UploadFile)) + } + system := r.Group("/system") + { + system.Use(middleware.JwtAuthMiddleware(logger.Logger)) + brand := system.Group("/brand") + { + brand.POST("/list", e.ErrorWrapper(hs.BrandList)) + brand.POST("/info", e.ErrorWrapper(hs.BrandInfo)) + brand.POST("/add", e.ErrorWrapper(hs.AddBrand)) + brand.POST("/edit", e.ErrorWrapper(hs.EditBrand)) + brand.POST("/delete", e.ErrorWrapper(hs.DeleteBrand)) + } + } } return root } diff --git a/internal/service/fileManage.go b/internal/service/fileManage.go new file mode 100644 index 0000000..5aea69a --- /dev/null +++ b/internal/service/fileManage.go @@ -0,0 +1,128 @@ +package service + +import ( + "context" + "crypto/md5" + "encoding/hex" + "fmt" + "git.hpds.cc/Component/logging" + "github.com/minio/minio-go/v7/pkg/credentials" + "hpds-iot-web/config" + "hpds-iot-web/internal/proto" + "hpds-iot-web/model" + "io" + "mime/multipart" + "net/http" + "time" + "xorm.io/xorm" + + "github.com/minio/minio-go/v7" +) + +type FileService interface { + UploadFile(ctx context.Context, req proto.UploadFileRequest) (rsp *proto.BaseResponse, err error) +} + +func NewFileService(cfg *config.WebConfig, engine *xorm.Engine, logger *logging.Logger) FileService { + return &repo{ + AppConfig: cfg, + engine: engine, + logger: logger, + } +} + +func (rp *repo) UploadFile(ctx context.Context, req proto.UploadFileRequest) (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: + list := make([]*model.FileManager, len(req.Files)) + for k, _ := range req.Files { + fileItem, err := rp.UploadFileToMinIo(ctx, req.Files[k], req.Scene, req.Creator) + if err != nil { + goto ReturnPoint + } + list[k] = fileItem + } + _, err = rp.engine.Insert(list) + + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "成功" + rsp.Data = list + 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) UploadFileToMinIo(ctx context.Context, srcFile *multipart.FileHeader, scene string, creator int64) (data *model.FileManager, err error) { + file, err := srcFile.Open() + defer file.Close() + if err != nil { + return nil, err + } + + fileName := srcFile.Filename + + //out, err := os.Create(fileName) + //defer out.Close() + //if err != nil { + // return nil, err + //} + // + //_, err = io.Copy(out, file) + //if err != nil { + // return nil, err + //} + // + //fileStat, err := out.Stat() + //if err != nil { + // return nil, err + //} + opt := &minio.Options{ + Creds: credentials.NewStaticV4(rp.AppConfig.Minio.AccessKeyId, rp.AppConfig.Minio.SecretAccessKey, ""), + Secure: false, + } + minioClient, err := minio.New(rp.AppConfig.Minio.Endpoint, opt) + if err != nil { + return nil, err + } + //bucketName := fmt.Sprintf("jky-data/%s/%s", scene, time.Now().Format("20060102")) + objPath := fmt.Sprintf("%s/%s/%s", scene, time.Now().Format("20060102"), fileName) + info, err := minioClient.PutObject(ctx, "jky-data", objPath, file, srcFile.Size, minio.PutObjectOptions{ContentType: "application/octet-stream"}) + if err != nil { + return nil, err + } + fmt.Println("info =====> ", info) + accessUrl := fmt.Sprintf("%s/jky-data/%s", rp.AppConfig.Minio.Endpoint, objPath) + + md5hash := md5.New() + if _, err := io.Copy(md5hash, file); err != nil { + return nil, err + } + + data = new(model.FileManager) + data.FileName = fileName + data.Scene = scene + data.AccessUrl = accessUrl + data.FileSize = srcFile.Size + data.Creator = creator + data.FileMd5 = hex.EncodeToString(md5hash.Sum(nil)) + data.CreateAt = time.Now().Unix() + data.UpdateAt = time.Now().Unix() + return data, nil +} diff --git a/internal/service/index.go b/internal/service/index.go index ef4dd52..f9d92d8 100644 --- a/internal/service/index.go +++ b/internal/service/index.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "git.hpds.cc/Component/logging" + "hpds-iot-web/config" "hpds-iot-web/internal/middleware" "hpds-iot-web/internal/proto" "hpds-iot-web/model" @@ -40,8 +41,9 @@ func FillPaging(count int64, pageNum int64, pageSize int64, list interface{}, da } type repo struct { - engine *xorm.Engine - logger *logging.Logger + AppConfig *config.WebConfig + engine *xorm.Engine + logger *logging.Logger } type UserService interface { diff --git a/internal/service/manage.go b/internal/service/manage.go index 0c88274..becf64c 100644 --- a/internal/service/manage.go +++ b/internal/service/manage.go @@ -57,6 +57,12 @@ type ManageService interface { AddServiceParams(ctx context.Context, req proto.ServiceParamItem) (rsp *proto.BaseResponse, err error) EditServiceParams(ctx context.Context, req proto.ServiceParamItem) (rsp *proto.BaseResponse, err error) DelServiceParams(ctx context.Context, req proto.ServiceParamItem) (rsp *proto.BaseResponse, err error) + + DeviceList(ctx context.Context, req proto.DeviceRequest) (rsp *proto.BaseResponse, err error) + DeviceInfo(ctx context.Context, req proto.DeviceItemRequest) (rsp *proto.BaseResponse, err error) + AddDevice(ctx context.Context, req proto.DeviceItemRequest) (rsp *proto.BaseResponse, err error) + EditDevice(ctx context.Context, req proto.DeviceItemRequest) (rsp *proto.BaseResponse, err error) + DeleteDevice(ctx context.Context, req proto.DeviceItemRequest) (rsp *proto.BaseResponse, err error) } func NewManageService(engine *xorm.Engine, logger *logging.Logger) ManageService { @@ -1806,3 +1812,245 @@ ReturnPoint: } return rsp, err } + +func (rp *repo) DeviceList(ctx context.Context, req proto.DeviceRequest) (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: + data := make([]model.Device, 0) + count, err := rp.engine.Where("(? = '' or device_name like ? or device_imei like ? or device_sn like ?)", + req.Key, "%"+req.Key+"%", "%"+req.Key+"%", "%"+req.Key+"%"). + And("(? = 0 or device_type_id = ?)", req.DeviceTypeId, req.DeviceTypeId). + And("(? = 0 or butt_matter_id = ?)", req.ProductId, req.ProductId). + And("status = 1"). + Limit(int(req.Size), int(((req.Page)-1)*req.Size)). + FindAndCount(&data) + if err != nil { + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "成功" + rsp = FillPaging(count, req.Page, req.Size, data, rsp) + 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) DeviceInfo(ctx context.Context, req proto.DeviceItemRequest) (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: + var h bool + item := new(model.Device) + h, err = rp.engine.ID(req.DeviceId).Get(item) + if err != nil { + goto ReturnPoint + } + if !h { + err = fmt.Errorf("未能找到对应的设备") + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "成功" + rsp.Data = item + 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) AddDevice(ctx context.Context, req proto.DeviceItemRequest) (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: + item := &model.Device{ + DeviceName: req.DeviceName, + DeviceBrandId: req.DeviceBrandId, + DeviceImei: req.DeviceImei, + DeviceSn: req.DeviceSn, + DeviceTypeId: req.DeviceTypeId, + ButtMatterId: req.ButtMatterId, + ButtType: req.ButtType, + ButtAddress: req.ButtAddress, + ButtPort: req.ButtPort, + Longitude: req.Longitude, + Latitude: req.Latitude, + DeviceDesc: req.DeviceDesc, + Status: 1, + CreateAt: time.Now().Unix(), + UpdateAt: time.Now().Unix(), + } + _, err = rp.engine.Insert(item) + if err != nil { + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "成功" + 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) EditDevice(ctx context.Context, req proto.DeviceItemRequest) (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: + var h bool + item := new(model.Device) + h, err = rp.engine.ID(req.DeviceId).Get(item) + if err != nil { + goto ReturnPoint + } + if !h { + err = fmt.Errorf("未能找到对应的设备") + goto ReturnPoint + } + if len(req.DeviceName) > 0 { + item.DeviceName = req.DeviceName + } + if req.DeviceBrandId > 0 { + item.DeviceBrandId = req.DeviceBrandId + } + if len(req.DeviceImei) > 0 { + item.DeviceImei = req.DeviceImei + } + if len(req.DeviceSn) > 0 { + item.DeviceSn = req.DeviceSn + } + if len(req.DeviceDesc) > 0 { + item.DeviceDesc = req.DeviceDesc + } + if req.DeviceTypeId > 0 { + item.DeviceTypeId = req.DeviceTypeId + } + if req.ButtMatterId > 0 { + item.ButtMatterId = req.ButtMatterId + } + if req.ButtType > 0 { + item.ButtType = req.ButtType + } + if len(req.ButtAddress) > 0 { + item.ButtAddress = req.ButtAddress + } + if req.ButtPort > 0 { + item.ButtPort = req.ButtPort + } + if req.Longitude > 0 { + item.Longitude = req.Longitude + } + if req.Latitude > 0 { + item.Latitude = req.Latitude + } + item.UpdateAt = time.Now().Unix() + _, err = rp.engine.ID(req.DeviceId).AllCols().Update(item) + if err != nil { + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "成功" + 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) DeleteDevice(ctx context.Context, req proto.DeviceItemRequest) (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: + var h bool + item := new(model.Device) + h, err = rp.engine.ID(req.DeviceId).Get(item) + if err != nil { + goto ReturnPoint + } + if !h { + err = fmt.Errorf("未能找到对应的设备") + goto ReturnPoint + } + item.Status = 0 + item.UpdateAt = time.Now().Unix() + _, err = rp.engine.ID(req.DeviceId).AllCols().Update(item) + if err != nil { + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "成功" + 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 +} diff --git a/internal/service/system.go b/internal/service/system.go new file mode 100644 index 0000000..319c9fd --- /dev/null +++ b/internal/service/system.go @@ -0,0 +1,233 @@ +package service + +import ( + "context" + "fmt" + "git.hpds.cc/Component/logging" + "hpds-iot-web/internal/proto" + "hpds-iot-web/model" + "net/http" + "time" + "xorm.io/xorm" +) + +type SystemService interface { + BrandList(ctx context.Context, req proto.BrandRequest) (rsp *proto.BaseResponse, err error) + BrandInfo(ctx context.Context, req proto.BrandItemRequest) (rsp *proto.BaseResponse, err error) + AddBrand(ctx context.Context, req proto.BrandItemRequest) (rsp *proto.BaseResponse, err error) + EditBrand(ctx context.Context, req proto.BrandItemRequest) (rsp *proto.BaseResponse, err error) + DeleteBrand(ctx context.Context, req proto.BrandItemRequest) (rsp *proto.BaseResponse, err error) +} + +func NewSystemService(engine *xorm.Engine, logger *logging.Logger) SystemService { + return &repo{ + engine: engine, + logger: logger, + } +} + +func (rp *repo) BrandList(ctx context.Context, req proto.BrandRequest) (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: + data := make([]model.Brand, 0) + count, err := rp.engine.Where("(? = '' or brand_name like ?)", req.BrandName, "%"+req.BrandName+"%"). + And("status = 1").Limit(int(req.Size), int(((req.Page)-1)*req.Size)). + FindAndCount(&data) + if err != nil { + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "成功" + rsp = FillPaging(count, req.Page, req.Size, data, rsp) + 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) BrandInfo(ctx context.Context, req proto.BrandItemRequest) (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: + var h bool + item := new(model.Brand) + h, err = rp.engine.ID(req.BrandId).Get(item) + if err != nil { + goto ReturnPoint + } + if !h { + err = fmt.Errorf("未能找到对应的品牌") + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "获取品牌成功" + rsp.Err = ctx.Err() + rsp.Data = item + 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) AddBrand(ctx context.Context, req proto.BrandItemRequest) (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: + item := &model.Brand{ + BrandName: req.BrandName, + BrandLogo: req.BrandLogo, + BrandWeb: req.BrandWeb, + Status: 1, + CreateAt: time.Now().Unix(), + UpdateAt: time.Now().Unix(), + } + _, err = rp.engine.Insert(item) + if err != nil { + goto ReturnPoint + } + + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "新增品牌成功" + rsp.Err = ctx.Err() + rsp.Data = item + 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) EditBrand(ctx context.Context, req proto.BrandItemRequest) (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: + var h bool + item := new(model.Brand) + h, err = rp.engine.ID(req.BrandId).Get(item) + if err != nil { + goto ReturnPoint + } + if !h { + err = fmt.Errorf("未能找到对应的品牌") + goto ReturnPoint + } + if len(req.BrandName) > 0 { + item.BrandName = req.BrandName + } + if len(req.BrandLogo) > 0 { + item.BrandLogo = req.BrandLogo + } + if len(req.BrandWeb) > 0 { + item.BrandWeb = req.BrandWeb + } + item.UpdateAt = time.Now().Unix() + _, err = rp.engine.ID(req.BrandId).AllCols().Update(item) + if err != nil { + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "修改品牌成功" + rsp.Err = ctx.Err() + rsp.Data = item + 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) DeleteBrand(ctx context.Context, req proto.BrandItemRequest) (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: + var h bool + item := new(model.Brand) + h, err = rp.engine.ID(req.BrandId).Get(item) + if err != nil { + goto ReturnPoint + } + if !h { + err = fmt.Errorf("未能找到对应的品牌") + goto ReturnPoint + } + item.Status = 0 + item.UpdateAt = time.Now().Unix() + _, err = rp.engine.ID(req.BrandId).AllCols().Update(item) + if err != nil { + goto ReturnPoint + } + rsp.Code = http.StatusOK + rsp.Status = http.StatusText(http.StatusOK) + rsp.Message = "删除品牌成功" + rsp.Err = ctx.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 +} diff --git a/model/brand.go b/model/brand.go index b7938e7..7c45c7f 100644 --- a/model/brand.go +++ b/model/brand.go @@ -5,6 +5,7 @@ type Brand struct { BrandName string `xorm:"varchar(200) not null" json:"brandName"` BrandLogo string `xorm:"varchar(200) " json:"brandLogo"` BrandWeb string `xorm:"varchar(200) " json:"brandWeb"` + Status int `xorm:"not null INT(11) default 0" json:"status"` CreateAt int64 `xorm:"created" json:"createAt"` UpdateAt int64 `xorm:"updated" json:"updateAt"` DeleteAt int64 `xorm:"deleted" json:"deleteAt"` diff --git a/model/device.go b/model/device.go index 7248d94..b6c0d75 100644 --- a/model/device.go +++ b/model/device.go @@ -13,6 +13,8 @@ type Device struct { 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"` //纬度 + DeviceDesc string `xorm:"varchar(200)" json:"deviceDesc"` //设备描述 + Status int `xorm:"not null INT(11) default 0" json:"status"` CreateAt int64 `xorm:"created" json:"createAt"` UpdateAt int64 `xorm:"updated" json:"updateAt"` DeleteAt int64 `xorm:"deleted" json:"deleteAt"` diff --git a/model/file.go b/model/file.go new file mode 100644 index 0000000..0d42d3e --- /dev/null +++ b/model/file.go @@ -0,0 +1,13 @@ +package model + +type FileManager struct { + FileId int64 `xorm:"not null pk autoincr INT(11)" json:"fileId"` //文件编号 + FileName string `xorm:"VARCHAR(200)" json:"fileName"` //文件名 + AccessUrl string `xorm:"VARCHAR(400)" json:"url"` //访问路径 + Scene string `xorm:"VARCHAR(40)" json:"scene"` //应用场景,0 : 其他, 1: 道路; 2: 桥梁; 3:隧道; 4: 边坡 + FileSize int64 `xorm:"BIGINT" json:"fileSize"` //文件大小 + FileMd5 string `xorm:"VARCHAR(64)" json:"fileMd5"` //文件MD5 + Creator int64 `xorm:"INT(11) index" json:"creator"` //上传人 + CreateAt int64 `xorm:"created" json:"createAt"` //上传时间 + UpdateAt int64 `xorm:"updated" json:"updateAt"` //更新时间 +} diff --git a/model/index.go b/model/index.go index 9b6e9c8..b39dd31 100644 --- a/model/index.go +++ b/model/index.go @@ -27,6 +27,7 @@ func New(driveName, dsn string) { &Device{}, &DeviceType{}, &Disease{}, + &FileManager{}, &MatterAttribute{}, &MatterCategory{}, &MatterEvent{}, diff --git a/model/systemUser.go b/model/systemUser.go index c4e9d94..6531366 100644 --- a/model/systemUser.go +++ b/model/systemUser.go @@ -1,6 +1,9 @@ package model -import "fmt" +import ( + "encoding/json" + "fmt" +) type SystemUser struct { UserId int64 `xorm:"not null pk autoincr INT(11)" json:"userId"` //用户编号 @@ -26,3 +29,11 @@ func GetUserById(userId int64) (*SystemUser, error) { } return us, err } + +func (us SystemUser) ToString() string { + data, err := json.Marshal(us) + if err != nil { + return "" + } + return string(data) +} diff --git a/pkg/minedata/constants.go b/pkg/minedata/constants.go new file mode 100644 index 0000000..4a129fa --- /dev/null +++ b/pkg/minedata/constants.go @@ -0,0 +1,11 @@ +package minedata + +const ( + GeocodingUrl = "https://service.minedata.cn/service/lbs/search/v1/geo" //地理编码 + ReverseGeocodingUrl = "https://service.minedata.cn/service/lbs/reverse/v1/regeo" //逆地理编码 + + MilepostUrl = "https://service.minedata.cn/service/lbs/kpiles/v1/keywords" // 正里程桩服务 + ReverseMilepostUrl = "https://service.minedata.cn/service/lbs/kpiles/v1/location" // 逆里程桩服务 + + RoadSearchUrl = "https://service.minedata.cn/service/lbs/search/v1/road" // 道路搜索 +) diff --git a/pkg/minedata/httpUtils.go b/pkg/minedata/httpUtils.go new file mode 100644 index 0000000..0c82090 --- /dev/null +++ b/pkg/minedata/httpUtils.go @@ -0,0 +1,40 @@ +package minedata + +import ( + "fmt" + "io" + "net/http" + "net/url" + "strings" +) + +func HttpDo(reqUrl, method string, params map[string]string, header map[string]string) (data []byte, err error) { + var paramStr = "" + for k, v := range params { + if len(paramStr) == 0 { + paramStr = fmt.Sprintf("%s=%s", k, url.QueryEscape(v)) + } else { + paramStr = fmt.Sprintf("%s&%s=%s", paramStr, k, url.QueryEscape(v)) + } + } + client := &http.Client{} + req, err := http.NewRequest(strings.ToUpper(method), reqUrl, strings.NewReader(paramStr)) + if err != nil { + return nil, err + } + req.Header.Set("content-type", "X-WWW-FORM-URLENCODED") + for k, v := range header { + req.Header.Set(k, v) + } + resp, err := client.Do(req) + + defer func() { + _ = resp.Body.Close() + }() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return body, nil +} diff --git a/pkg/minedata/minedata.go b/pkg/minedata/minedata.go new file mode 100644 index 0000000..e3000bf --- /dev/null +++ b/pkg/minedata/minedata.go @@ -0,0 +1,95 @@ +package minedata + +import ( + "encoding/json" + "fmt" +) + +type MineDateClient struct { + AppKey string +} + +func NewMineData(key string) *MineDateClient { + return &MineDateClient{ + AppKey: key, //默认 f0bda738033e47ffbfbd5d3f865c19e1 + } +} + +// ReverseGeocoding 逆地理 +func (client *MineDateClient) ReverseGeocoding(lng, lat float64) (data *ReverseGeocodingResponse, err error) { + params := make(map[string]string) + params["location"] = fmt.Sprintf("%.6f, %.6f", lng, lat) + params["type"] = "道路" + params["coordtype"] = "02" + params["radius"] = "100" + params["extensions"] = "road" + params["key"] = client.AppKey + res, err := HttpDo(ReverseGeocodingUrl, "GET", params, make(map[string]string)) + if err != nil { + return nil, err + } + data = new(ReverseGeocodingResponse) + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, err +} + +// MilepostService 正里程桩服务 +func (client *MineDateClient) MilepostService(formatName string) (data *MilepostResponse, err error) { + params := make(map[string]string) + params["key"] = client.AppKey + params["format_name"] = formatName + res, err := HttpDo(MilepostUrl, "GET", params, make(map[string]string)) + if err != nil { + return nil, err + } + data = new(MilepostResponse) + fmt.Println(string(res)) + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, err +} + +// ReverseMilepost 逆里程桩 +func (client *MineDateClient) ReverseMilepost(lng, lat float64) (data *ReverseMilepostResponse, err error) { + params := make(map[string]string) + params["key"] = client.AppKey + params["location"] = fmt.Sprintf("%.6f, %.6f", lng, lat) + res, err := HttpDo(ReverseMilepostUrl, "GET", params, make(map[string]string)) + if err != nil { + return nil, err + } + data = new(ReverseMilepostResponse) + fmt.Println(string(res)) + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, err +} + +// RoadSearch 道路搜索 +func (client *MineDateClient) RoadSearch(keywords string) (data *RoadSearchResponse, err error) { + params := make(map[string]string) + params["key"] = client.AppKey + params["keywords"] = keywords + params["city"] = "330000" + params["page_idx"] = "1" + params["page_size"] = "20" + params["extensions"] = "all" + params["citylimit"] = "true" + res, err := HttpDo(RoadSearchUrl, "GET", params, make(map[string]string)) + if err != nil { + return nil, err + } + data = new(RoadSearchResponse) + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, err +} diff --git a/pkg/minedata/minedata_test.go b/pkg/minedata/minedata_test.go new file mode 100644 index 0000000..4e3353c --- /dev/null +++ b/pkg/minedata/minedata_test.go @@ -0,0 +1,22 @@ +package minedata + +import ( + "fmt" + "testing" +) + +func TestMineDataService(t *testing.T) { + mine := NewMineData("f0bda738033e47ffbfbd5d3f865c19e1") + //正里程桩 + res, err := mine.MilepostService("G60+K800+600") + if err != nil { + fmt.Println(err) + } + fmt.Println(ToString(res)) + //逆里程桩 + res1, err := mine.ReverseMilepost(119.736232, 29.785655) + if err != nil { + fmt.Println(err) + } + fmt.Println(ToString(res1)) +} diff --git a/pkg/minedata/response.go b/pkg/minedata/response.go new file mode 100644 index 0000000..ade22af --- /dev/null +++ b/pkg/minedata/response.go @@ -0,0 +1,101 @@ +package minedata + +import "encoding/json" + +type MilepostResponse struct { + Status int `json:"status"` + Message string `json:"message"` + Count int `json:"count"` + Items []struct { + Roadname string `json:"roadname"` + Roadid string `json:"roadid"` + Roadtype string `json:"roadtype"` + Kpileid string `json:"kpileid"` + Direction string `json:"direction"` + Location string `json:"location"` + Offset int `json:"offset"` + Adcode string `json:"adcode"` + Province string `json:"province"` + City string `json:"city"` + Area string `json:"area"` + FormatName string `json:"format_name"` + } `json:"items"` +} + +type RoadSearchResponse struct { + Suggestion interface{} `json:"suggestion"` + Count int `json:"count"` + Pois []struct { + Alias interface{} `json:"alias"` + Brandcode string `json:"brandcode"` + Brand string `json:"brand"` + Tag string `json:"tag"` + Hit int `json:"hit"` + Tel string `json:"tel"` + Region struct { + Adcode string `json:"adcode"` + Province string `json:"province"` + City string `json:"city"` + County string `json:"county"` + Town interface{} `json:"town"` + } `json:"region"` + Subpois interface{} `json:"subpois"` + Nid string `json:"nid"` + Name string `json:"name"` + Typecode string `json:"typecode"` + Type string `json:"type"` + Location string `json:"location"` + Address string `json:"address"` + Distance interface{} `json:"distance"` + } `json:"pois"` + Status int `json:"status"` + Message string `json:"message"` +} + +type ReverseMilepostResponse struct { + Status int `json:"status"` + Message string `json:"message"` + Count int `json:"count"` + Items []struct { + Roadname string `json:"roadname"` + Roadid string `json:"roadid"` + Roadtype string `json:"roadtype"` + Direction string `json:"direction"` + Kpileid string `json:"kpileid"` + Location string `json:"location"` + Adcode string `json:"adcode"` + Province string `json:"province"` + City string `json:"city"` + Area string `json:"area"` + Offset int `json:"offset"` + FormatName string `json:"format_name"` + } `json:"items"` +} + +type ReverseGeocodingResponse struct { + Status int `json:"status"` + Message string `json:"message"` + Count int `json:"count"` + Items []struct { + Roadname string `json:"roadname"` + Roadid string `json:"roadid"` + Roadtype string `json:"roadtype"` + Direction string `json:"direction"` + Kpileid string `json:"kpileid"` + Location string `json:"location"` + Adcode string `json:"adcode"` + Province string `json:"province"` + City string `json:"city"` + Area string `json:"area"` + Offset int `json:"offset"` + FormatName string `json:"format_name"` + } `json:"items"` +} + +func ToString(data interface{}) string { + b, err := json.Marshal(data) + if err != nil { + return "" + } + return string(b) +}