Files
hr_data_analyzer/models/product_definition.go
2026-05-01 07:46:48 +08:00

191 lines
6.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package models
import (
"encoding/json"
"errors"
"strings"
"time"
"gorm.io/gorm"
)
type ProductDefinition struct {
ID uint `gorm:"primaryKey" json:"id"`
Code string `gorm:"size:64;not null;uniqueIndex" json:"code"`
Name string `gorm:"size:255;not null" json:"name"`
Category string `gorm:"size:64;not null;default:'device';index" json:"category"`
Description string `gorm:"size:1024" json:"description"`
ParameterSchema string `gorm:"type:text" json:"parameterSchema"`
TrackSerialNumber bool `gorm:"not null;default:false" json:"trackSerialNumber"`
IsActive bool `gorm:"not null;default:true;index" json:"isActive"`
Sort int `gorm:"not null;default:0;index" json:"sort"`
CreatedAt int64 `gorm:"not null" json:"created_at"`
UpdatedAt int64 `gorm:"not null" json:"updated_at"`
}
func (ProductDefinition) TableName() string {
return "product_definitions"
}
func (p *ProductDefinition) BeforeCreate(tx *gorm.DB) (err error) {
now := time.Now().UnixMilli()
p.Code = normalizeProductCodeValue(p.Code)
p.Name = strings.TrimSpace(p.Name)
p.Category = normalizeProductCategoryValue(p.Category)
p.Description = strings.TrimSpace(p.Description)
p.ParameterSchema = normalizeJSONTextValue(p.ParameterSchema)
p.CreatedAt = now
p.UpdatedAt = now
return nil
}
func (p *ProductDefinition) BeforeUpdate(tx *gorm.DB) (err error) {
p.Code = normalizeProductCodeValue(p.Code)
p.Name = strings.TrimSpace(p.Name)
p.Category = normalizeProductCategoryValue(p.Category)
p.Description = strings.TrimSpace(p.Description)
p.ParameterSchema = normalizeJSONTextValue(p.ParameterSchema)
p.UpdatedAt = time.Now().UnixMilli()
return nil
}
func normalizeProductCodeValue(code string) string {
return strings.TrimSpace(strings.ToLower(code))
}
func normalizeProductCategoryValue(category string) string {
value := strings.TrimSpace(strings.ToLower(category))
if value == "" {
return "device"
}
return value
}
func normalizeJSONTextValue(value string) string {
trimmed := strings.TrimSpace(value)
if trimmed == "" {
return ""
}
if !json.Valid([]byte(trimmed)) {
return ""
}
return trimmed
}
type ProductParameterSchemaField struct {
Key string `json:"key"`
Label string `json:"label"`
Type string `json:"type"`
Required bool `json:"required"`
Options []string `json:"options,omitempty"`
}
func mustJSON(value interface{}) string {
bytes, err := json.Marshal(value)
if err != nil {
return "[]"
}
return string(bytes)
}
func EnsureDefaultProductDefinitions(db *gorm.DB) error {
defaults := []ProductDefinition{
{
Code: "charging_case_large",
Name: "充电收纳箱20位",
Category: "container",
Description: "可收纳20个手环的大充电收纳箱",
ParameterSchema: mustJSON([]ProductParameterSchemaField{{Key: "capacity", Label: "容量", Type: "number", Required: false}, {Key: "powerAdapter", Label: "适配器型号", Type: "string", Required: false}}),
TrackSerialNumber: true,
IsActive: true,
Sort: 10,
},
{
Code: "charging_case_small",
Name: "小充电收纳箱10位",
Category: "container",
Description: "可收纳10个手环的小充电收纳箱",
ParameterSchema: mustJSON([]ProductParameterSchemaField{{Key: "capacity", Label: "容量", Type: "number", Required: false}, {Key: "powerAdapter", Label: "适配器型号", Type: "string", Required: false}}),
TrackSerialNumber: true,
IsActive: true,
Sort: 20,
},
{
Code: "collection_band",
Name: "采集手环",
Category: "wearable",
Description: "用于智能心率采集、50米往返跑等项目的采集手环",
ParameterSchema: mustJSON([]ProductParameterSchemaField{{Key: "bandSize", Label: "尺码", Type: "string", Required: false}, {Key: "firmwareVersion", Label: "固件版本", Type: "string", Required: false}}),
TrackSerialNumber: true,
IsActive: true,
Sort: 30,
},
{
Code: "control_tablet",
Name: "控制平板",
Category: "tablet",
Description: "项目控制与操作使用的平板设备",
ParameterSchema: mustJSON([]ProductParameterSchemaField{{Key: "screenSize", Label: "屏幕尺寸", Type: "string", Required: false}, {Key: "osVersion", Label: "系统版本", Type: "string", Required: false}}),
TrackSerialNumber: true,
IsActive: true,
Sort: 40,
},
{
Code: "collection_gateway",
Name: "采集网关",
Category: "gateway",
Description: "用于设备数据采集与上传的网关",
ParameterSchema: mustJSON([]ProductParameterSchemaField{{Key: "mac", Label: "MAC地址", Type: "string", Required: true}, {Key: "location", Label: "安装位置", Type: "string", Required: false}}),
TrackSerialNumber: true,
IsActive: true,
Sort: 50,
},
{
Code: "display_stand_screen",
Name: "闺蜜机",
Category: "display",
Description: "用于投屏展示的移动显示设备",
ParameterSchema: mustJSON([]ProductParameterSchemaField{{Key: "screenSize", Label: "屏幕尺寸", Type: "string", Required: false}, {Key: "resolution", Label: "分辨率", Type: "string", Required: false}}),
TrackSerialNumber: true,
IsActive: true,
Sort: 60,
},
{
Code: "led_light_strip",
Name: "LED灯带",
Category: "accessory",
Description: "心肺耐力测试配套的LED灯带",
ParameterSchema: mustJSON([]ProductParameterSchemaField{{Key: "length", Label: "长度", Type: "string", Required: false}, {Key: "colorMode", Label: "颜色模式", Type: "string", Required: false}}),
TrackSerialNumber: true,
IsActive: true,
Sort: 70,
},
}
for _, item := range defaults {
var existing ProductDefinition
err := db.Where("code = ?", item.Code).First(&existing).Error
switch {
case err == nil:
existing.Name = item.Name
existing.Category = item.Category
existing.Description = item.Description
existing.ParameterSchema = item.ParameterSchema
existing.TrackSerialNumber = item.TrackSerialNumber
existing.IsActive = item.IsActive
existing.Sort = item.Sort
if err := db.Save(&existing).Error; err != nil {
return err
}
case errors.Is(err, gorm.ErrRecordNotFound):
if err := db.Create(&item).Error; err != nil {
return err
}
default:
return err
}
}
return nil
}