0e42f0e417
- 项目目录结构:backend/ deploy/ schema/ migrations/ - 数据库 Schema:所有建表 SQL,含 hotel_id 多租户隔离 - Go 后端:config、model、handler、service、middleware、router - 认证:账号密码登录 + JWT(Access + Refresh Token) - 许可证:HMAC-SHA256 激活码生成 + 设备绑定验证 - 业务模块:商品、仓库、往来单位、入库、出库、库存、盘点 - 库存事务:入库/出库审核时原子更新库存 + 流水记录 - 数据导入:Excel/CSV 批量导入商品、往来单位 - Docker Compose:本地 MySQL + Adminer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
51 lines
970 B
Go
51 lines
970 B
Go
package model
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// JSON 类型,用于 custom_fields
|
|
type JSON map[string]interface{}
|
|
|
|
func (j JSON) Value() (driver.Value, error) {
|
|
if j == nil {
|
|
return nil, nil
|
|
}
|
|
b, err := json.Marshal(j)
|
|
return string(b), err
|
|
}
|
|
|
|
func (j *JSON) Scan(value interface{}) error {
|
|
if value == nil {
|
|
*j = nil
|
|
return nil
|
|
}
|
|
var bytes []byte
|
|
switch v := value.(type) {
|
|
case string:
|
|
bytes = []byte(v)
|
|
case []byte:
|
|
bytes = v
|
|
default:
|
|
return fmt.Errorf("cannot scan type %T into JSON", value)
|
|
}
|
|
return json.Unmarshal(bytes, j)
|
|
}
|
|
|
|
// Base 公共字段
|
|
type Base struct {
|
|
ID uint64 `gorm:"primaryKey;autoIncrement" json:"id"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt *time.Time `gorm:"index" json:"-"`
|
|
}
|
|
|
|
// TenantBase 含租户隔离的公共字段
|
|
type TenantBase struct {
|
|
Base
|
|
HotelID uint64 `gorm:"not null;index" json:"hotel_id"`
|
|
}
|