按照前面的二、三、四章节,先创建RPC项目、再定义模型、然后编写RPC、API服务,就可以完成仓储、订单的RPC、API服务开发,其目录结构如下
go-zero-my
|___systemmanage
|___stockmanage
|___ordermanage
一、仓储模型
1、产品模型
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"go-zero-my/common/orm/ent/mixins"
)
type Product struct {
ent.Schema
}
func (Product) Fields() []ent.Field {
return []ent.Field{
field.String("code").Comment("编码").Unique().
SchemaType(map[string]string{
dialect.MySQL: "varchar(32)",
}),
field.String("name").Comment("名称").Unique().
SchemaType(map[string]string{
dialect.MySQL: "varchar(32)",
}),
field.String("uom").Comment("单位").
SchemaType(map[string]string{
dialect.MySQL: "varchar(16)",
}),
field.Float("price").Comment("单价").
SchemaType(map[string]string{
dialect.MySQL: "decimal(6,2)",
}),
}
}
func (Product) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.BaseMixin{},
}
}
func (Product) Edges() []ent.Edge {
return []ent.Edge{
edge.To("inventory", Inventory.Type),
edge.To("transactiondetails", TransactionDetails.Type).StorageKey(edge.Column("product_id")), //另一种方法配置关系字段,在transactiondetails里不需要定义product_id字段
}
}
func (Product) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "wh_product"},
}
}
2、仓库模型
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"go-zero-my/common/orm/ent/mixins"
)
type Warehouse struct {
ent.Schema
}
func (Warehouse) Fields() []ent.Field {
return []ent.Field{
field.String("name").Comment("名称").Unique().
SchemaType(map[string]string{
dialect.MySQL: "varchar(32)",
}),
}
}
func (Warehouse) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.BaseMixin{},
}
}
func (Warehouse) Edges() []ent.Edge {
return []ent.Edge{
edge.To("inventory", Inventory.Type),
edge.To("transactiondetails", TransactionDetails.Type).StorageKey(edge.Column("warehouse_id")), //另一种方法配置关系字段,在transactiondetails里不需要定义warehouse_id字段
}
}
func (Warehouse) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "wh_warehouse"},
}
}
3、库存模型
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"go-zero-my/common/orm/ent/mixins"
)
type Inventory struct {
ent.Schema
}
func (Inventory) Fields() []ent.Field {
return []ent.Field{
field.Float("qty").Comment("数量").
SchemaType(map[string]string{
dialect.MySQL: "decimal(18,2)",
}),
field.Uint64("product_id").Comment("商品ID"),
field.Uint64("warehouse_id").Comment("仓库ID"),
}
}
func (Inventory) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.BaseMixin{},
}
}
func (Inventory) Edges() []ent.Edge {
return []ent.Edge{
edge.From("product", Product.Type).Field("product_id").Ref("inventory").Unique().Required(),
edge.From("warehouse", Warehouse.Type).Field("warehouse_id").Ref("inventory").Unique().Required(),
}
}
func (Inventory) Indexes() []ent.Index {
return []ent.Index{
//index.Fields("product_id", "warehouse_id"), //按字段建立索引
//index.Edges("warehouse", "product"), //按边建立索引
}
}
func (Inventory) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "wh_inventory"},
}
}
4、库存交易明细
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"go-zero-my/common/orm/ent/mixins"
"time"
)
type TransactionDetails struct {
ent.Schema
}
func (TransactionDetails) Fields() []ent.Field {
return []ent.Field{
field.String("number").Comment("单号").
SchemaType(map[string]string{
dialect.MySQL: "varchar(32)",
}),
field.Enum("bill_type").Comment("单据类型").
Values("delivery", "scrap", "receipt"),
field.Float("qty").Comment("数量").
SchemaType(map[string]string{
dialect.MySQL: "decimal(18,2)",
}),
field.Time("tran_time").
Comment("交易时间").
Default(time.Now),
}
}
func (TransactionDetails) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.BaseMixin{},
}
}
func (TransactionDetails) Edges() []ent.Edge {
return []ent.Edge{
edge.From("product", Product.Type).Ref("transactiondetails").Unique().Required(),
edge.From("warehouse", Warehouse.Type).Ref("transactiondetails").Unique().Required(),
}
}
func (TransactionDetails) Indexes() []ent.Index {
return []ent.Index{}
}
func (TransactionDetails) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "wh_transactiondetails"},
}
}
二、订单模型
1、客户模型
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"go-zero-my/common/orm/ent/mixins"
)
type Customer struct {
ent.Schema
}
func (Customer) Fields() []ent.Field {
return []ent.Field{
field.String("name").Comment("名称").Unique().
SchemaType(map[string]string{
dialect.MySQL: "varchar(32)",
}),
}
}
func (Customer) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.BaseMixin{},
}
}
func (Customer) Edges() []ent.Edge {
return []ent.Edge{
edge.To("order", Order.Type),
}
}
func (Customer) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "ord_customer"},
}
}
2、订单模型
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"go-zero-my/common/orm/ent/mixins"
"time"
)
type Order struct {
ent.Schema
}
func (Order) Fields() []ent.Field {
return []ent.Field{
field.Time("order_date").
Comment("订单日期").
Default(time.Now),
field.String("order_no").Comment("订单编号").Unique().
SchemaType(map[string]string{
dialect.MySQL: "varchar(32)",
}),
field.Uint64("customer_id").Comment("客户ID"),
field.String("remark").Comment("备注").Optional().
SchemaType(map[string]string{
dialect.MySQL: "varchar(200)",
}),
}
}
func (Order) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.BaseMixin{},
}
}
func (Order) Edges() []ent.Edge {
return []ent.Edge{
edge.From("customer", Customer.Type).Field("customer_id").Ref("order").Unique().Required(),
edge.To("orderitem", OrderItem.Type),
}
}
func (Order) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "ord_order"},
}
}
3、订单明细模型
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
"go-zero-my/common/orm/ent/mixins"
)
type OrderItem struct {
ent.Schema
}
func (OrderItem) Fields() []ent.Field {
return []ent.Field{
field.Uint64("order_id").Comment("订单ID"),
field.Uint64("product_id").Comment("商品ID"),
field.Float("qty").Comment("数量").
SchemaType(map[string]string{
dialect.MySQL: "decimal(18,2)",
}),
field.Float("price").Comment("单价").
SchemaType(map[string]string{
dialect.MySQL: "decimal(6,2)",
}),
}
}
func (OrderItem) Mixin() []ent.Mixin {
return []ent.Mixin{
mixins.BaseMixin{},
}
}
func (OrderItem) Edges() []ent.Edge {
return []ent.Edge{
edge.From("order", Order.Type).Field("order_id").Ref("orderitem").Unique().Required(),
}
}
func (OrderItem) Indexes() []ent.Index {
return []ent.Index{
index.Fields("order_id", "product_id").Unique(), //按字段建立索引
}
}
func (OrderItem) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "ord_orderitem"},
}
}
三、项目重构
将ent从rpc项目中提出来,将所有的模型放在一起,这样订单明细与产品就可以建关系
1、建立ent目录
在项目根目录(go-zero-my)下执行如下命令建立ent目录,注意,Example首字母要大写
go run -mod=mod entgo.io/ent/cmd/ent new Example
建立后删除ent\schema下的 example.go文件
2、将三个RPC的模型复制到ent\schema目录
3、在订单明细、产品模型,增加边
func (OrderItem) Edges() []ent.Edge {
return []ent.Edge{
edge.From("order", Order.Type).Field("order_id").Ref("orderitem").Unique().Required(),
edge.From("product", Product.Type).Field("product_id").Ref("orderitem").Unique().Required(),
}
}
func (Product) Edges() []ent.Edge {
return []ent.Edge{
edge.To("inventory", Inventory.Type),
edge.To("transactiondetails", TransactionDetails.Type).StorageKey(edge.Column("product_id")), //另一种方法配置关系字段,在transactiondetails里不需要定义product_id字段
edge.To("orderitem", OrderItem.Type),
}
}
4、产生ent代码
go run -mod=mod entgo.io/ent/cmd/ent generate ./ent/schema
5、产生ent模板代码
将其中一个rpc\ent下的template复制到go-zero-my\ent目录,然后执行如下命令
go run -mod=mod entgo.io/ent/cmd/ent generate --template glob="./ent/template/*.tmpl" ./ent/schema
6、删除各rpc下ent目录,然后修改相应文件的ent引用路径
7、将syndb.go移到根目录,删除各rpc下的syndb.go文件
修改import路径
然后在根目录下(go-zero-my)执行数据库迁移 go run syndb.go
8、重构后目录结构如下
9、生成proto文件和logic代码的命令变化
--schema参数改为根目录下的ent,命令执行目录还是在rpc目录下
goctls rpc ent --schema=../../ent/schema --service_name=order --project_name=order --model=Customer --group=customer --proto_out=./desc/customer.proto --style=gozero
10、其他按照二、三、四章节完成服务的编写即可