тестовый го бэкэнд
This commit is contained in:
726
backend/handler.go
Normal file
726
backend/handler.go
Normal file
@@ -0,0 +1,726 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// --- Helpers ---
|
||||
|
||||
func parseUUID(c *gin.Context, param string) (uuid.UUID, bool) {
|
||||
id, err := uuid.Parse(c.Param(param))
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"detail": "invalid uuid"})
|
||||
return uuid.Nil, false
|
||||
}
|
||||
return id, true
|
||||
}
|
||||
|
||||
func templateAttributeDetails(db *gorm.DB, templateID uuid.UUID) []gin.H {
|
||||
var allAttrs []Attribute
|
||||
db.Find(&allAttrs)
|
||||
|
||||
var tas []TemplateAttribute
|
||||
db.Where("template_id = ?", templateID).Preload("Attribute").Find(&tas)
|
||||
|
||||
taMap := map[uuid.UUID]*TemplateAttribute{}
|
||||
for i := range tas {
|
||||
taMap[tas[i].AttributeID] = &tas[i]
|
||||
}
|
||||
|
||||
result := []gin.H{}
|
||||
for _, a := range allAttrs {
|
||||
detail := gin.H{
|
||||
"attribute_id": a.ID,
|
||||
"attribute_name": a.Name,
|
||||
"is_required": a.IsRequired,
|
||||
"value": nil,
|
||||
}
|
||||
if ta, ok := taMap[a.ID]; ok {
|
||||
detail["value"] = ta.Value
|
||||
}
|
||||
result = append(result, detail)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func templateWithAttrs(db *gorm.DB, t Template) gin.H {
|
||||
return gin.H{
|
||||
"id": t.ID,
|
||||
"name": t.Name,
|
||||
"description": t.Description,
|
||||
"elements": json.RawMessage(t.Elements),
|
||||
"group_id": t.GroupID,
|
||||
"attributes": templateAttributeDetails(db, t.ID),
|
||||
"order": t.Order,
|
||||
"created_at": t.CreatedAt,
|
||||
"updated_at": t.UpdatedAt,
|
||||
"deleted_at": t.DeletedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// --- Templates ---
|
||||
|
||||
func getTemplates(c *gin.Context, db *gorm.DB) {
|
||||
var templates []Template
|
||||
db.Find(&templates)
|
||||
|
||||
result := []gin.H{}
|
||||
for _, t := range templates {
|
||||
result = append(result, templateWithAttrs(db, t))
|
||||
}
|
||||
c.JSON(200, gin.H{"templates": result})
|
||||
}
|
||||
|
||||
func getTemplate(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var t Template
|
||||
if db.First(&t, "id = ?", id).Error != nil {
|
||||
c.JSON(200, gin.H{"template": nil})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"template": templateWithAttrs(db, t)})
|
||||
}
|
||||
|
||||
func createTemplate(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Elements json.RawMessage `json:"elements"`
|
||||
Attributes []setTemplateAttrInput `json:"attributes"`
|
||||
GroupID *uuid.UUID `json:"group_id"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
t := Template{Name: input.Name, Description: &input.Description, Elements: JSON(input.Elements), GroupID: input.GroupID}
|
||||
db.Create(&t)
|
||||
|
||||
for _, a := range input.Attributes {
|
||||
db.Create(&TemplateAttribute{TemplateID: t.ID, AttributeID: a.AttributeID, Value: a.Value})
|
||||
}
|
||||
c.JSON(200, gin.H{"id": t.ID})
|
||||
}
|
||||
|
||||
type setTemplateAttrInput struct {
|
||||
AttributeID uuid.UUID `json:"attribute_id"`
|
||||
Value *string `json:"value"`
|
||||
}
|
||||
|
||||
func patchTemplate(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var t Template
|
||||
if db.First(&t, "id = ?", id).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "Template not found"})
|
||||
return
|
||||
}
|
||||
|
||||
var input struct {
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
Elements *json.RawMessage `json:"elements"`
|
||||
Attributes []setTemplateAttrInput `json:"attributes"`
|
||||
GroupID interface{} `json:"group_id"`
|
||||
Order *float64 `json:"order"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
updates := map[string]interface{}{}
|
||||
if input.Name != nil {
|
||||
updates["name"] = *input.Name
|
||||
}
|
||||
if input.Description != nil {
|
||||
updates["description"] = *input.Description
|
||||
}
|
||||
if input.Elements != nil {
|
||||
updates["elements"] = JSON(*input.Elements)
|
||||
}
|
||||
if input.Order != nil {
|
||||
updates["order"] = *input.Order
|
||||
}
|
||||
if input.GroupID != nil {
|
||||
switch v := input.GroupID.(type) {
|
||||
case string:
|
||||
if v == "ungroup" {
|
||||
updates["group_id"] = nil
|
||||
} else {
|
||||
if uid, err := uuid.Parse(v); err == nil {
|
||||
updates["group_id"] = uid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(updates) > 0 {
|
||||
db.Model(&t).Updates(updates)
|
||||
}
|
||||
|
||||
for _, a := range input.Attributes {
|
||||
res := db.Model(&TemplateAttribute{}).Where("template_id = ? AND attribute_id = ?", id, a.AttributeID).Update("value", a.Value)
|
||||
if res.RowsAffected == 0 {
|
||||
db.Create(&TemplateAttribute{TemplateID: id, AttributeID: a.AttributeID, Value: a.Value})
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"id": t.ID})
|
||||
}
|
||||
|
||||
func deleteTemplate(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
res := db.Delete(&Template{}, "id = ?", id)
|
||||
if res.RowsAffected == 0 {
|
||||
c.JSON(404, gin.H{"detail": "Template not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"success": true, "template_id": id})
|
||||
}
|
||||
|
||||
func copyTemplate(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
TemplateID uuid.UUID `json:"template_id"`
|
||||
NewName string `json:"new_name"`
|
||||
NewDescription *string `json:"new_description"`
|
||||
NewAttributes []setTemplateAttrInput `json:"new_attributes"`
|
||||
GroupID *uuid.UUID `json:"group_id"`
|
||||
CopyFirstSheetEmpty bool `json:"copy_first_sheet_empty"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var orig Template
|
||||
if db.First(&orig, "id = ?", input.TemplateID).Error != nil {
|
||||
c.JSON(400, gin.H{"detail": "Template not found"})
|
||||
return
|
||||
}
|
||||
|
||||
// Update element IDs
|
||||
newElements := updateElementIDs(orig.Elements)
|
||||
|
||||
newT := Template{Name: input.NewName, Description: input.NewDescription, Elements: newElements, GroupID: input.GroupID}
|
||||
db.Create(&newT)
|
||||
|
||||
// Copy files
|
||||
var files []File
|
||||
db.Where("template_id = ?", input.TemplateID).Find(&files)
|
||||
for _, f := range files {
|
||||
newF := File{Name: f.Name, Content: f.Content, Cells: f.Cells, TemplateID: &newT.ID}
|
||||
db.Create(&newF)
|
||||
}
|
||||
|
||||
// Copy sheets
|
||||
var sheets []Sheet
|
||||
db.Where("template_id = ?", input.TemplateID).Find(&sheets)
|
||||
for _, s := range sheets {
|
||||
cells := s.Cells
|
||||
if s.Name == "L" && input.CopyFirstSheetEmpty {
|
||||
cells = JSON("{}")
|
||||
}
|
||||
newS := Sheet{Name: s.Name, Cells: cells, TemplateID: newT.ID}
|
||||
db.Create(&newS)
|
||||
}
|
||||
|
||||
// Copy or set attributes
|
||||
if len(input.NewAttributes) > 0 {
|
||||
for _, a := range input.NewAttributes {
|
||||
db.Create(&TemplateAttribute{TemplateID: newT.ID, AttributeID: a.AttributeID, Value: a.Value})
|
||||
}
|
||||
} else {
|
||||
var origAttrs []TemplateAttribute
|
||||
db.Where("template_id = ?", input.TemplateID).Find(&origAttrs)
|
||||
for _, a := range origAttrs {
|
||||
db.Create(&TemplateAttribute{TemplateID: newT.ID, AttributeID: a.AttributeID, Value: a.Value})
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"new_template_id": newT.ID})
|
||||
}
|
||||
|
||||
func updateElementIDs(elements JSON) JSON {
|
||||
var parsed map[string]interface{}
|
||||
if json.Unmarshal(elements, &parsed) != nil || parsed == nil {
|
||||
return elements
|
||||
}
|
||||
newElements := map[string]interface{}{}
|
||||
for _, data := range parsed {
|
||||
newID := uuid.New().String()
|
||||
if m, ok := data.(map[string]interface{}); ok {
|
||||
m["id"] = newID
|
||||
}
|
||||
newElements[newID] = data
|
||||
}
|
||||
result, _ := json.Marshal(newElements)
|
||||
return JSON(result)
|
||||
}
|
||||
|
||||
// --- Files ---
|
||||
|
||||
func getFiles(c *gin.Context, db *gorm.DB) {
|
||||
var files []File
|
||||
q := db.Model(&File{})
|
||||
if tid := c.Query("template_id"); tid != "" {
|
||||
q = q.Where("template_id = ?", tid)
|
||||
}
|
||||
q.Find(&files)
|
||||
c.JSON(200, gin.H{"files": files})
|
||||
}
|
||||
|
||||
func getFile(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var f File
|
||||
if db.First(&f, "id = ?", id).Error != nil {
|
||||
c.JSON(200, gin.H{"file": nil})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"file": f})
|
||||
}
|
||||
|
||||
func uploadFile(c *gin.Context, db *gorm.DB) {
|
||||
templateID, err := uuid.Parse(c.Query("template_id"))
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"detail": "invalid template_id"})
|
||||
return
|
||||
}
|
||||
|
||||
fileHeader, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"detail": "file required"})
|
||||
return
|
||||
}
|
||||
|
||||
f, _ := fileHeader.Open()
|
||||
defer f.Close()
|
||||
content, _ := io.ReadAll(f)
|
||||
|
||||
cellsData, err := ReadCells(content)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"detail": fmt.Sprintf("failed to read cells: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
cellsJSON, _ := json.Marshal(cellsData)
|
||||
file := File{Name: fileHeader.Filename, Content: content, Cells: JSON(cellsJSON), TemplateID: &templateID}
|
||||
db.Create(&file)
|
||||
|
||||
c.JSON(200, gin.H{"file_id": file.ID, "cells": cellsData})
|
||||
}
|
||||
|
||||
// --- Sheets ---
|
||||
|
||||
func getSheets(c *gin.Context, db *gorm.DB) {
|
||||
var sheets []Sheet
|
||||
q := db.Model(&Sheet{})
|
||||
if tid := c.Query("template_id"); tid != "" {
|
||||
q = q.Where("template_id = ?", tid)
|
||||
}
|
||||
q.Find(&sheets)
|
||||
c.JSON(200, gin.H{"sheets": sheets})
|
||||
}
|
||||
|
||||
func getSheet(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var s Sheet
|
||||
if db.First(&s, "id = ?", id).Error != nil {
|
||||
c.JSON(200, gin.H{"sheet": nil})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"sheet": s})
|
||||
}
|
||||
|
||||
func createSheet(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
Name string `json:"name"`
|
||||
Cells json.RawMessage `json:"cells"`
|
||||
TemplateID uuid.UUID `json:"template_id"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
s := Sheet{Name: input.Name, Cells: JSON(input.Cells), TemplateID: input.TemplateID}
|
||||
db.Create(&s)
|
||||
c.JSON(200, gin.H{"id": s.ID})
|
||||
}
|
||||
|
||||
func patchSheet(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var s Sheet
|
||||
if db.First(&s, "id = ?", id).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "Sheet not found"})
|
||||
return
|
||||
}
|
||||
var input struct {
|
||||
Name *string `json:"name"`
|
||||
Cells *json.RawMessage `json:"cells"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
updates := map[string]interface{}{}
|
||||
if input.Name != nil {
|
||||
updates["name"] = *input.Name
|
||||
}
|
||||
if input.Cells != nil {
|
||||
updates["cells"] = JSON(*input.Cells)
|
||||
}
|
||||
if len(updates) > 0 {
|
||||
db.Model(&s).Updates(updates)
|
||||
}
|
||||
c.JSON(200, gin.H{"id": s.ID})
|
||||
}
|
||||
|
||||
// --- Attributes ---
|
||||
|
||||
func getAttributes(c *gin.Context, db *gorm.DB) {
|
||||
var attrs []Attribute
|
||||
db.Find(&attrs)
|
||||
c.JSON(200, gin.H{"attributes": attrs})
|
||||
}
|
||||
|
||||
func createAttribute(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
Name string `json:"name"`
|
||||
IsRequired bool `json:"is_required"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
var existing Attribute
|
||||
if db.Where("name = ?", input.Name).First(&existing).Error == nil {
|
||||
c.JSON(400, gin.H{"detail": fmt.Sprintf("Атрибут с именем '%s' уже существует", input.Name)})
|
||||
return
|
||||
}
|
||||
a := Attribute{Name: input.Name, IsRequired: input.IsRequired}
|
||||
db.Create(&a)
|
||||
c.JSON(200, gin.H{"id": a.ID})
|
||||
}
|
||||
|
||||
func getAttributeValues(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var attr Attribute
|
||||
if db.First(&attr, "id = ?", id).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "Attribute not found"})
|
||||
return
|
||||
}
|
||||
|
||||
type valCount struct {
|
||||
Value string `json:"value"`
|
||||
UsageCount int `json:"usage_count"`
|
||||
}
|
||||
var values []valCount
|
||||
db.Model(&TemplateAttribute{}).
|
||||
Select("value, count(template_id) as usage_count").
|
||||
Where("attribute_id = ? AND value IS NOT NULL", id).
|
||||
Group("value").
|
||||
Order("usage_count DESC").
|
||||
Find(&values)
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"attribute_id": attr.ID,
|
||||
"attribute_name": attr.Name,
|
||||
"values": values,
|
||||
"total_count": len(values),
|
||||
})
|
||||
}
|
||||
|
||||
// --- Standards ---
|
||||
|
||||
func getStandards(c *gin.Context, db *gorm.DB) {
|
||||
var standards []Standard
|
||||
db.Find(&standards)
|
||||
c.JSON(200, gin.H{"standards": standards})
|
||||
}
|
||||
|
||||
func getStandard(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var s Standard
|
||||
if db.First(&s, "id = ?", id).Error != nil {
|
||||
c.JSON(200, gin.H{"standard": nil})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"standard": s})
|
||||
}
|
||||
|
||||
func createStandard(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
Name string `json:"name"`
|
||||
ProtocolName string `json:"protocol_name"`
|
||||
RegistryNumber string `json:"registry_number"`
|
||||
Range string `json:"range"`
|
||||
Accuracy string `json:"accuracy"`
|
||||
ValidUntil string `json:"valid_until"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
validUntil, _ := time.Parse("2006-01-02", input.ValidUntil)
|
||||
s := Standard{
|
||||
Name: input.Name, ProtocolName: input.ProtocolName, RegistryNumber: input.RegistryNumber,
|
||||
Range: input.Range, Accuracy: input.Accuracy, ValidUntil: validUntil,
|
||||
}
|
||||
db.Create(&s)
|
||||
c.JSON(200, gin.H{"id": s.ID})
|
||||
}
|
||||
|
||||
func patchStandard(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var s Standard
|
||||
if db.First(&s, "id = ?", id).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "Standard not found"})
|
||||
return
|
||||
}
|
||||
var raw map[string]interface{}
|
||||
if c.BindJSON(&raw) != nil {
|
||||
return
|
||||
}
|
||||
db.Model(&s).Updates(raw)
|
||||
c.JSON(200, gin.H{"id": s.ID})
|
||||
}
|
||||
|
||||
func deleteStandard(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
res := db.Delete(&Standard{}, "id = ?", id)
|
||||
if res.RowsAffected == 0 {
|
||||
c.JSON(404, gin.H{"detail": "Standard not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"message": "Standard deleted successfully"})
|
||||
}
|
||||
|
||||
// --- Laboratories ---
|
||||
|
||||
func getLaboratories(c *gin.Context, db *gorm.DB) {
|
||||
var labs []Laboratory
|
||||
db.Preload("ConditionTypes").Find(&labs)
|
||||
c.JSON(200, gin.H{"laboratories": labs})
|
||||
}
|
||||
|
||||
func getLaboratory(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var lab Laboratory
|
||||
if db.Preload("ConditionTypes").First(&lab, "id = ?", id).Error != nil {
|
||||
c.JSON(200, gin.H{"laboratory": nil})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"laboratory": lab})
|
||||
}
|
||||
|
||||
// --- Daily Conditions ---
|
||||
|
||||
func getDailyConditions(c *gin.Context, db *gorm.DB) {
|
||||
q := db.Model(&DailyCondition{})
|
||||
if lid := c.Query("laboratory_id"); lid != "" {
|
||||
q = q.Where("laboratory_id = ?", lid)
|
||||
}
|
||||
if sd := c.Query("start_date"); sd != "" {
|
||||
q = q.Where("measurement_date >= ?", sd)
|
||||
}
|
||||
if ed := c.Query("end_date"); ed != "" {
|
||||
q = q.Where("measurement_date <= ?", ed)
|
||||
}
|
||||
var dcs []DailyCondition
|
||||
q.Find(&dcs)
|
||||
c.JSON(200, gin.H{"daily_conditions": dcs})
|
||||
}
|
||||
|
||||
func getDailyCondition(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var dc DailyCondition
|
||||
if db.First(&dc, "id = ?", id).Error != nil {
|
||||
c.JSON(200, gin.H{"daily_condition": nil})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"daily_condition": dc})
|
||||
}
|
||||
|
||||
func createDailyCondition(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
LaboratoryID uuid.UUID `json:"laboratory_id"`
|
||||
MeasurementDate string `json:"measurement_date"`
|
||||
Conditions json.RawMessage `json:"conditions"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
var lab Laboratory
|
||||
if db.First(&lab, "id = ?", input.LaboratoryID).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "Laboratory not found"})
|
||||
return
|
||||
}
|
||||
md, _ := time.Parse("2006-01-02", input.MeasurementDate)
|
||||
dc := DailyCondition{LaboratoryID: input.LaboratoryID, MeasurementDate: md, Conditions: JSON(input.Conditions)}
|
||||
db.Create(&dc)
|
||||
c.JSON(200, gin.H{"id": dc.ID})
|
||||
}
|
||||
|
||||
func updateDailyCondition(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var dc DailyCondition
|
||||
if db.First(&dc, "id = ?", id).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "Daily condition not found"})
|
||||
return
|
||||
}
|
||||
var raw map[string]interface{}
|
||||
if c.BindJSON(&raw) != nil {
|
||||
return
|
||||
}
|
||||
db.Model(&dc).Updates(raw)
|
||||
c.JSON(200, gin.H{"id": dc.ID})
|
||||
}
|
||||
|
||||
func deleteDailyCondition(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
res := db.Delete(&DailyCondition{}, "id = ?", id)
|
||||
if res.RowsAffected == 0 {
|
||||
c.JSON(404, gin.H{"detail": "Daily condition not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"message": "Daily condition deleted successfully"})
|
||||
}
|
||||
|
||||
// --- Groups ---
|
||||
|
||||
func getGroups(c *gin.Context, db *gorm.DB) {
|
||||
var groups []Group
|
||||
db.Order("\"order\", name").Find(&groups)
|
||||
c.JSON(200, gin.H{"groups": groups})
|
||||
}
|
||||
|
||||
func getGroup(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var g Group
|
||||
if db.First(&g, "id = ?", id).Error != nil {
|
||||
c.JSON(200, gin.H{"group": nil})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"group": g})
|
||||
}
|
||||
|
||||
func createGroup(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
Name string `json:"name"`
|
||||
Order float64 `json:"order"`
|
||||
IsVisible *bool `json:"is_visible"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
isVisible := true
|
||||
if input.IsVisible != nil {
|
||||
isVisible = *input.IsVisible
|
||||
}
|
||||
g := Group{Name: input.Name, Order: input.Order, IsVisible: isVisible}
|
||||
db.Create(&g)
|
||||
c.JSON(200, gin.H{"id": g.ID})
|
||||
}
|
||||
|
||||
func patchGroup(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var g Group
|
||||
if db.First(&g, "id = ?", id).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "Group not found"})
|
||||
return
|
||||
}
|
||||
var raw map[string]interface{}
|
||||
if c.BindJSON(&raw) != nil {
|
||||
return
|
||||
}
|
||||
db.Model(&g).Updates(raw)
|
||||
db.First(&g, "id = ?", id) // reload
|
||||
c.JSON(200, g)
|
||||
}
|
||||
|
||||
func deleteGroup(c *gin.Context, db *gorm.DB) {
|
||||
id, ok := parseUUID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
res := db.Delete(&Group{}, "id = ?", id)
|
||||
c.JSON(200, gin.H{"success": res.RowsAffected > 0})
|
||||
}
|
||||
|
||||
// --- Protocols ---
|
||||
|
||||
func createProtocol(c *gin.Context, db *gorm.DB) {
|
||||
var input struct {
|
||||
TemplateID uuid.UUID `json:"template_id"`
|
||||
FileID uuid.UUID `json:"file_id"`
|
||||
CellsToUpdate map[string]interface{} `json:"cells_to_update"`
|
||||
PrintArea string `json:"print_area"`
|
||||
}
|
||||
if c.BindJSON(&input) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var file File
|
||||
if db.First(&file, "id = ?", input.FileID).Error != nil {
|
||||
c.JSON(404, gin.H{"detail": "File not found"})
|
||||
return
|
||||
}
|
||||
|
||||
modified, err := FillCells(input.CellsToUpdate, file.Content, input.PrintArea)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"detail": fmt.Sprintf("Excel error: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
protocolID := uuid.New()
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=protocol_%s.xlsx", protocolID))
|
||||
c.Data(200, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", modified)
|
||||
}
|
||||
Reference in New Issue
Block a user