feat: add producer account management
This commit is contained in:
@@ -20,7 +20,7 @@ func TestInitPlatformAccessSeedsRootRole(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "platform_role" WHERE role_code = $1 ORDER BY "platform_role"."id" LIMIT $2`)).
|
||||
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "platform_role" WHERE role_code = $1 AND "platform_role"."deleted_at" IS NULL ORDER BY "platform_role"."id" LIMIT $2`)).
|
||||
WithArgs("root", 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "status", "role_code", "name", "location_scope", "is_system"}).
|
||||
AddRow(uint64(1), "root-role", 1, "root", "Root", "precise", true))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package common
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -408,6 +408,7 @@ var relationIdentityModels = map[string]any{
|
||||
"user_account_id": &models.UserAccount{},
|
||||
"staff_account_id": &models.StaffAccount{},
|
||||
"product_type_id": &models.ProductType{},
|
||||
"producer_account_id": &models.ProducerAccount{},
|
||||
"product_info_id": &models.ProductInfo{},
|
||||
"warehouse_id": &models.ProductWarehouse{},
|
||||
"ec_category_id": &models.EcCategory{},
|
||||
@@ -419,7 +420,7 @@ var relationIdentityModels = map[string]any{
|
||||
"gasorder_track_id": &models.GasorderTrack{},
|
||||
"platform_role_id": &models.PlatformRole{},
|
||||
"wallet_basic_id": &models.WalletBasic{},
|
||||
"payment_order_id": &models.PaymentOrder{},
|
||||
"payment_order_id": &models.PaymentOrder{},
|
||||
"wallet_bank_id": &models.WalletBank{},
|
||||
"related_record_id": &models.WalletRecord{},
|
||||
}
|
||||
|
||||
@@ -46,9 +46,10 @@ var PlatformMenus = [][]Menu{
|
||||
},
|
||||
{
|
||||
{Identity: "device", GroupCode: "device", Name: "智能气阀管理", Icon: "icon-common", Path: "/product", SortNo: 60, Status: common.StatusEnable},
|
||||
{Identity: "product_type", ParentIdentity: "device", GroupCode: "device", Name: "类型管理", Path: "/product/product-type", SortNo: 1, Status: common.StatusEnable},
|
||||
{Identity: "product_warehouse", ParentIdentity: "device", GroupCode: "device", Name: "库房管理", Path: "/product/warehouse", SortNo: 2, Status: common.StatusEnable},
|
||||
{Identity: "product_info", ParentIdentity: "device", GroupCode: "device", Name: "智能气阀管理", Path: "/product/product-info", SortNo: 3, Status: common.StatusEnable},
|
||||
{Identity: "producer_account", ParentIdentity: "device", GroupCode: "device", Name: "生产商管理", Path: "/product/producers", SortNo: 1, Status: common.StatusEnable},
|
||||
{Identity: "product_type", ParentIdentity: "device", GroupCode: "device", Name: "类型管理", Path: "/product/product-type", SortNo: 2, Status: common.StatusEnable},
|
||||
{Identity: "product_warehouse", ParentIdentity: "device", GroupCode: "device", Name: "库房管理", Path: "/product/warehouse", SortNo: 3, Status: common.StatusEnable},
|
||||
{Identity: "product_info", ParentIdentity: "device", GroupCode: "device", Name: "智能气阀管理", Path: "/product/product-info", SortNo: 4, Status: common.StatusEnable},
|
||||
},
|
||||
{
|
||||
{Identity: "gasorder", GroupCode: "gasorder", Name: "气体配送订单管理", Icon: "icon-list", Path: "/gasorder", SortNo: 70, Status: common.StatusEnable},
|
||||
|
||||
108
backend/api/internal/logic/platform/product/producer.go
Normal file
108
backend/api/internal/logic/platform/product/producer.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package product
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
|
||||
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type producerAccountCreateRequest struct {
|
||||
ProducerCode string `json:"producer_code" binding:"required,max=64"`
|
||||
Name string `json:"name" binding:"required,max=128"`
|
||||
CreditCode string `json:"credit_code" binding:"max=64"`
|
||||
Principal string `json:"principal" binding:"max=64"`
|
||||
Phone string `json:"phone" binding:"max=32"`
|
||||
Address string `json:"address" binding:"max=255"`
|
||||
Username string `json:"username" binding:"required,max=64"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
DisplayName string `json:"display_name" binding:"max=64"`
|
||||
RoleCode string `json:"role_code" binding:"max=64"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type producerAccountUpdateRequest struct {
|
||||
Name string `json:"name" binding:"required,max=128"`
|
||||
CreditCode string `json:"credit_code" binding:"max=64"`
|
||||
Principal string `json:"principal" binding:"max=64"`
|
||||
Phone string `json:"phone" binding:"max=32"`
|
||||
Address string `json:"address" binding:"max=255"`
|
||||
DisplayName string `json:"display_name" binding:"max=64"`
|
||||
RoleCode string `json:"role_code" binding:"max=64"`
|
||||
Password string `json:"password"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func ListProducerAccount(ctx *gin.Context) { common.ListResource(ctx, &models.ProducerAccount{}) }
|
||||
func GetProducerAccount(ctx *gin.Context) { common.GetResource(ctx, &models.ProducerAccount{}) }
|
||||
|
||||
func CreateProducerAccount(ctx *gin.Context) {
|
||||
var request producerAccountCreateRequest
|
||||
if ctx.ShouldBindJSON(&request) != nil || !common.IsValidAccountPassword(request.Password) {
|
||||
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
hash, err := common.PasswordHash(request.Password)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
roleCode := strings.TrimSpace(request.RoleCode)
|
||||
if roleCode == "" {
|
||||
roleCode = "admin"
|
||||
}
|
||||
data := models.ProducerAccount{Entity: common.NewEntity(common.StatusEnable), ProducerCode: strings.TrimSpace(request.ProducerCode), Name: strings.TrimSpace(request.Name), CreditCode: strings.TrimSpace(request.CreditCode), Principal: strings.TrimSpace(request.Principal), Phone: strings.TrimSpace(request.Phone), Address: strings.TrimSpace(request.Address), Username: strings.TrimSpace(request.Username), DisplayName: strings.TrimSpace(request.DisplayName), PasswordHash: hash, RoleCode: roleCode, Remark: request.Remark}
|
||||
if err := impl.DBService.Create(&data).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
common.RespondCreatedResource(ctx, data)
|
||||
}
|
||||
|
||||
func UpdateProducerAccount(ctx *gin.Context) {
|
||||
var request producerAccountUpdateRequest
|
||||
if ctx.ShouldBindJSON(&request) != nil {
|
||||
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
values := gin.H{"name": strings.TrimSpace(request.Name), "credit_code": strings.TrimSpace(request.CreditCode), "principal": strings.TrimSpace(request.Principal), "phone": strings.TrimSpace(request.Phone), "address": strings.TrimSpace(request.Address), "display_name": strings.TrimSpace(request.DisplayName), "role_code": strings.TrimSpace(request.RoleCode), "remark": request.Remark}
|
||||
if request.Password != "" {
|
||||
if !common.IsValidAccountPassword(request.Password) {
|
||||
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
hash, err := common.PasswordHash(request.Password)
|
||||
if err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
values["password_hash"] = hash
|
||||
}
|
||||
common.UpdateAllowedByIdentity(ctx, &models.ProducerAccount{}, values, []string{"name", "credit_code", "principal", "phone", "address", "display_name", "role_code", "remark", "password_hash"})
|
||||
}
|
||||
|
||||
func DeleteProducerAccount(ctx *gin.Context) {
|
||||
var producer models.ProducerAccount
|
||||
if err := impl.DBService.Where("identity = ?", ctx.Param("identity")).First(&producer).Error; err != nil {
|
||||
common.RespondRecordError(ctx, err)
|
||||
return
|
||||
}
|
||||
var references int64
|
||||
if err := impl.DBService.Unscoped().Model(&models.ProductInfo{}).Where("producer_account_id = ?", producer.ID).Count(&references).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
if references > 0 {
|
||||
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if err := impl.DBService.Delete(&producer).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(ctx, gin.H{"deleted": true})
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func createProductInfo(ctx *gin.Context, fields []string, relations []common.Res
|
||||
delete(values, "reason")
|
||||
delete(values, "remark")
|
||||
data := models.ProductInfo{Entity: common.NewEntity(common.StatusDisable), ProductStatus: common.StatusPending, Params: "{}"}
|
||||
if err := decodeValues(values, &data); err != nil || data.Code == "" || data.Name == "" || data.ProducedAt.IsZero() || !validProductOwnership(data) {
|
||||
if err := decodeValues(values, &data); err != nil || data.Code == "" || data.Name == "" || !validProductProducer(data) || data.ProducedAt.IsZero() || !validProductOwnership(data) {
|
||||
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
@@ -91,7 +91,7 @@ func updateProductInfo(ctx *gin.Context, fields []string, relations []common.Res
|
||||
delete(values, "code")
|
||||
}
|
||||
preview := current
|
||||
if err := decodeValues(values, &preview); err != nil || !validProductOwnership(preview) {
|
||||
if err := decodeValues(values, &preview); err != nil || !validProductProducer(preview) || !validProductOwnership(preview) {
|
||||
return errors.New("product can have at most one current owner")
|
||||
}
|
||||
ownershipChanged := ownershipValuesChanged(current, values)
|
||||
@@ -379,6 +379,10 @@ func validProductOwnership(product models.ProductInfo) bool {
|
||||
return count <= 1
|
||||
}
|
||||
|
||||
func validProductProducer(product models.ProductInfo) bool {
|
||||
return product.ProducerAccountID != 0
|
||||
}
|
||||
|
||||
func ownershipValuesChanged(current models.ProductInfo, values map[string]any) bool {
|
||||
for key, old := range map[string]uint64{
|
||||
"warehouse_id": current.WarehouseID, "gas_basic_id": current.GasBasicID,
|
||||
|
||||
@@ -85,3 +85,12 @@ func TestProductHasAtMostOneCurrentOwner(t *testing.T) {
|
||||
t.Fatal("conflicting warehouse and user owners were accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProductRequiresProducer(t *testing.T) {
|
||||
if validProductProducer(models.ProductInfo{}) {
|
||||
t.Fatal("product without producer was accepted")
|
||||
}
|
||||
if !validProductProducer(models.ProductInfo{ProducerAccountID: 1}) {
|
||||
t.Fatal("product with producer was rejected")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package platform
|
||||
package platform
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
@@ -81,7 +81,7 @@ func ExpectedResources() []ResourceContract {
|
||||
resourceContract("delivery", "delivery_basic", Writable, "list"), resourceContract("delivery", "delivery_account", Writable, "list"),
|
||||
resourceContract("staff", "staff_account", Writable, "list"), resourceContract("staff", "staff_credential", Writable, "list"),
|
||||
resourceContract("user", "user_account", Writable, "list"), resourceContract("user", "user_address", Writable, "list"), resourceContract("user", "user_service_relation", Writable, "list"),
|
||||
resourceContract("product", "product_type", Editable, "list"), resourceContract("product", "product_warehouse", Editable, "list"), resourceContract("product", "product_info", Editable, "list"), resourceContract("product", "product_repair", Editable, "list"), resourceContract("product", "product_owner", ReadOnly, "list"),
|
||||
resourceContract("product", "producer_account", Writable, "list"), resourceContract("product", "product_type", Editable, "list"), resourceContract("product", "product_warehouse", Editable, "list"), resourceContract("product", "product_info", Editable, "list"), resourceContract("product", "product_repair", Editable, "list"), resourceContract("product", "product_owner", ReadOnly, "list"),
|
||||
resourceContract("ec", "ec_category", Writable, "list"), resourceContract("ec", "ec_product", Writable, "list"), resourceContract("ec", "ec_product_attribute", Writable, "list"), resourceContract("ec", "ec_product_image", Writable, "list"), resourceContract("ec", "ec_cart", ReadOnly, "list"), resourceContract("ec", "ec_order", ReadOnly, "list"), resourceContract("ec", "ec_order_item", ReadOnly, "list"), resourceContract("ec", "ec_review", ReadOnly, "list"),
|
||||
resourceContract("gasorder", "gasorder_contract", Managed, "list"), resourceContract("gasorder", "gasorder_contract_product", AppendOnly, "list"), resourceContract("gasorder", "gasorder_contract_revision", ReadOnly, "list"),
|
||||
resourceContract("gasorder", "gasorder_basic", AppendOnly, "list"), resourceContract("gasorder", "gasorder_item", ReadOnly, "list"), resourceContract("gasorder", "gasorder_assign", ReadOnly, "list"), resourceContract("gasorder", "gasorder_status", ReadOnly, "list"),
|
||||
|
||||
@@ -5,15 +5,17 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Entity 是所有主表共享字段。id 是数据库自增主键,identity 是应用生成的 UUID V7 业务标识。
|
||||
type Entity struct {
|
||||
ID uint64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 数据库自增主键
|
||||
Identity string `gorm:"column:identity;type:varchar(36);not null;uniqueIndex" json:"identity"` // UUID V7 业务标识
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;index" json:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamptz;not null" json:"updated_at"` // 更新时间
|
||||
Status int `gorm:"column:status;not null;default:0;index" json:"status"` // 通用记录状态
|
||||
ID uint64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 数据库自增主键
|
||||
Identity string `gorm:"column:identity;type:varchar(36);not null;uniqueIndex" json:"identity"` // UUID V7 业务标识
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;index" json:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamptz;not null" json:"updated_at"` // 更新时间
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"` // 软删除时间,非空表示记录已删除但仍保留在数据库中
|
||||
Status int `gorm:"column:status;not null;default:0;index" json:"status"` // 通用记录状态
|
||||
}
|
||||
|
||||
// NewIdentity 生成时间有序的 UUID V7 字符串,生成失败属于不可恢复的运行时错误。
|
||||
|
||||
21
backend/api/internal/models/entity_test.go
Normal file
21
backend/api/internal/models/entity_test.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestEntityDeletedAtEnablesSoftDelete(t *testing.T) {
|
||||
field, ok := reflect.TypeOf(Entity{}).FieldByName("DeletedAt")
|
||||
if !ok {
|
||||
t.Fatal("Entity 缺少 DeletedAt 软删除字段")
|
||||
}
|
||||
if field.Type != reflect.TypeOf(gorm.DeletedAt{}) {
|
||||
t.Fatalf("DeletedAt 类型为 %v,期望 gorm.DeletedAt", field.Type)
|
||||
}
|
||||
if got := field.Tag.Get("gorm"); got != "index" {
|
||||
t.Fatalf("DeletedAt gorm 标签为 %q,期望 %q", got, "index")
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ func TestPlatformModelTableNames(t *testing.T) {
|
||||
{name: "account", table: &PlatformAccount{}, want: "platform_account"},
|
||||
{name: "role", table: &PlatformRole{}, want: "platform_role"},
|
||||
{name: "role menu", table: &PlatformRoleMenu{}, want: "platform_role_menu"},
|
||||
{name: "producer account", table: &ProducerAccount{}, want: "producer_account"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
22
backend/api/internal/models/producer_account.go
Normal file
22
backend/api/internal/models/producer_account.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package models
|
||||
|
||||
import "git.apinb.com/bsm-sdk/core/database"
|
||||
|
||||
// ProducerAccount 对应 producer_account,保存可登录的生产商企业主数据。
|
||||
type ProducerAccount struct {
|
||||
Entity // 公共实体字段
|
||||
ProducerCode string `gorm:"column:producer_code;type:varchar(64);not null;uniqueIndex" json:"producer_code"` // 生产商编码
|
||||
Name string `gorm:"column:name;type:varchar(128);not null" json:"name"` // 生产商名称
|
||||
CreditCode string `gorm:"column:credit_code;type:varchar(64);not null;default:'';index" json:"credit_code"` // 统一社会信用代码
|
||||
Principal string `gorm:"column:principal;type:varchar(64);not null;default:''" json:"principal"` // 企业负责人
|
||||
Phone string `gorm:"column:phone;type:varchar(32);not null;default:''" json:"phone"` // 联系电话
|
||||
Address string `gorm:"column:address;type:varchar(255);not null;default:''" json:"address"` // 企业地址
|
||||
Username string `gorm:"column:username;type:varchar(64);not null;uniqueIndex" json:"username"` // 登录用户名
|
||||
DisplayName string `gorm:"column:display_name;type:varchar(64);not null;default:''" json:"display_name"` // 登录展示名称
|
||||
PasswordHash string `gorm:"column:password_hash;type:varchar(255);not null" json:"-"` // 登录密码哈希
|
||||
RoleCode string `gorm:"column:role_code;type:varchar(64);not null;default:'admin'" json:"role_code"` // 生产商端角色编码
|
||||
Remark string `gorm:"column:remark;type:text;not null;default:''" json:"remark"` // 备注
|
||||
}
|
||||
|
||||
func init() { database.AppendMigrate(&ProducerAccount{}) }
|
||||
func (table *ProducerAccount) TableName() string { return "producer_account" }
|
||||
@@ -8,18 +8,19 @@ import (
|
||||
|
||||
// ProductInfo 对应 product_info,保存一物一码的实体产品档案。
|
||||
type ProductInfo struct {
|
||||
Entity // 公共实体字段
|
||||
ProductStatus int `gorm:"column:product_status;not null;default:10;index" json:"product_status"` // 产品业务状态
|
||||
Code string `gorm:"column:code;type:varchar(64);not null;uniqueIndex" json:"code"` // 产品唯一标识
|
||||
Name string `gorm:"column:name;type:varchar(128);not null" json:"name"` // 产品名称
|
||||
ProductTypeID uint64 `gorm:"column:product_type_id;not null;index" json:"product_type_id"` // 产品类型自增主键
|
||||
Params string `gorm:"column:params;type:text;not null;default:'{}'" json:"params"` // 产品参数 JSON 对象文本
|
||||
WarehouseID uint64 `gorm:"column:warehouse_id;not null;default:0;index" json:"warehouse_id"` // 当前实际库房自增主键
|
||||
GasBasicID uint64 `gorm:"column:gas_basic_id;not null;default:0;index" json:"gas_basic_id"` // 当前归属气站自增主键
|
||||
DeliveryBasicID uint64 `gorm:"column:delivery_basic_id;not null;default:0;index" json:"delivery_basic_id"` // 当前归属配送站自增主键
|
||||
UserAccountID uint64 `gorm:"column:user_account_id;not null;default:0;index" json:"user_account_id"` // 当前归属用户自增主键
|
||||
ProducedAt time.Time `gorm:"column:produced_at;type:timestamptz;not null" json:"produced_at"` // 生产时间
|
||||
EnabledAt *time.Time `gorm:"column:enabled_at;type:timestamptz" json:"enabled_at"` // 首次启用时间
|
||||
Entity // 公共实体字段
|
||||
ProductStatus int `gorm:"column:product_status;not null;default:10;index" json:"product_status"` // 产品业务状态
|
||||
Code string `gorm:"column:code;type:varchar(64);not null;uniqueIndex" json:"code"` // 产品唯一标识
|
||||
Name string `gorm:"column:name;type:varchar(128);not null" json:"name"` // 产品名称
|
||||
ProducerAccountID uint64 `gorm:"column:producer_account_id;not null;default:0;index" json:"producer_account_id"` // 生产商自增主键;历史数据迁移前可为 0,新建和编辑必须关联有效生产商
|
||||
ProductTypeID uint64 `gorm:"column:product_type_id;not null;index" json:"product_type_id"` // 产品类型自增主键
|
||||
Params string `gorm:"column:params;type:text;not null;default:'{}'" json:"params"` // 产品参数 JSON 对象文本
|
||||
WarehouseID uint64 `gorm:"column:warehouse_id;not null;default:0;index" json:"warehouse_id"` // 当前实际库房自增主键
|
||||
GasBasicID uint64 `gorm:"column:gas_basic_id;not null;default:0;index" json:"gas_basic_id"` // 当前归属气站自增主键
|
||||
DeliveryBasicID uint64 `gorm:"column:delivery_basic_id;not null;default:0;index" json:"delivery_basic_id"` // 当前归属配送站自增主键
|
||||
UserAccountID uint64 `gorm:"column:user_account_id;not null;default:0;index" json:"user_account_id"` // 当前归属用户自增主键
|
||||
ProducedAt time.Time `gorm:"column:produced_at;type:timestamptz;not null" json:"produced_at"` // 生产时间
|
||||
EnabledAt *time.Time `gorm:"column:enabled_at;type:timestamptz" json:"enabled_at"` // 首次启用时间
|
||||
}
|
||||
|
||||
func init() { database.AppendMigrate(&ProductInfo{}) }
|
||||
|
||||
@@ -107,10 +107,19 @@ func registerGasorderRoute(group *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
func registerProductRoute(group *gin.RouterGroup) {
|
||||
producer := group.Group("/producer_account")
|
||||
producer.GET("", product.ListProducerAccount)
|
||||
producer.POST("", product.CreateProducerAccount)
|
||||
producer.GET("/:identity", product.GetProducerAccount)
|
||||
producer.PUT("/:identity", product.UpdateProducerAccount)
|
||||
producer.PATCH("/:identity/status", func(ctx *gin.Context) { common.UpdateRecordStatus(ctx, &models.ProducerAccount{}) })
|
||||
producer.DELETE("/:identity", product.DeleteProducerAccount)
|
||||
|
||||
registerRestrictedNoDeleteResource(group, "/product_type", &models.ProductType{}, []string{"code", "name"})
|
||||
registerRestrictedNoDeleteResource(group, "/product_warehouse", &models.ProductWarehouse{}, []string{"code", "name", "address", "manager", "phone"})
|
||||
|
||||
infoRelations := []common.ResourceRelation{
|
||||
requiredRelation("producer_account_identity", "producer_account_id", &models.ProducerAccount{}),
|
||||
requiredRelation("product_type_identity", "product_type_id", &models.ProductType{}),
|
||||
optionalRelation("warehouse_identity", "warehouse_id", &models.ProductWarehouse{}),
|
||||
optionalRelation("gas_basic_identity", "gas_basic_id", &models.GasBasic{}),
|
||||
|
||||
@@ -166,6 +166,10 @@ func TestPlatformProductCommerceAndDeliveryRoutesFollowTheirContracts(t *testing
|
||||
assertRouteMethods(t, routes, path+"/:identity/status", http.MethodPatch)
|
||||
assertNoRouteMethods(t, routes, path+"/:identity", http.MethodDelete)
|
||||
}
|
||||
producer := "/heqi/platform/v1/producer_account"
|
||||
assertRouteMethods(t, routes, producer, http.MethodGet, http.MethodPost)
|
||||
assertRouteMethods(t, routes, producer+"/:identity", http.MethodGet, http.MethodPut, http.MethodDelete)
|
||||
assertRouteMethods(t, routes, producer+"/:identity/status", http.MethodPatch)
|
||||
owner := "/heqi/platform/v1/product_owner"
|
||||
assertRouteMethods(t, routes, owner, http.MethodGet)
|
||||
assertNoRouteMethods(t, routes, owner, http.MethodPost)
|
||||
|
||||
Reference in New Issue
Block a user