equipment documentation
parent
74c6f93d3a
commit
a3ff89f5a1
3
main.go
3
main.go
|
@ -183,7 +183,8 @@ func createServerDirectoriesIfNotExists() {
|
||||||
cfg.LogsSystem,
|
cfg.LogsSystem,
|
||||||
cfg.PublicStatic + "avatars/",
|
cfg.PublicStatic + "avatars/",
|
||||||
cfg.PublicStatic + "grouptasks/",
|
cfg.PublicStatic + "grouptasks/",
|
||||||
cfg.PublicStatic + "sounds/"}
|
cfg.PublicStatic + "sounds/",
|
||||||
|
cfg.PublicStatic + "equipmentdocumentation/"}
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
|
|
|
@ -43,6 +43,5 @@ func InitDatabase() {
|
||||||
db.AutoMigrate(&structs.Role{})
|
db.AutoMigrate(&structs.Role{})
|
||||||
db.AutoMigrate(&structs.RolePermission{})
|
db.AutoMigrate(&structs.RolePermission{})
|
||||||
db.AutoMigrate(&structs.UserApiKey{})
|
db.AutoMigrate(&structs.UserApiKey{})
|
||||||
db.AutoMigrate(&structs.Equipment{})
|
|
||||||
db.AutoMigrate(&structs.EquipmentDocumentation{})
|
db.AutoMigrate(&structs.EquipmentDocumentation{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
package equipment
|
package equipment
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"jannex/admin-dashboard-backend/modules/database"
|
"jannex/admin-dashboard-backend/modules/database"
|
||||||
"jannex/admin-dashboard-backend/modules/structs"
|
"jannex/admin-dashboard-backend/modules/structs"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const Base = "https://inv.ex.umbach.dev"
|
const Base = "https://inv.ex.umbach.dev"
|
||||||
const apiBase = Base + "/api"
|
const apiBase = Base + "/api"
|
||||||
const ApiToken = "1367f15d21935e4eb540f897946fb5cd98485c3f"
|
const ApiToken = "1367f15d21935e4eb540f897946fb5cd98485c3f"
|
||||||
|
|
||||||
|
func GetEquipmentDocumentation(stockItemId string, c *fiber.Ctx) error {
|
||||||
|
var documentations []structs.EquipmentDocumentation
|
||||||
|
|
||||||
|
database.DB.Where("stock_item_id = ?", stockItemId).Find(&documentations)
|
||||||
|
|
||||||
|
return c.JSON(documentations)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func GetEquipmentDocumentation(stockItemId string, c *fiber.Ctx) error {
|
func GetEquipmentDocumentation(stockItemId string, c *fiber.Ctx) error {
|
||||||
equipment := structs.Equipment{Id: stockItemId}
|
equipment := structs.Equipment{Id: stockItemId}
|
||||||
|
|
||||||
|
@ -79,14 +84,16 @@ func GetEquipmentDocumentation(stockItemId string, c *fiber.Ctx) error {
|
||||||
|
|
||||||
return c.JSON([]structs.EquipmentDocumentation{})
|
return c.JSON([]structs.EquipmentDocumentation{})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
func GetEquipment() []structs.Equipment {
|
func GetEquipment() []structs.Equipment {
|
||||||
var equipments []structs.Equipment
|
var equipments []structs.Equipment
|
||||||
|
|
||||||
database.DB.Find(&equipments)
|
database.DB.Find(&equipments)
|
||||||
|
|
||||||
return equipments
|
return equipments
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// return whether the scanned equipment is existing in the database
|
// return whether the scanned equipment is existing in the database
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"jannex/admin-dashboard-backend/modules/cache"
|
"jannex/admin-dashboard-backend/modules/cache"
|
||||||
"jannex/admin-dashboard-backend/modules/config"
|
"jannex/admin-dashboard-backend/modules/config"
|
||||||
"jannex/admin-dashboard-backend/modules/database"
|
"jannex/admin-dashboard-backend/modules/database"
|
||||||
|
@ -535,7 +534,7 @@ func RunGroupTask(args RunGroupTaskArgs) {
|
||||||
log.Error().Msgf("Error reading file %s", err.Error())
|
log.Error().Msgf("Error reading file %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(config.Cfg.FolderPaths.GroupTasksRunningTasks+groupTaskStep.GroupTasksId+"/"+info.Name(), bytesRead, 0644)
|
err = os.WriteFile(config.Cfg.FolderPaths.GroupTasksRunningTasks+groupTaskStep.GroupTasksId+"/"+info.Name(), bytesRead, 0644)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msgf("Error writing file %s", err.Error())
|
log.Error().Msgf("Error writing file %s", err.Error())
|
||||||
|
|
|
@ -1,22 +1,37 @@
|
||||||
package structs
|
package structs
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
type Equipment struct {
|
type Equipment struct {
|
||||||
Id string // stock item id of invex system
|
Id string // stock item id of invex system
|
||||||
Name string
|
Name string
|
||||||
Thumbnail string // url provided by invex system
|
Thumbnail string // url provided by invex system
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
} */
|
||||||
|
|
||||||
type EquipmentDocumentation struct {
|
type EquipmentDocumentation struct {
|
||||||
Id string // stock item id of invex system
|
Id string
|
||||||
Content string
|
StockItemId string // stock item id of invex system
|
||||||
CreatedAt time.Time
|
Type uint8
|
||||||
UpdatedAt time.Time
|
Title string
|
||||||
|
Notes string
|
||||||
|
CreatedByUserId string
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApiEquipmentParamsRequest struct {
|
type ApiEquipmentParamsRequest struct {
|
||||||
StockItemId string `json:"stockItemId"`
|
StockItemId string `json:"stockItemId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ApiCreateEquipmentDocumentationRequest struct {
|
||||||
|
StockItemId string `json:"stockItemId"`
|
||||||
|
Type uint8 `json:"type"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Notes json.RawMessage `json:"notes"`
|
||||||
|
}
|
||||||
|
|
|
@ -1,16 +1,117 @@
|
||||||
package equipment
|
package equipment
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"jannex/admin-dashboard-backend/modules/config"
|
||||||
|
"jannex/admin-dashboard-backend/modules/database"
|
||||||
"jannex/admin-dashboard-backend/modules/equipment"
|
"jannex/admin-dashboard-backend/modules/equipment"
|
||||||
"jannex/admin-dashboard-backend/modules/structs"
|
"jannex/admin-dashboard-backend/modules/structs"
|
||||||
"jannex/admin-dashboard-backend/modules/utils"
|
"jannex/admin-dashboard-backend/modules/utils"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetEquipment(c *fiber.Ctx) error {
|
func getImageType(data string) string {
|
||||||
return c.JSON(equipment.GetEquipment())
|
switch data {
|
||||||
|
case "data:image/png;base64":
|
||||||
|
return "png"
|
||||||
|
default:
|
||||||
|
return "jpeg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Notes struct {
|
||||||
|
Image string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateEquipmentDocumentation(c *fiber.Ctx) error {
|
||||||
|
var body structs.ApiCreateEquipmentDocumentationRequest
|
||||||
|
|
||||||
|
if err := c.BodyParser(&body); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bodyNotes []map[string]string
|
||||||
|
|
||||||
|
err := json.Unmarshal(body.Notes, &bodyNotes)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("Failed to unmarshal json, err: %s", err)
|
||||||
|
return c.SendStatus(fiber.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
newEquipmentDocumentation := structs.EquipmentDocumentation{
|
||||||
|
Id: uuid.New().String(),
|
||||||
|
StockItemId: body.StockItemId,
|
||||||
|
Type: body.Type,
|
||||||
|
Title: body.Title,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: only create folder if there is an image
|
||||||
|
if err := os.Mkdir(config.Cfg.FolderPaths.PublicStatic+"/equipmentdocumentation/"+newEquipmentDocumentation.Id, os.ModePerm); err != nil {
|
||||||
|
log.Error().Msgf("Failed to create folder, err: %s", err)
|
||||||
|
return c.SendStatus(fiber.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
var notes []Notes
|
||||||
|
|
||||||
|
// loop throught bodyNotes and save image to static folder under random name
|
||||||
|
for _, bodyNote := range bodyNotes {
|
||||||
|
log.Info().Msgf("bodyNote %s", bodyNote)
|
||||||
|
|
||||||
|
var newFileName string
|
||||||
|
|
||||||
|
if bodyNote["image"] != "" {
|
||||||
|
// image is sent as base64 string
|
||||||
|
// decode it and save it to the static folder
|
||||||
|
|
||||||
|
// encoded base64 image structure is: data:image/jpeg;base64,/9j/4AA...
|
||||||
|
splittedImageData := strings.Split(bodyNote["image"], ",")
|
||||||
|
|
||||||
|
decodedImage, err := base64.StdEncoding.DecodeString(splittedImageData[1])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("Failed to decode base64 string, err: %s", err)
|
||||||
|
return c.SendStatus(fiber.StatusInternalServerError)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
newFileName = uuid.New().String() + "." + getImageType(splittedImageData[0])
|
||||||
|
|
||||||
|
err = os.WriteFile(config.Cfg.FolderPaths.PublicStatic+"/equipmentdocumentation/"+newEquipmentDocumentation.Id+"/"+newFileName, decodedImage, 0644)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("Failed to save image, err: %s", err)
|
||||||
|
return c.SendStatus(fiber.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notes = append(notes, Notes{
|
||||||
|
Image: newFileName,
|
||||||
|
Description: bodyNote["description"],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().Msgf("bodyNotes %v", bodyNotes)
|
||||||
|
|
||||||
|
marshaledNotes, err := json.Marshal(notes)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("Failed to marshal notes, err: %s", err)
|
||||||
|
return c.SendStatus(fiber.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
newEquipmentDocumentation.Notes = string(marshaledNotes)
|
||||||
|
|
||||||
|
database.DB.Create(&newEquipmentDocumentation)
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{"message": "ok"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetEquipmentDocumentation(c *fiber.Ctx) error {
|
func GetEquipmentDocumentation(c *fiber.Ctx) error {
|
||||||
|
@ -48,13 +149,6 @@ func GetEquipmentThumbnail(c *fiber.Ctx) error {
|
||||||
code, body, errs := a.Bytes()
|
code, body, errs := a.Bytes()
|
||||||
|
|
||||||
log.Info().Msgf("code %d %s", code, errs)
|
log.Info().Msgf("code %d %s", code, errs)
|
||||||
/*
|
|
||||||
resp := fiber.AcquireResponse()
|
|
||||||
|
|
||||||
a.SetResponse(resp)
|
|
||||||
|
|
||||||
fiber.ReleaseResponse(resp)
|
|
||||||
*/
|
|
||||||
|
|
||||||
c.Set("Content-Type", "image/png")
|
c.Set("Content-Type", "image/png")
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,9 @@ func SetupRoutes(app *fiber.App) {
|
||||||
e := v1.Group("/equipment")
|
e := v1.Group("/equipment")
|
||||||
// TODO: add user session validation
|
// TODO: add user session validation
|
||||||
//e.Get("/scanned/:stockItemId", requestAccessValidation, equipment.EquipmentScanned)
|
//e.Get("/scanned/:stockItemId", requestAccessValidation, equipment.EquipmentScanned)
|
||||||
e.Get("/", requestAccessValidation, equipment.GetEquipment)
|
//e.Get("/", requestAccessValidation, equipment.GetEquipment)
|
||||||
e.Get("/documentation/:stockItemId", requestAccessValidation, equipment.GetEquipmentDocumentation)
|
e.Get("/documentation/:stockItemId", requestAccessValidation, equipment.GetEquipmentDocumentation)
|
||||||
|
e.Post("/documentation/create", requestAccessValidation, equipment.CreateEquipmentDocumentation)
|
||||||
// access validation here implented as it would require to implement authorization on web client side on Avatar Component
|
// access validation here implented as it would require to implement authorization on web client side on Avatar Component
|
||||||
e.Get("/thumbnail/media/part_images/:stockItemThumbnail", equipment.GetEquipmentThumbnail)
|
e.Get("/thumbnail/media/part_images/:stockItemThumbnail", equipment.GetEquipmentThumbnail)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue