ソースを参照

1、运维管理模块增加导出功能;
2、添加交付项目管理、交付项目事件管理相关Dao、Model

程健 2 週間 前
コミット
bd378d4cac
23 ファイル変更2792 行追加7 行削除
  1. 500 0
      opms_parent/app/dao/opsdev/internal/ops_delivery_project.go
  2. 497 0
      opms_parent/app/dao/opsdev/internal/ops_delivery_project_event.go
  3. 464 0
      opms_parent/app/dao/opsdev/internal/ops_delivery_project_event_attachment.go
  4. 458 0
      opms_parent/app/dao/opsdev/internal/ops_delivery_project_event_record.go
  5. 2 2
      opms_parent/app/dao/opsdev/internal/ops_operation_event.go
  6. 36 0
      opms_parent/app/dao/opsdev/ops_delivery_project.go
  7. 36 0
      opms_parent/app/dao/opsdev/ops_delivery_project_event.go
  8. 36 0
      opms_parent/app/dao/opsdev/ops_delivery_project_event_attachment.go
  9. 36 0
      opms_parent/app/dao/opsdev/ops_delivery_project_event_record.go
  10. 26 0
      opms_parent/app/handler/opsdev/operation.go
  11. 49 0
      opms_parent/app/model/opsdev/internal/ops_delivery_project.go
  12. 48 0
      opms_parent/app/model/opsdev/internal/ops_delivery_project_event.go
  13. 37 0
      opms_parent/app/model/opsdev/internal/ops_delivery_project_event_attachment.go
  14. 35 0
      opms_parent/app/model/opsdev/internal/ops_delivery_project_event_record.go
  15. 2 2
      opms_parent/app/model/opsdev/internal/ops_operation_event.go
  16. 42 0
      opms_parent/app/model/opsdev/operation.go
  17. 14 0
      opms_parent/app/model/opsdev/ops_delivery_project.go
  18. 14 0
      opms_parent/app/model/opsdev/ops_delivery_project_event.go
  19. 14 0
      opms_parent/app/model/opsdev/ops_delivery_project_event_attachment.go
  20. 14 0
      opms_parent/app/model/opsdev/ops_delivery_project_event_record.go
  21. 15 1
      opms_parent/app/service/base.go
  22. 312 2
      opms_parent/app/service/opsdev/operation.go
  23. 105 0
      opms_storage/.idea/workspace.xml

+ 500 - 0
opms_parent/app/dao/opsdev/internal/ops_delivery_project.go

@@ -0,0 +1,500 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"dashoo.cn/opms_parent/app/model/opsdev"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+)
+
+// OpsDeliveryProjectDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type OpsDeliveryProjectDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns opsDeliveryProjectColumns
+}
+
+// OpsDeliveryProjectColumns defines and stores column names for table ops_delivery_project.
+type opsDeliveryProjectColumns struct {
+	Id                     string // 主键
+	ProjectName            string // 项目名称
+	ProjectStatus          string // 项目状态(10 待交付 20 交付中 30 暂停 40交付完成 50 验收 90作废)
+	ContractId             string // 合同ID
+	ContractNo             string // 合同编号
+	CustId                 string // 客户ID
+	CustName               string // 客户名称
+	ProductLine            string // 产品线(10 Biobank 20 LIMS 30 CellLbank 40MCS )
+	DeliveryUserId         string // 交付负责人ID
+	DeliveryUserName       string // 交付负责人
+	SalesUserId            string // 销售ID
+	SalesUserName          string // 销售
+	DeliveryNode           string // 交付节点(10内部启动会 15 外部启动会 20 制定计划 30项目实施 40完成部署 50试运行 60交付完成)
+	InternalKickoffTime    string // 内部启动会时间
+	ExternalKickoffTime    string // 外部启动会时间
+	DeliveryPlanSubmitTime string // 交付计划提交时间
+	DeploymentTime         string // 部署时间
+	TrialRunTime           string // 试运行时间
+	GoLiveTime             string // 上线时间
+	Attribute1             string // 增强字段1
+	Attribute2             string // 增强字段2
+	Attribute3             string // 增强字段3
+	Attribute4             string // 增强字段4
+	Attribute5             string // 增强字段5
+	Attribute6             string // 增强字段6
+	Attribute7             string // 增强字段7
+	Attribute8             string // 增强字段8
+	Attribute9             string // 增强字段9
+	Remark                 string // 备注
+	CreatedBy              string // 创建者
+	CreatedName            string // 创建人
+	CreatedTime            string // 创建时间
+	UpdatedBy              string // 更新者
+	UpdatedName            string // 更新人
+	UpdatedTime            string // 更新时间
+	DeletedTime            string // 删除时间
+}
+
+var (
+	// OpsDeliveryProject is globally public accessible object for table ops_delivery_project operations.
+	OpsDeliveryProject = OpsDeliveryProjectDao{
+		M:     g.DB("default").Model("ops_delivery_project").Safe(),
+		DB:    g.DB("default"),
+		Table: "ops_delivery_project",
+		Columns: opsDeliveryProjectColumns{
+			Id:                     "id",
+			ProjectName:            "project_name",
+			ProjectStatus:          "project_status",
+			ContractId:             "contract_id",
+			ContractNo:             "contract_no",
+			CustId:                 "cust_id",
+			CustName:               "cust_name",
+			ProductLine:            "product_line",
+			DeliveryUserId:         "delivery_user_id",
+			DeliveryUserName:       "delivery_user_name",
+			SalesUserId:            "sales_user_id",
+			SalesUserName:          "sales_user_name",
+			DeliveryNode:           "delivery_node",
+			InternalKickoffTime:    "internal_kickoff_time",
+			ExternalKickoffTime:    "external_kickoff_time",
+			DeliveryPlanSubmitTime: "delivery_plan_submit_time",
+			DeploymentTime:         "deployment_time",
+			TrialRunTime:           "trial_run_time",
+			GoLiveTime:             "go_live_time",
+			Attribute1:             "attribute1",
+			Attribute2:             "attribute2",
+			Attribute3:             "attribute3",
+			Attribute4:             "attribute4",
+			Attribute5:             "attribute5",
+			Attribute6:             "attribute6",
+			Attribute7:             "attribute7",
+			Attribute8:             "attribute8",
+			Attribute9:             "attribute9",
+			Remark:                 "remark",
+			CreatedBy:              "created_by",
+			CreatedName:            "created_name",
+			CreatedTime:            "created_time",
+			UpdatedBy:              "updated_by",
+			UpdatedName:            "updated_name",
+			UpdatedTime:            "updated_time",
+			DeletedTime:            "deleted_time",
+		},
+	}
+)
+
+func NewOpsDeliveryProjectDao(tenant string) OpsDeliveryProjectDao {
+	var dao OpsDeliveryProjectDao
+	dao = OpsDeliveryProjectDao{
+		M:     g.DB(tenant).Model("ops_delivery_project").Safe(),
+		DB:    g.DB(tenant),
+		Table: "ops_delivery_project",
+		Columns: opsDeliveryProjectColumns{
+			Id:                     "id",
+			ProjectName:            "project_name",
+			ProjectStatus:          "project_status",
+			ContractId:             "contract_id",
+			ContractNo:             "contract_no",
+			CustId:                 "cust_id",
+			CustName:               "cust_name",
+			ProductLine:            "product_line",
+			DeliveryUserId:         "delivery_user_id",
+			DeliveryUserName:       "delivery_user_name",
+			SalesUserId:            "sales_user_id",
+			SalesUserName:          "sales_user_name",
+			DeliveryNode:           "delivery_node",
+			InternalKickoffTime:    "internal_kickoff_time",
+			ExternalKickoffTime:    "external_kickoff_time",
+			DeliveryPlanSubmitTime: "delivery_plan_submit_time",
+			DeploymentTime:         "deployment_time",
+			TrialRunTime:           "trial_run_time",
+			GoLiveTime:             "go_live_time",
+			Attribute1:             "attribute1",
+			Attribute2:             "attribute2",
+			Attribute3:             "attribute3",
+			Attribute4:             "attribute4",
+			Attribute5:             "attribute5",
+			Attribute6:             "attribute6",
+			Attribute7:             "attribute7",
+			Attribute8:             "attribute8",
+			Attribute9:             "attribute9",
+			Remark:                 "remark",
+			CreatedBy:              "created_by",
+			CreatedName:            "created_name",
+			CreatedTime:            "created_time",
+			UpdatedBy:              "updated_by",
+			UpdatedName:            "updated_name",
+			UpdatedTime:            "updated_time",
+			DeletedTime:            "deleted_time",
+		},
+	}
+	return dao
+}
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *OpsDeliveryProjectDao) Ctx(ctx context.Context) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *OpsDeliveryProjectDao) As(as string) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *OpsDeliveryProjectDao) TX(tx *gdb.TX) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *OpsDeliveryProjectDao) Master() *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *OpsDeliveryProjectDao) Slave() *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *OpsDeliveryProjectDao) Args(args ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectDao) LeftJoin(table ...string) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectDao) RightJoin(table ...string) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectDao) InnerJoin(table ...string) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectDao) Fields(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *OpsDeliveryProjectDao) Option(option int) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *OpsDeliveryProjectDao) OmitEmpty() *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *OpsDeliveryProjectDao) Filter() *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *OpsDeliveryProjectDao) Where(where interface{}, args ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *OpsDeliveryProjectDao) WherePri(where interface{}, args ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *OpsDeliveryProjectDao) And(where interface{}, args ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *OpsDeliveryProjectDao) Or(where interface{}, args ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *OpsDeliveryProjectDao) Group(groupBy string) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *OpsDeliveryProjectDao) Order(orderBy ...string) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *OpsDeliveryProjectDao) Limit(limit ...int) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *OpsDeliveryProjectDao) Offset(offset int) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *OpsDeliveryProjectDao) Page(page, limit int) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *OpsDeliveryProjectDao) Batch(batch int) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *OpsDeliveryProjectDao) Cache(duration time.Duration, name ...string) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *OpsDeliveryProjectDao) Data(data ...interface{}) *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.OpsDeliveryProject.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectDao) All(where ...interface{}) ([]*opsdev.OpsDeliveryProject, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProject
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.OpsDeliveryProject.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectDao) One(where ...interface{}) (*opsdev.OpsDeliveryProject, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProject
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *OpsDeliveryProjectDao) FindOne(where ...interface{}) (*opsdev.OpsDeliveryProject, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProject
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *OpsDeliveryProjectDao) FindAll(where ...interface{}) ([]*opsdev.OpsDeliveryProject, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProject
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *OpsDeliveryProjectDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *OpsDeliveryProjectDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *OpsDeliveryProjectDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *OpsDeliveryProjectDao) Chunk(limit int, callback func(entities []*opsdev.OpsDeliveryProject, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*opsdev.OpsDeliveryProject
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *OpsDeliveryProjectDao) LockUpdate() *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *OpsDeliveryProjectDao) LockShared() *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *OpsDeliveryProjectDao) Unscoped() *OpsDeliveryProjectDao {
+	return &OpsDeliveryProjectDao{M: d.M.Unscoped()}
+}

+ 497 - 0
opms_parent/app/dao/opsdev/internal/ops_delivery_project_event.go

@@ -0,0 +1,497 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"dashoo.cn/opms_parent/app/model/opsdev"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+)
+
+// OpsDeliveryProjectEventDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type OpsDeliveryProjectEventDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns opsDeliveryProjectEventColumns
+}
+
+// OpsDeliveryProjectEventColumns defines and stores column names for table ops_delivery_project_event.
+type opsDeliveryProjectEventColumns struct {
+	Id                  string // 主键
+	ProjectId           string // 交付项目ID
+	DeliveryEventNo     string // 事件编码
+	DeliveryEventTitle  string // 事件标题
+	DeliveryEventDesc   string // 事件描述
+	DeliveryEventType   string // 事件类型(10内部启动会 15 外部启动会 20 制定计划 30系统培训 31需求沟通 32功能调整 33二开需求 34BUG修复 35功能测试 36系统发版  39软件部署 40硬件发货 41硬件安装 50试运行 60验收汇报)
+	DeliveryEventStatus string // 事件状态(10 待处理,20 处理中 30 已关闭)
+	DeliveryEventResult string // 事件结果(10 已解决、30 未解决)
+	FeedbackSource      string // 反馈来源(10 客户 20 销售 30 交付)
+	FeedbackReporter    string // 反馈人
+	FeedbackDate        string // 反馈时间
+	OpsUserId           string // 负责人员ID
+	OpsUserName         string // 负责人员姓名
+	AssignTime          string // 接单时间
+	OnSite              string // 是否现场(10是 20否)
+	CompleteTime        string // 处理完成时间
+	CompleteDesc        string // 处理方案说明
+	DeliveryEventId     string // 关联事件ID
+	Attribute1          string // 增强字段1
+	Attribute2          string // 增强字段2
+	Attribute3          string // 增强字段3
+	Attribute4          string // 增强字段4
+	Attribute5          string // 增强字段5
+	Attribute6          string // 增强字段6
+	Attribute7          string // 增强字段7
+	Attribute8          string // 增强字段8
+	Attribute9          string // 增强字段9
+	Remark              string // 备注
+	CreatedBy           string // 创建者
+	CreatedName         string // 创建人
+	CreatedTime         string // 创建时间
+	UpdatedBy           string // 更新者
+	UpdatedName         string // 更新人
+	UpdatedTime         string // 更新时间
+	DeletedTime         string // 删除时间
+}
+
+var (
+	// OpsDeliveryProjectEvent is globally public accessible object for table ops_delivery_project_event operations.
+	OpsDeliveryProjectEvent = OpsDeliveryProjectEventDao{
+		M:     g.DB("default").Model("ops_delivery_project_event").Safe(),
+		DB:    g.DB("default"),
+		Table: "ops_delivery_project_event",
+		Columns: opsDeliveryProjectEventColumns{
+			Id:                  "id",
+			ProjectId:           "project_id",
+			DeliveryEventNo:     "delivery_event_no",
+			DeliveryEventTitle:  "delivery_event_title",
+			DeliveryEventDesc:   "delivery_event_desc",
+			DeliveryEventType:   "delivery_event_type",
+			DeliveryEventStatus: "delivery_event_status",
+			DeliveryEventResult: "delivery_event_result",
+			FeedbackSource:      "feedback_source",
+			FeedbackReporter:    "feedback_reporter",
+			FeedbackDate:        "feedback_date",
+			OpsUserId:           "ops_user_id",
+			OpsUserName:         "ops_user_name",
+			AssignTime:          "assign_time",
+			OnSite:              "on_site",
+			CompleteTime:        "complete_time",
+			CompleteDesc:        "complete_desc",
+			DeliveryEventId:     "delivery_event_id",
+			Attribute1:          "attribute1",
+			Attribute2:          "attribute2",
+			Attribute3:          "attribute3",
+			Attribute4:          "attribute4",
+			Attribute5:          "attribute5",
+			Attribute6:          "attribute6",
+			Attribute7:          "attribute7",
+			Attribute8:          "attribute8",
+			Attribute9:          "attribute9",
+			Remark:              "remark",
+			CreatedBy:           "created_by",
+			CreatedName:         "created_name",
+			CreatedTime:         "created_time",
+			UpdatedBy:           "updated_by",
+			UpdatedName:         "updated_name",
+			UpdatedTime:         "updated_time",
+			DeletedTime:         "deleted_time",
+		},
+	}
+)
+
+func NewOpsDeliveryProjectEventDao(tenant string) OpsDeliveryProjectEventDao {
+	var dao OpsDeliveryProjectEventDao
+	dao = OpsDeliveryProjectEventDao{
+		M:     g.DB(tenant).Model("ops_delivery_project_event").Safe(),
+		DB:    g.DB(tenant),
+		Table: "ops_delivery_project_event",
+		Columns: opsDeliveryProjectEventColumns{
+			Id:                  "id",
+			ProjectId:           "project_id",
+			DeliveryEventNo:     "delivery_event_no",
+			DeliveryEventTitle:  "delivery_event_title",
+			DeliveryEventDesc:   "delivery_event_desc",
+			DeliveryEventType:   "delivery_event_type",
+			DeliveryEventStatus: "delivery_event_status",
+			DeliveryEventResult: "delivery_event_result",
+			FeedbackSource:      "feedback_source",
+			FeedbackReporter:    "feedback_reporter",
+			FeedbackDate:        "feedback_date",
+			OpsUserId:           "ops_user_id",
+			OpsUserName:         "ops_user_name",
+			AssignTime:          "assign_time",
+			OnSite:              "on_site",
+			CompleteTime:        "complete_time",
+			CompleteDesc:        "complete_desc",
+			DeliveryEventId:     "delivery_event_id",
+			Attribute1:          "attribute1",
+			Attribute2:          "attribute2",
+			Attribute3:          "attribute3",
+			Attribute4:          "attribute4",
+			Attribute5:          "attribute5",
+			Attribute6:          "attribute6",
+			Attribute7:          "attribute7",
+			Attribute8:          "attribute8",
+			Attribute9:          "attribute9",
+			Remark:              "remark",
+			CreatedBy:           "created_by",
+			CreatedName:         "created_name",
+			CreatedTime:         "created_time",
+			UpdatedBy:           "updated_by",
+			UpdatedName:         "updated_name",
+			UpdatedTime:         "updated_time",
+			DeletedTime:         "deleted_time",
+		},
+	}
+	return dao
+}
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *OpsDeliveryProjectEventDao) Ctx(ctx context.Context) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *OpsDeliveryProjectEventDao) As(as string) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *OpsDeliveryProjectEventDao) TX(tx *gdb.TX) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *OpsDeliveryProjectEventDao) Master() *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *OpsDeliveryProjectEventDao) Slave() *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *OpsDeliveryProjectEventDao) Args(args ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventDao) LeftJoin(table ...string) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventDao) RightJoin(table ...string) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventDao) InnerJoin(table ...string) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectEventDao) Fields(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectEventDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *OpsDeliveryProjectEventDao) Option(option int) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *OpsDeliveryProjectEventDao) OmitEmpty() *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *OpsDeliveryProjectEventDao) Filter() *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *OpsDeliveryProjectEventDao) Where(where interface{}, args ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *OpsDeliveryProjectEventDao) WherePri(where interface{}, args ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *OpsDeliveryProjectEventDao) And(where interface{}, args ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *OpsDeliveryProjectEventDao) Or(where interface{}, args ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *OpsDeliveryProjectEventDao) Group(groupBy string) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *OpsDeliveryProjectEventDao) Order(orderBy ...string) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *OpsDeliveryProjectEventDao) Limit(limit ...int) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *OpsDeliveryProjectEventDao) Offset(offset int) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *OpsDeliveryProjectEventDao) Page(page, limit int) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *OpsDeliveryProjectEventDao) Batch(batch int) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *OpsDeliveryProjectEventDao) Cache(duration time.Duration, name ...string) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *OpsDeliveryProjectEventDao) Data(data ...interface{}) *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.OpsDeliveryProjectEvent.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectEventDao) All(where ...interface{}) ([]*opsdev.OpsDeliveryProjectEvent, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProjectEvent
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.OpsDeliveryProjectEvent.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectEventDao) One(where ...interface{}) (*opsdev.OpsDeliveryProjectEvent, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProjectEvent
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *OpsDeliveryProjectEventDao) FindOne(where ...interface{}) (*opsdev.OpsDeliveryProjectEvent, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProjectEvent
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *OpsDeliveryProjectEventDao) FindAll(where ...interface{}) ([]*opsdev.OpsDeliveryProjectEvent, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProjectEvent
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *OpsDeliveryProjectEventDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *OpsDeliveryProjectEventDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *OpsDeliveryProjectEventDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *OpsDeliveryProjectEventDao) Chunk(limit int, callback func(entities []*opsdev.OpsDeliveryProjectEvent, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*opsdev.OpsDeliveryProjectEvent
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *OpsDeliveryProjectEventDao) LockUpdate() *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *OpsDeliveryProjectEventDao) LockShared() *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *OpsDeliveryProjectEventDao) Unscoped() *OpsDeliveryProjectEventDao {
+	return &OpsDeliveryProjectEventDao{M: d.M.Unscoped()}
+}

+ 464 - 0
opms_parent/app/dao/opsdev/internal/ops_delivery_project_event_attachment.go

@@ -0,0 +1,464 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"dashoo.cn/opms_parent/app/model/opsdev"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+)
+
+// OpsDeliveryProjectEventAttachmentDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type OpsDeliveryProjectEventAttachmentDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns opsDeliveryProjectEventAttachmentColumns
+}
+
+// OpsDeliveryProjectEventAttachmentColumns defines and stores column names for table ops_delivery_project_event_attachment.
+type opsDeliveryProjectEventAttachmentColumns struct {
+	Id              string // 主键
+	DeliveryEventId string // 交付事件ID
+	EventId         string // 事件ID
+	EventRecordId   string // 事件过程ID(事件过程附件该字段不允许为空)
+	FileName        string // 附件名称
+	FileUrl         string // 附件URL
+	FileType        string // 附件类型(jpg/png/pdf/docx)
+	Attribute1      string // 增强字段1
+	Attribute2      string // 增强字段2
+	Attribute3      string // 增强字段3
+	Attribute4      string // 增强字段4
+	Attribute5      string // 增强字段5
+	Attribute6      string // 增强字段6
+	Attribute7      string // 增强字段7
+	Attribute8      string // 增强字段8
+	Attribute9      string // 增强字段9
+	Remark          string // 备注
+	CreatedBy       string // 创建者
+	CreatedName     string // 创建人
+	CreatedTime     string // 创建时间
+	UpdatedBy       string // 更新者
+	UpdatedName     string // 更新人
+	UpdatedTime     string // 更新时间
+	DeletedTime     string // 删除时间
+}
+
+var (
+	// OpsDeliveryProjectEventAttachment is globally public accessible object for table ops_delivery_project_event_attachment operations.
+	OpsDeliveryProjectEventAttachment = OpsDeliveryProjectEventAttachmentDao{
+		M:     g.DB("default").Model("ops_delivery_project_event_attachment").Safe(),
+		DB:    g.DB("default"),
+		Table: "ops_delivery_project_event_attachment",
+		Columns: opsDeliveryProjectEventAttachmentColumns{
+			Id:              "id",
+			DeliveryEventId: "delivery_event_id",
+			EventId:         "event_id",
+			EventRecordId:   "event_record_id",
+			FileName:        "file_name",
+			FileUrl:         "file_url",
+			FileType:        "file_type",
+			Attribute1:      "attribute1",
+			Attribute2:      "attribute2",
+			Attribute3:      "attribute3",
+			Attribute4:      "attribute4",
+			Attribute5:      "attribute5",
+			Attribute6:      "attribute6",
+			Attribute7:      "attribute7",
+			Attribute8:      "attribute8",
+			Attribute9:      "attribute9",
+			Remark:          "remark",
+			CreatedBy:       "created_by",
+			CreatedName:     "created_name",
+			CreatedTime:     "created_time",
+			UpdatedBy:       "updated_by",
+			UpdatedName:     "updated_name",
+			UpdatedTime:     "updated_time",
+			DeletedTime:     "deleted_time",
+		},
+	}
+)
+
+func NewOpsDeliveryProjectEventAttachmentDao(tenant string) OpsDeliveryProjectEventAttachmentDao {
+	var dao OpsDeliveryProjectEventAttachmentDao
+	dao = OpsDeliveryProjectEventAttachmentDao{
+		M:     g.DB(tenant).Model("ops_delivery_project_event_attachment").Safe(),
+		DB:    g.DB(tenant),
+		Table: "ops_delivery_project_event_attachment",
+		Columns: opsDeliveryProjectEventAttachmentColumns{
+			Id:              "id",
+			DeliveryEventId: "delivery_event_id",
+			EventId:         "event_id",
+			EventRecordId:   "event_record_id",
+			FileName:        "file_name",
+			FileUrl:         "file_url",
+			FileType:        "file_type",
+			Attribute1:      "attribute1",
+			Attribute2:      "attribute2",
+			Attribute3:      "attribute3",
+			Attribute4:      "attribute4",
+			Attribute5:      "attribute5",
+			Attribute6:      "attribute6",
+			Attribute7:      "attribute7",
+			Attribute8:      "attribute8",
+			Attribute9:      "attribute9",
+			Remark:          "remark",
+			CreatedBy:       "created_by",
+			CreatedName:     "created_name",
+			CreatedTime:     "created_time",
+			UpdatedBy:       "updated_by",
+			UpdatedName:     "updated_name",
+			UpdatedTime:     "updated_time",
+			DeletedTime:     "deleted_time",
+		},
+	}
+	return dao
+}
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *OpsDeliveryProjectEventAttachmentDao) Ctx(ctx context.Context) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *OpsDeliveryProjectEventAttachmentDao) As(as string) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *OpsDeliveryProjectEventAttachmentDao) TX(tx *gdb.TX) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *OpsDeliveryProjectEventAttachmentDao) Master() *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *OpsDeliveryProjectEventAttachmentDao) Slave() *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *OpsDeliveryProjectEventAttachmentDao) Args(args ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventAttachmentDao) LeftJoin(table ...string) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventAttachmentDao) RightJoin(table ...string) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventAttachmentDao) InnerJoin(table ...string) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectEventAttachmentDao) Fields(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectEventAttachmentDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *OpsDeliveryProjectEventAttachmentDao) Option(option int) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *OpsDeliveryProjectEventAttachmentDao) OmitEmpty() *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *OpsDeliveryProjectEventAttachmentDao) Filter() *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *OpsDeliveryProjectEventAttachmentDao) Where(where interface{}, args ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *OpsDeliveryProjectEventAttachmentDao) WherePri(where interface{}, args ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *OpsDeliveryProjectEventAttachmentDao) And(where interface{}, args ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *OpsDeliveryProjectEventAttachmentDao) Or(where interface{}, args ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *OpsDeliveryProjectEventAttachmentDao) Group(groupBy string) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *OpsDeliveryProjectEventAttachmentDao) Order(orderBy ...string) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *OpsDeliveryProjectEventAttachmentDao) Limit(limit ...int) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *OpsDeliveryProjectEventAttachmentDao) Offset(offset int) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *OpsDeliveryProjectEventAttachmentDao) Page(page, limit int) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *OpsDeliveryProjectEventAttachmentDao) Batch(batch int) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *OpsDeliveryProjectEventAttachmentDao) Cache(duration time.Duration, name ...string) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *OpsDeliveryProjectEventAttachmentDao) Data(data ...interface{}) *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.OpsDeliveryProjectEventAttachment.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectEventAttachmentDao) All(where ...interface{}) ([]*opsdev.OpsDeliveryProjectEventAttachment, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProjectEventAttachment
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.OpsDeliveryProjectEventAttachment.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectEventAttachmentDao) One(where ...interface{}) (*opsdev.OpsDeliveryProjectEventAttachment, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProjectEventAttachment
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *OpsDeliveryProjectEventAttachmentDao) FindOne(where ...interface{}) (*opsdev.OpsDeliveryProjectEventAttachment, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProjectEventAttachment
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *OpsDeliveryProjectEventAttachmentDao) FindAll(where ...interface{}) ([]*opsdev.OpsDeliveryProjectEventAttachment, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProjectEventAttachment
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *OpsDeliveryProjectEventAttachmentDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *OpsDeliveryProjectEventAttachmentDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *OpsDeliveryProjectEventAttachmentDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *OpsDeliveryProjectEventAttachmentDao) Chunk(limit int, callback func(entities []*opsdev.OpsDeliveryProjectEventAttachment, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*opsdev.OpsDeliveryProjectEventAttachment
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *OpsDeliveryProjectEventAttachmentDao) LockUpdate() *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *OpsDeliveryProjectEventAttachmentDao) LockShared() *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *OpsDeliveryProjectEventAttachmentDao) Unscoped() *OpsDeliveryProjectEventAttachmentDao {
+	return &OpsDeliveryProjectEventAttachmentDao{M: d.M.Unscoped()}
+}

+ 458 - 0
opms_parent/app/dao/opsdev/internal/ops_delivery_project_event_record.go

@@ -0,0 +1,458 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"dashoo.cn/opms_parent/app/model/opsdev"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+)
+
+// OpsDeliveryProjectEventRecordDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type OpsDeliveryProjectEventRecordDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns opsDeliveryProjectEventRecordColumns
+}
+
+// OpsDeliveryProjectEventRecordColumns defines and stores column names for table ops_delivery_project_event_record.
+type opsDeliveryProjectEventRecordColumns struct {
+	Id              string // 主键
+	DeliveryEventId string // 交付事件ID
+	HandleUserId    string // 记录人ID
+	HandleUserName  string // 记录人
+	HandleContent   string // 描述
+	Attribute1      string // 增强字段1
+	Attribute2      string // 增强字段2
+	Attribute3      string // 增强字段3
+	Attribute4      string // 增强字段4
+	Attribute5      string // 增强字段5
+	Attribute6      string // 增强字段6
+	Attribute7      string // 增强字段7
+	Attribute8      string // 增强字段8
+	Attribute9      string // 增强字段9
+	Remark          string // 备注
+	CreatedBy       string // 创建者
+	CreatedName     string // 创建人
+	CreatedTime     string // 创建时间
+	UpdatedBy       string // 更新者
+	UpdatedName     string // 更新人
+	UpdatedTime     string // 更新时间
+	DeletedTime     string // 删除时间
+}
+
+var (
+	// OpsDeliveryProjectEventRecord is globally public accessible object for table ops_delivery_project_event_record operations.
+	OpsDeliveryProjectEventRecord = OpsDeliveryProjectEventRecordDao{
+		M:     g.DB("default").Model("ops_delivery_project_event_record").Safe(),
+		DB:    g.DB("default"),
+		Table: "ops_delivery_project_event_record",
+		Columns: opsDeliveryProjectEventRecordColumns{
+			Id:              "id",
+			DeliveryEventId: "delivery_event_id",
+			HandleUserId:    "handle_user_id",
+			HandleUserName:  "handle_user_name",
+			HandleContent:   "handle_content",
+			Attribute1:      "attribute1",
+			Attribute2:      "attribute2",
+			Attribute3:      "attribute3",
+			Attribute4:      "attribute4",
+			Attribute5:      "attribute5",
+			Attribute6:      "attribute6",
+			Attribute7:      "attribute7",
+			Attribute8:      "attribute8",
+			Attribute9:      "attribute9",
+			Remark:          "remark",
+			CreatedBy:       "created_by",
+			CreatedName:     "created_name",
+			CreatedTime:     "created_time",
+			UpdatedBy:       "updated_by",
+			UpdatedName:     "updated_name",
+			UpdatedTime:     "updated_time",
+			DeletedTime:     "deleted_time",
+		},
+	}
+)
+
+func NewOpsDeliveryProjectEventRecordDao(tenant string) OpsDeliveryProjectEventRecordDao {
+	var dao OpsDeliveryProjectEventRecordDao
+	dao = OpsDeliveryProjectEventRecordDao{
+		M:     g.DB(tenant).Model("ops_delivery_project_event_record").Safe(),
+		DB:    g.DB(tenant),
+		Table: "ops_delivery_project_event_record",
+		Columns: opsDeliveryProjectEventRecordColumns{
+			Id:              "id",
+			DeliveryEventId: "delivery_event_id",
+			HandleUserId:    "handle_user_id",
+			HandleUserName:  "handle_user_name",
+			HandleContent:   "handle_content",
+			Attribute1:      "attribute1",
+			Attribute2:      "attribute2",
+			Attribute3:      "attribute3",
+			Attribute4:      "attribute4",
+			Attribute5:      "attribute5",
+			Attribute6:      "attribute6",
+			Attribute7:      "attribute7",
+			Attribute8:      "attribute8",
+			Attribute9:      "attribute9",
+			Remark:          "remark",
+			CreatedBy:       "created_by",
+			CreatedName:     "created_name",
+			CreatedTime:     "created_time",
+			UpdatedBy:       "updated_by",
+			UpdatedName:     "updated_name",
+			UpdatedTime:     "updated_time",
+			DeletedTime:     "deleted_time",
+		},
+	}
+	return dao
+}
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *OpsDeliveryProjectEventRecordDao) Ctx(ctx context.Context) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *OpsDeliveryProjectEventRecordDao) As(as string) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *OpsDeliveryProjectEventRecordDao) TX(tx *gdb.TX) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *OpsDeliveryProjectEventRecordDao) Master() *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *OpsDeliveryProjectEventRecordDao) Slave() *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *OpsDeliveryProjectEventRecordDao) Args(args ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventRecordDao) LeftJoin(table ...string) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventRecordDao) RightJoin(table ...string) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *OpsDeliveryProjectEventRecordDao) InnerJoin(table ...string) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectEventRecordDao) Fields(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *OpsDeliveryProjectEventRecordDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *OpsDeliveryProjectEventRecordDao) Option(option int) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *OpsDeliveryProjectEventRecordDao) OmitEmpty() *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *OpsDeliveryProjectEventRecordDao) Filter() *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *OpsDeliveryProjectEventRecordDao) Where(where interface{}, args ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *OpsDeliveryProjectEventRecordDao) WherePri(where interface{}, args ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *OpsDeliveryProjectEventRecordDao) And(where interface{}, args ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *OpsDeliveryProjectEventRecordDao) Or(where interface{}, args ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *OpsDeliveryProjectEventRecordDao) Group(groupBy string) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *OpsDeliveryProjectEventRecordDao) Order(orderBy ...string) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *OpsDeliveryProjectEventRecordDao) Limit(limit ...int) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *OpsDeliveryProjectEventRecordDao) Offset(offset int) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *OpsDeliveryProjectEventRecordDao) Page(page, limit int) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *OpsDeliveryProjectEventRecordDao) Batch(batch int) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *OpsDeliveryProjectEventRecordDao) Cache(duration time.Duration, name ...string) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *OpsDeliveryProjectEventRecordDao) Data(data ...interface{}) *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.OpsDeliveryProjectEventRecord.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectEventRecordDao) All(where ...interface{}) ([]*opsdev.OpsDeliveryProjectEventRecord, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProjectEventRecord
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.OpsDeliveryProjectEventRecord.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *OpsDeliveryProjectEventRecordDao) One(where ...interface{}) (*opsdev.OpsDeliveryProjectEventRecord, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProjectEventRecord
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *OpsDeliveryProjectEventRecordDao) FindOne(where ...interface{}) (*opsdev.OpsDeliveryProjectEventRecord, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *opsdev.OpsDeliveryProjectEventRecord
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *OpsDeliveryProjectEventRecordDao) FindAll(where ...interface{}) ([]*opsdev.OpsDeliveryProjectEventRecord, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*opsdev.OpsDeliveryProjectEventRecord
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *OpsDeliveryProjectEventRecordDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *OpsDeliveryProjectEventRecordDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *OpsDeliveryProjectEventRecordDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *OpsDeliveryProjectEventRecordDao) Chunk(limit int, callback func(entities []*opsdev.OpsDeliveryProjectEventRecord, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*opsdev.OpsDeliveryProjectEventRecord
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *OpsDeliveryProjectEventRecordDao) LockUpdate() *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *OpsDeliveryProjectEventRecordDao) LockShared() *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *OpsDeliveryProjectEventRecordDao) Unscoped() *OpsDeliveryProjectEventRecordDao {
+	return &OpsDeliveryProjectEventRecordDao{M: d.M.Unscoped()}
+}

+ 2 - 2
opms_parent/app/dao/opsdev/internal/ops_operation_event.go

@@ -29,7 +29,7 @@ type opsOperationEventColumns struct {
 	EventNo          string // 事件编号
 	EventTitle       string // 事件标题
 	EventDesc        string // 事件描述
-	EventType        string // 事件类型:10-咨询 20-故障 30-需求 40-其他
+	EventType        string // 事件类型:10-操作咨询 20-数据处理 30-系统BUG 40-功能调整 50-二开需求 90-其他问题
 	EventStatus      string // 事件状态:10-待处理 20-处理中 30-转研发 70-挂起 80-已关闭
 	EventResult      string // 事件结果:10-已解决 20-部分解决 30-未解决
 	ContractId       string // 关联合同ID
@@ -40,7 +40,7 @@ type opsOperationEventColumns struct {
 	IsBig            string // 是否重点项目:10-是 20-否
 	IsOps            string // 是否在运维期:10-是 20-否
 	PriorityLevel    string // 优先级:P1-紧急 P2-一般 P3-低优
-	FeedbackSource   string // 反馈来源:10-微信 20-销售 30-交付
+	FeedbackSource   string // 反馈来源:10-客户 20-销售 30-交付
 	FeedbackReporter string // 反馈人
 	FeedbackDate     string // 反馈时间
 	OpsUserId        string // 运维人员ID

+ 36 - 0
opms_parent/app/dao/opsdev/ops_delivery_project.go

@@ -0,0 +1,36 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/dao/opsdev/internal"
+)
+
+// opsDeliveryProjectDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type opsDeliveryProjectDao struct {
+	internal.OpsDeliveryProjectDao
+}
+
+var (
+	// OpsDeliveryProject is globally public accessible object for table ops_delivery_project operations.
+	OpsDeliveryProject = opsDeliveryProjectDao{
+		internal.OpsDeliveryProject,
+	}
+)
+
+type OpsDeliveryProjectDao struct {
+	internal.OpsDeliveryProjectDao
+}
+
+func NewOpsDeliveryProjectDao(tenant string) *OpsDeliveryProjectDao {
+	dao := internal.NewOpsDeliveryProjectDao(tenant)
+	return &OpsDeliveryProjectDao{
+		dao,
+	}
+}
+
+// Fill with you ideas below.

+ 36 - 0
opms_parent/app/dao/opsdev/ops_delivery_project_event.go

@@ -0,0 +1,36 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/dao/opsdev/internal"
+)
+
+// opsDeliveryProjectEventDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type opsDeliveryProjectEventDao struct {
+	internal.OpsDeliveryProjectEventDao
+}
+
+var (
+	// OpsDeliveryProjectEvent is globally public accessible object for table ops_delivery_project_event operations.
+	OpsDeliveryProjectEvent = opsDeliveryProjectEventDao{
+		internal.OpsDeliveryProjectEvent,
+	}
+)
+
+type OpsDeliveryProjectEventDao struct {
+	internal.OpsDeliveryProjectEventDao
+}
+
+func NewOpsDeliveryProjectEventDao(tenant string) *OpsDeliveryProjectEventDao {
+	dao := internal.NewOpsDeliveryProjectEventDao(tenant)
+	return &OpsDeliveryProjectEventDao{
+		dao,
+	}
+}
+
+// Fill with you ideas below.

+ 36 - 0
opms_parent/app/dao/opsdev/ops_delivery_project_event_attachment.go

@@ -0,0 +1,36 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/dao/opsdev/internal"
+)
+
+// opsDeliveryProjectEventAttachmentDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type opsDeliveryProjectEventAttachmentDao struct {
+	internal.OpsDeliveryProjectEventAttachmentDao
+}
+
+var (
+	// OpsDeliveryProjectEventAttachment is globally public accessible object for table ops_delivery_project_event_attachment operations.
+	OpsDeliveryProjectEventAttachment = opsDeliveryProjectEventAttachmentDao{
+		internal.OpsDeliveryProjectEventAttachment,
+	}
+)
+
+type OpsDeliveryProjectEventAttachmentDao struct {
+	internal.OpsDeliveryProjectEventAttachmentDao
+}
+
+func NewOpsDeliveryProjectEventAttachmentDao(tenant string) *OpsDeliveryProjectEventAttachmentDao {
+	dao := internal.NewOpsDeliveryProjectEventAttachmentDao(tenant)
+	return &OpsDeliveryProjectEventAttachmentDao{
+		dao,
+	}
+}
+
+// Fill with you ideas below.

+ 36 - 0
opms_parent/app/dao/opsdev/ops_delivery_project_event_record.go

@@ -0,0 +1,36 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/dao/opsdev/internal"
+)
+
+// opsDeliveryProjectEventRecordDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type opsDeliveryProjectEventRecordDao struct {
+	internal.OpsDeliveryProjectEventRecordDao
+}
+
+var (
+	// OpsDeliveryProjectEventRecord is globally public accessible object for table ops_delivery_project_event_record operations.
+	OpsDeliveryProjectEventRecord = opsDeliveryProjectEventRecordDao{
+		internal.OpsDeliveryProjectEventRecord,
+	}
+)
+
+type OpsDeliveryProjectEventRecordDao struct {
+	internal.OpsDeliveryProjectEventRecordDao
+}
+
+func NewOpsDeliveryProjectEventRecordDao(tenant string) *OpsDeliveryProjectEventRecordDao {
+	dao := internal.NewOpsDeliveryProjectEventRecordDao(tenant)
+	return &OpsDeliveryProjectEventRecordDao{
+		dao,
+	}
+}
+
+// Fill with you ideas below.

+ 26 - 0
opms_parent/app/handler/opsdev/operation.go

@@ -225,3 +225,29 @@ func (h *OperationHandler) GetHistoryList(ctx context.Context, req *opsdevmodel.
 	rsp.Data = g.Map{"list": list, "total": total}
 	return nil
 }
+
+func (h *OperationHandler) Export(ctx context.Context, req *opsdevmodel.OpsOperationEventHistoryExport, rsp *comm_def.CommonMsg) error {
+	srv, err := opsdevSrv.NewOperationService(ctx)
+	if err != nil {
+		return err
+	}
+	content, err := srv.Export(ctx, req)
+	if err != nil {
+		return err
+	}
+	rsp.Data = content
+	return nil
+}
+
+func (h *OperationHandler) ExportNonClosed(ctx context.Context, req *opsdevmodel.OpsOperationEventExport, rsp *comm_def.CommonMsg) error {
+	srv, err := opsdevSrv.NewOperationService(ctx)
+	if err != nil {
+		return err
+	}
+	content, err := srv.ExportNonClosed(ctx, req)
+	if err != nil {
+		return err
+	}
+	rsp.Data = content
+	return nil
+}

+ 49 - 0
opms_parent/app/model/opsdev/internal/ops_delivery_project.go

@@ -0,0 +1,49 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// OpsDeliveryProject is the golang structure for table ops_delivery_project.
+type OpsDeliveryProject struct {
+	Id                     int         `orm:"id,primary"                json:"id"`                     // 主键
+	ProjectName            string      `orm:"project_name"              json:"projectName"`            // 项目名称
+	ProjectStatus          string      `orm:"project_status"            json:"projectStatus"`          // 项目状态(10 待交付 20 交付中 30 暂停 40交付完成 50 验收 90作废)
+	ContractId             int         `orm:"contract_id"               json:"contractId"`             // 合同ID
+	ContractNo             string      `orm:"contract_no"               json:"contractNo"`             // 合同编号
+	CustId                 string      `orm:"cust_id"                   json:"custId"`                 // 客户ID
+	CustName               string      `orm:"cust_name"                 json:"custName"`               // 客户名称
+	ProductLine            string      `orm:"product_line"              json:"productLine"`            // 产品线(10 Biobank 20 LIMS 30 CellLbank 40MCS )
+	DeliveryUserId         int         `orm:"delivery_user_id"          json:"deliveryUserId"`         // 交付负责人ID
+	DeliveryUserName       string      `orm:"delivery_user_name"        json:"deliveryUserName"`       // 交付负责人
+	SalesUserId            int         `orm:"sales_user_id"             json:"salesUserId"`            // 销售ID
+	SalesUserName          string      `orm:"sales_user_name"           json:"salesUserName"`          // 销售
+	DeliveryNode           string      `orm:"delivery_node"             json:"deliveryNode"`           // 交付节点(10内部启动会 15 外部启动会 20 制定计划 30项目实施 40完成部署 50试运行 60交付完成)
+	InternalKickoffTime    *gtime.Time `orm:"internal_kickoff_time"     json:"internalKickoffTime"`    // 内部启动会时间
+	ExternalKickoffTime    *gtime.Time `orm:"external_kickoff_time"     json:"externalKickoffTime"`    // 外部启动会时间
+	DeliveryPlanSubmitTime *gtime.Time `orm:"delivery_plan_submit_time" json:"deliveryPlanSubmitTime"` // 交付计划提交时间
+	DeploymentTime         *gtime.Time `orm:"deployment_time"           json:"deploymentTime"`         // 部署时间
+	TrialRunTime           *gtime.Time `orm:"trial_run_time"            json:"trialRunTime"`           // 试运行时间
+	GoLiveTime             *gtime.Time `orm:"go_live_time"              json:"goLiveTime"`             // 上线时间
+	Attribute1             string      `orm:"attribute1"                json:"attribute1"`             // 增强字段1
+	Attribute2             string      `orm:"attribute2"                json:"attribute2"`             // 增强字段2
+	Attribute3             string      `orm:"attribute3"                json:"attribute3"`             // 增强字段3
+	Attribute4             float64     `orm:"attribute4"                json:"attribute4"`             // 增强字段4
+	Attribute5             float64     `orm:"attribute5"                json:"attribute5"`             // 增强字段5
+	Attribute6             *gtime.Time `orm:"attribute6"                json:"attribute6"`             // 增强字段6
+	Attribute7             *gtime.Time `orm:"attribute7"                json:"attribute7"`             // 增强字段7
+	Attribute8             string      `orm:"attribute8"                json:"attribute8"`             // 增强字段8
+	Attribute9             string      `orm:"attribute9"                json:"attribute9"`             // 增强字段9
+	Remark                 string      `orm:"remark"                    json:"remark"`                 // 备注
+	CreatedBy              int         `orm:"created_by"                json:"createdBy"`              // 创建者
+	CreatedName            string      `orm:"created_name"              json:"createdName"`            // 创建人
+	CreatedTime            *gtime.Time `orm:"created_time"              json:"createdTime"`            // 创建时间
+	UpdatedBy              int         `orm:"updated_by"                json:"updatedBy"`              // 更新者
+	UpdatedName            string      `orm:"updated_name"              json:"updatedName"`            // 更新人
+	UpdatedTime            *gtime.Time `orm:"updated_time"              json:"updatedTime"`            // 更新时间
+	DeletedTime            *gtime.Time `orm:"deleted_time"              json:"deletedTime"`            // 删除时间
+}

+ 48 - 0
opms_parent/app/model/opsdev/internal/ops_delivery_project_event.go

@@ -0,0 +1,48 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// OpsDeliveryProjectEvent is the golang structure for table ops_delivery_project_event.
+type OpsDeliveryProjectEvent struct {
+	Id                  int         `orm:"id,primary"            json:"id"`                  // 主键
+	ProjectId           int         `orm:"project_id"            json:"projectId"`           // 交付项目ID
+	DeliveryEventNo     string      `orm:"delivery_event_no"     json:"deliveryEventNo"`     // 事件编码
+	DeliveryEventTitle  string      `orm:"delivery_event_title"  json:"deliveryEventTitle"`  // 事件标题
+	DeliveryEventDesc   string      `orm:"delivery_event_desc"   json:"deliveryEventDesc"`   // 事件描述
+	DeliveryEventType   string      `orm:"delivery_event_type"   json:"deliveryEventType"`   // 事件类型(10内部启动会 15 外部启动会 20 制定计划 30系统培训 31需求沟通 32功能调整 33二开需求 34BUG修复 35功能测试 36系统发版  39软件部署 40硬件发货 41硬件安装 50试运行 60验收汇报)
+	DeliveryEventStatus string      `orm:"delivery_event_status" json:"deliveryEventStatus"` // 事件状态(10 待处理,20 处理中 30 已关闭)
+	DeliveryEventResult string      `orm:"delivery_event_result" json:"deliveryEventResult"` // 事件结果(10 已解决、30 未解决)
+	FeedbackSource      string      `orm:"feedback_source"       json:"feedbackSource"`      // 反馈来源(10 客户 20 销售 30 交付)
+	FeedbackReporter    string      `orm:"feedback_reporter"     json:"feedbackReporter"`    // 反馈人
+	FeedbackDate        *gtime.Time `orm:"feedback_date"         json:"feedbackDate"`        // 反馈时间
+	OpsUserId           int         `orm:"ops_user_id"           json:"opsUserId"`           // 负责人员ID
+	OpsUserName         string      `orm:"ops_user_name"         json:"opsUserName"`         // 负责人员姓名
+	AssignTime          *gtime.Time `orm:"assign_time"           json:"assignTime"`          // 接单时间
+	OnSite              string      `orm:"on_site"               json:"onSite"`              // 是否现场(10是 20否)
+	CompleteTime        *gtime.Time `orm:"complete_time"         json:"completeTime"`        // 处理完成时间
+	CompleteDesc        string      `orm:"complete_desc"         json:"completeDesc"`        // 处理方案说明
+	DeliveryEventId     string      `orm:"delivery_event_id"     json:"deliveryEventId"`     // 关联事件ID
+	Attribute1          string      `orm:"attribute1"            json:"attribute1"`          // 增强字段1
+	Attribute2          string      `orm:"attribute2"            json:"attribute2"`          // 增强字段2
+	Attribute3          string      `orm:"attribute3"            json:"attribute3"`          // 增强字段3
+	Attribute4          float64     `orm:"attribute4"            json:"attribute4"`          // 增强字段4
+	Attribute5          float64     `orm:"attribute5"            json:"attribute5"`          // 增强字段5
+	Attribute6          *gtime.Time `orm:"attribute6"            json:"attribute6"`          // 增强字段6
+	Attribute7          *gtime.Time `orm:"attribute7"            json:"attribute7"`          // 增强字段7
+	Attribute8          string      `orm:"attribute8"            json:"attribute8"`          // 增强字段8
+	Attribute9          string      `orm:"attribute9"            json:"attribute9"`          // 增强字段9
+	Remark              string      `orm:"remark"                json:"remark"`              // 备注
+	CreatedBy           int         `orm:"created_by"            json:"createdBy"`           // 创建者
+	CreatedName         string      `orm:"created_name"          json:"createdName"`         // 创建人
+	CreatedTime         *gtime.Time `orm:"created_time"          json:"createdTime"`         // 创建时间
+	UpdatedBy           int         `orm:"updated_by"            json:"updatedBy"`           // 更新者
+	UpdatedName         string      `orm:"updated_name"          json:"updatedName"`         // 更新人
+	UpdatedTime         *gtime.Time `orm:"updated_time"          json:"updatedTime"`         // 更新时间
+	DeletedTime         *gtime.Time `orm:"deleted_time"          json:"deletedTime"`         // 删除时间
+}

+ 37 - 0
opms_parent/app/model/opsdev/internal/ops_delivery_project_event_attachment.go

@@ -0,0 +1,37 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// OpsDeliveryProjectEventAttachment is the golang structure for table ops_delivery_project_event_attachment.
+type OpsDeliveryProjectEventAttachment struct {
+	Id              int         `orm:"id,primary"        json:"id"`              // 主键
+	DeliveryEventId int         `orm:"delivery_event_id" json:"deliveryEventId"` // 交付事件ID
+	EventId         int         `orm:"event_id"          json:"eventId"`         // 事件ID
+	EventRecordId   int         `orm:"event_record_id"   json:"eventRecordId"`   // 事件过程ID(事件过程附件该字段不允许为空)
+	FileName        string      `orm:"file_name"         json:"fileName"`        // 附件名称
+	FileUrl         string      `orm:"file_url"          json:"fileUrl"`         // 附件URL
+	FileType        string      `orm:"file_type"         json:"fileType"`        // 附件类型(jpg/png/pdf/docx)
+	Attribute1      string      `orm:"attribute1"        json:"attribute1"`      // 增强字段1
+	Attribute2      string      `orm:"attribute2"        json:"attribute2"`      // 增强字段2
+	Attribute3      string      `orm:"attribute3"        json:"attribute3"`      // 增强字段3
+	Attribute4      float64     `orm:"attribute4"        json:"attribute4"`      // 增强字段4
+	Attribute5      float64     `orm:"attribute5"        json:"attribute5"`      // 增强字段5
+	Attribute6      *gtime.Time `orm:"attribute6"        json:"attribute6"`      // 增强字段6
+	Attribute7      *gtime.Time `orm:"attribute7"        json:"attribute7"`      // 增强字段7
+	Attribute8      string      `orm:"attribute8"        json:"attribute8"`      // 增强字段8
+	Attribute9      string      `orm:"attribute9"        json:"attribute9"`      // 增强字段9
+	Remark          string      `orm:"remark"            json:"remark"`          // 备注
+	CreatedBy       int         `orm:"created_by"        json:"createdBy"`       // 创建者
+	CreatedName     string      `orm:"created_name"      json:"createdName"`     // 创建人
+	CreatedTime     *gtime.Time `orm:"created_time"      json:"createdTime"`     // 创建时间
+	UpdatedBy       int         `orm:"updated_by"        json:"updatedBy"`       // 更新者
+	UpdatedName     string      `orm:"updated_name"      json:"updatedName"`     // 更新人
+	UpdatedTime     *gtime.Time `orm:"updated_time"      json:"updatedTime"`     // 更新时间
+	DeletedTime     *gtime.Time `orm:"deleted_time"      json:"deletedTime"`     // 删除时间
+}

+ 35 - 0
opms_parent/app/model/opsdev/internal/ops_delivery_project_event_record.go

@@ -0,0 +1,35 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// OpsDeliveryProjectEventRecord is the golang structure for table ops_delivery_project_event_record.
+type OpsDeliveryProjectEventRecord struct {
+	Id              int         `orm:"id,primary"        json:"id"`              // 主键
+	DeliveryEventId int         `orm:"delivery_event_id" json:"deliveryEventId"` // 交付事件ID
+	HandleUserId    int         `orm:"handle_user_id"    json:"handleUserId"`    // 记录人ID
+	HandleUserName  string      `orm:"handle_user_name"  json:"handleUserName"`  // 记录人
+	HandleContent   string      `orm:"handle_content"    json:"handleContent"`   // 描述
+	Attribute1      string      `orm:"attribute1"        json:"attribute1"`      // 增强字段1
+	Attribute2      string      `orm:"attribute2"        json:"attribute2"`      // 增强字段2
+	Attribute3      string      `orm:"attribute3"        json:"attribute3"`      // 增强字段3
+	Attribute4      float64     `orm:"attribute4"        json:"attribute4"`      // 增强字段4
+	Attribute5      float64     `orm:"attribute5"        json:"attribute5"`      // 增强字段5
+	Attribute6      *gtime.Time `orm:"attribute6"        json:"attribute6"`      // 增强字段6
+	Attribute7      *gtime.Time `orm:"attribute7"        json:"attribute7"`      // 增强字段7
+	Attribute8      string      `orm:"attribute8"        json:"attribute8"`      // 增强字段8
+	Attribute9      string      `orm:"attribute9"        json:"attribute9"`      // 增强字段9
+	Remark          string      `orm:"remark"            json:"remark"`          // 备注
+	CreatedBy       int         `orm:"created_by"        json:"createdBy"`       // 创建者
+	CreatedName     string      `orm:"created_name"      json:"createdName"`     // 创建人
+	CreatedTime     *gtime.Time `orm:"created_time"      json:"createdTime"`     // 创建时间
+	UpdatedBy       int         `orm:"updated_by"        json:"updatedBy"`       // 更新者
+	UpdatedName     string      `orm:"updated_name"      json:"updatedName"`     // 更新人
+	UpdatedTime     *gtime.Time `orm:"updated_time"      json:"updatedTime"`     // 更新时间
+	DeletedTime     *gtime.Time `orm:"deleted_time"      json:"deletedTime"`     // 删除时间
+}

+ 2 - 2
opms_parent/app/model/opsdev/internal/ops_operation_event.go

@@ -14,7 +14,7 @@ type OpsOperationEvent struct {
 	EventNo          string      `orm:"event_no"          json:"eventNo"`          // 事件编号
 	EventTitle       string      `orm:"event_title"       json:"eventTitle"`       // 事件标题
 	EventDesc        string      `orm:"event_desc"        json:"eventDesc"`        // 事件描述
-	EventType        string      `orm:"event_type"        json:"eventType"`        // 事件类型(10 咨询 20
+	EventType        string      `orm:"event_type"        json:"eventType"`        // 事件类型(10-操作咨询 20-数据处理 30-系统BUG 40-功能调整 50-二开需求 90-其他问题
 	EventStatus      string      `orm:"event_status"      json:"eventStatus"`      // 事件状态(10 待处理、20处理中、30 转研发、70 已完成、80已关闭)
 	ContractId       int         `orm:"contract_id"       json:"contractId"`       // 关联合同
 	ContractName     string      `orm:"contract_name"     json:"contractName"`     // 合同名称
@@ -24,7 +24,7 @@ type OpsOperationEvent struct {
 	IsBig            string      `orm:"is_big"            json:"isBig"`            // 是否重点项目(10是 20否)
 	IsOps            string      `orm:"is_ops"            json:"isOps"`            // 是否在运维期(10是 20否)
 	PriorityLevel    string      `orm:"priority_level"    json:"priorityLevel"`    // 优先级(P1 紧急 P2 一般 P3 低优)
-	FeedbackSource   string      `orm:"feedback_source"   json:"feedbackSource"`   // 反馈来源(10 微信 20 销售 30 交付)
+	FeedbackSource   string      `orm:"feedback_source"   json:"feedbackSource"`   // 反馈来源(10 客户 20 销售 30 交付)
 	FeedbackReporter string      `orm:"feedback_reporter" json:"feedbackReporter"` // 反馈人
 	FeedbackDate     *gtime.Time `orm:"feedback_date"     json:"feedbackDate"`     // 反馈时间
 	OpsUserId        int         `orm:"ops_user_id"       json:"opsUserId"`        // 运维人员ID

+ 42 - 0
opms_parent/app/model/opsdev/operation.go

@@ -120,6 +120,7 @@ type AddRecordReq struct {
 // OpsOperationEventHistorySearchReq 运维历史搜索请求
 type OpsOperationEventHistorySearchReq struct {
 	ScopeType        string `json:"scopeType"`        // 范围: my-本人处理, all-全部
+	IncludeClosed    bool   `json:"includeClosed"`    // 是否包含未关闭事件
 	EventTitle       string `json:"eventTitle"`       // 事件标题(模糊搜索)
 	CustName         string `json:"custName"`         // 客户名称(模糊搜索)
 	FeedbackReporter string `json:"feedbackReporter"` // 反馈人(模糊搜索)
@@ -128,3 +129,44 @@ type OpsOperationEventHistorySearchReq struct {
 	EndTime          string `json:"endTime"`          // 反馈结束时间
 	request.PageReq
 }
+
+// OpsOperationEventHistoryExport 运维历史导出参数
+type OpsOperationEventHistoryExport struct {
+	OpsOperationEventHistorySearchReq
+	Columns []string `json:"columns"` // 导出列
+}
+
+// OpsOperationEventHistoryExportData 运维历史导出数据
+type OpsOperationEventHistoryExportData struct {
+	EventNo       string `json:"eventNo"       export:"事件编号"`
+	EventTitle    string `json:"eventTitle"    export:"事件标题"`
+	EventStatus   string `json:"eventStatus"   export:"事件状态"`
+	EventType     string `json:"eventType"     export:"事件类型"`
+	CustName      string `json:"custName"      export:"客户名称"`
+	OpsUserName   string `json:"opsUserName"   export:"处理人员"`
+	FeedbackDate  string `json:"feedbackDate"  export:"反馈时间"`
+	PriorityLevel string `json:"priorityLevel" export:"优先级"`
+	HandleProcess string `json:"handleProcess" export:"处理过程"`
+	ClosedTime    string `json:"closedTime"    export:"关闭时间"`
+}
+
+// OpsOperationEventHistoryExportContent 运维历史导出内容
+type OpsOperationEventHistoryExportContent struct {
+	Content string `json:"content"` // 导出内容(base64编码)
+}
+
+type OpsOperationEventExport struct {
+	Columns []string `json:"columns"`
+}
+
+type OpsOperationEventExportData struct {
+	EventNo       string `json:"eventNo"       export:"事件编号"`
+	EventTitle    string `json:"eventTitle"    export:"事件标题"`
+	EventStatus   string `json:"eventStatus"   export:"事件状态"`
+	EventType     string `json:"eventType"     export:"事件类型"`
+	CustName      string `json:"custName"      export:"客户名称"`
+	OpsUserName   string `json:"opsUserName"   export:"处理人员"`
+	FeedbackDate  string `json:"feedbackDate"  export:"反馈时间"`
+	PriorityLevel string `json:"priorityLevel" export:"优先级"`
+	HandleProcess string `json:"handleProcess" export:"处理过程"`
+}

+ 14 - 0
opms_parent/app/model/opsdev/ops_delivery_project.go

@@ -0,0 +1,14 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/model/opsdev/internal"
+)
+
+// OpsDeliveryProject is the golang structure for table ops_delivery_project.
+type OpsDeliveryProject internal.OpsDeliveryProject
+
+// Fill with you ideas below.

+ 14 - 0
opms_parent/app/model/opsdev/ops_delivery_project_event.go

@@ -0,0 +1,14 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/model/opsdev/internal"
+)
+
+// OpsDeliveryProjectEvent is the golang structure for table ops_delivery_project_event.
+type OpsDeliveryProjectEvent internal.OpsDeliveryProjectEvent
+
+// Fill with you ideas below.

+ 14 - 0
opms_parent/app/model/opsdev/ops_delivery_project_event_attachment.go

@@ -0,0 +1,14 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/model/opsdev/internal"
+)
+
+// OpsDeliveryProjectEventAttachment is the golang structure for table ops_delivery_project_event_attachment.
+type OpsDeliveryProjectEventAttachment internal.OpsDeliveryProjectEventAttachment
+
+// Fill with you ideas below.

+ 14 - 0
opms_parent/app/model/opsdev/ops_delivery_project_event_record.go

@@ -0,0 +1,14 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package opsdev
+
+import (
+	"dashoo.cn/opms_parent/app/model/opsdev/internal"
+)
+
+// OpsDeliveryProjectEventRecord is the golang structure for table ops_delivery_project_event_record.
+type OpsDeliveryProjectEventRecord internal.OpsDeliveryProjectEventRecord
+
+// Fill with you ideas below.

+ 15 - 1
opms_parent/app/service/base.go

@@ -537,10 +537,11 @@ func CommonExportExcel(ctx context.Context, fileName string, exportStruct interf
 	headerStyle, err := xlsxFile.NewStyle(&excelize.Style{
 		Alignment: &excelize.Alignment{
 			Horizontal: "center",
+			Vertical:   "center",
 		},
 		Fill: excelize.Fill{
 			Type:    "pattern",
-			Color:   []string{"#a6a6a6"},
+			Color:   []string{"#CCE5FF"},
 			Pattern: 1,
 		},
 		Border: []excelize.Border{
@@ -554,8 +555,21 @@ func CommonExportExcel(ctx context.Context, fileName string, exportStruct interf
 
 	xlsxFile.SetColStyle("Sheet1", "A:"+lastColName, colStyle)
 	xlsxFile.SetCellStyle("Sheet1", "A1", lastColName+"1", headerStyle)
+	xlsxFile.SetRowHeight("Sheet1", 1, 40)
 	xlsxFile.SetColWidth("Sheet1", "A", lastColName, 20)
 
+	handleProcessColIndex := -1
+	for i, h := range headerList {
+		if h == "处理过程" {
+			handleProcessColIndex = i + 1
+			break
+		}
+	}
+	if handleProcessColIndex > 0 {
+		handleColName, _ := excelize.ColumnNumberToName(handleProcessColIndex)
+		xlsxFile.SetColWidth("Sheet1", handleColName, handleColName, 40)
+	}
+
 	xlsxFile.SetSheetName("Sheet1", fileName)
 	xlsxFile.SetSheetRow(fileName, "A1", &headerList)
 	if err != nil {

+ 312 - 2
opms_parent/app/service/opsdev/operation.go

@@ -3,6 +3,8 @@ package opsdev
 import (
 	"context"
 	"fmt"
+	"regexp"
+	"strings"
 
 	"dashoo.cn/common_definition/comm_def"
 	"dashoo.cn/opms_libary/myerrors"
@@ -757,9 +759,12 @@ func (s *OperationService) DeleteAttachment(req *comm_def.IdReq) error {
 	return nil
 }
 
-// GetHistoryList 运维历史列表(已关闭事件)
+// GetHistoryList 运维历史列表
 func (s *OperationService) GetHistoryList(req *opsdevmodel.OpsOperationEventHistorySearchReq) (total int, list []*opsdevmodel.OpsOperationEvent, err error) {
-	db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus, opsdevmodel.EventStatusClosed)
+	db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime)
+	if !req.IncludeClosed {
+		db = db.Where(s.Dao.Columns.EventStatus, opsdevmodel.EventStatusClosed)
+	}
 
 	if req.ScopeType == "my" {
 		db = db.Where(s.Dao.Columns.OpsUserId, s.GetCxtUserId())
@@ -798,3 +803,308 @@ func (s *OperationService) GetHistoryList(req *opsdevmodel.OpsOperationEventHist
 
 	return total, list, nil
 }
+
+// Export 导出运维历史
+func (s *OperationService) Export(ctx context.Context, req *opsdevmodel.OpsOperationEventHistoryExport) (content *opsdevmodel.OpsOperationEventHistoryExportContent, err error) {
+	db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime)
+	if !req.IncludeClosed {
+		db = db.Where(s.Dao.Columns.EventStatus, opsdevmodel.EventStatusClosed)
+	}
+
+	if req.ScopeType == "my" {
+		db = db.Where(s.Dao.Columns.OpsUserId, s.GetCxtUserId())
+	}
+	if req.EventTitle != "" {
+		db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.EventTitle+"%")
+	}
+	if req.CustName != "" {
+		db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.CustName+"%")
+	}
+	if req.FeedbackReporter != "" {
+		db = db.Where(s.Dao.Columns.FeedbackReporter+" like ?", "%"+req.FeedbackReporter+"%")
+	}
+	if req.OpsUserName != "" {
+		db = db.Where(s.Dao.Columns.OpsUserName+" like ?", "%"+req.OpsUserName+"%")
+	}
+	if req.BeginTime != "" {
+		db = db.Where(s.Dao.Columns.FeedbackDate+" >= ?", req.BeginTime)
+	}
+	if req.EndTime != "" {
+		db = db.Where(s.Dao.Columns.FeedbackDate+" <= ?", req.EndTime)
+	}
+
+	var list []*opsdevmodel.OpsOperationEvent
+	err = db.Order(s.Dao.Columns.CompleteTime + " desc").Scan(&list)
+	if err != nil {
+		g.Log().Error(err)
+		return nil, myerrors.DbError("查询运维历史失败")
+	}
+
+	// 获取所有事件ID
+	var eventIds []int
+	for _, item := range list {
+		eventIds = append(eventIds, item.Id)
+	}
+
+	// 获取所有事件的处理记录
+	var records []*opsdevmodel.OpsOperationEventRecord
+	if len(eventIds) > 0 {
+		err = s.RecordDao.WhereIn(s.RecordDao.Columns.EventId, eventIds).Order(s.RecordDao.Columns.HandleDate + " desc").Scan(&records)
+		if err != nil {
+			g.Log().Error(err)
+			return nil, myerrors.DbError("查询处理记录失败")
+		}
+	}
+
+	// 构建记录Map
+	recordMap := make(map[int][]*opsdevmodel.OpsOperationEventRecord)
+	for _, record := range records {
+		recordMap[record.EventId] = append(recordMap[record.EventId], record)
+	}
+
+	// 构建状态Map
+	statusMap := map[string]string{
+		opsdevmodel.EventStatusPending:          "待处理",
+		opsdevmodel.EventStatusProcessing:       "处理中(重点)",
+		opsdevmodel.EventStatusProcessingNormal: "处理中(普通)",
+		opsdevmodel.EventStatusTransfer:         "转研发",
+		opsdevmodel.EventStatusSuspended:        "挂起",
+		opsdevmodel.EventStatusClosed:           "已关闭",
+	}
+	// 构建操作类型Map
+	operateTypeMap := map[string]string{
+		opsdevmodel.OperateTypeProcess:  "处理",
+		opsdevmodel.OperateTypeResume:   "转处理",
+		opsdevmodel.OperateTypeTransfer: "转研发",
+		opsdevmodel.OperateTypeSuspend:  "挂起",
+		opsdevmodel.OperateTypeClose:    "关闭",
+	}
+	// 构建处理结果Map
+	handleResultMap := map[string]string{
+		opsdevmodel.HandleResultResolved:   "已解决",
+		opsdevmodel.HandleResultPartially:  "部分解决",
+		opsdevmodel.HandleResultUnresolved: "未解决",
+	}
+
+	// 构建导出数据
+	exportDataList := make([]map[string]interface{}, 0)
+	for _, item := range list {
+		// 构建处理过程
+		processBuilder := ""
+		if itemRecords, ok := recordMap[item.Id]; ok && len(itemRecords) > 0 {
+			for i, record := range itemRecords {
+				// 处理时间(仅年月)
+				handleDate := ""
+				if record.HandleDate != nil {
+					handleDate = record.HandleDate.Format("Y-m-d H:i:s")
+				}
+				// 操作类型描述
+				operateTypeStr := operateTypeMap[record.OperateType]
+				if operateTypeStr == "" {
+					operateTypeStr = record.OperateType
+				}
+				// 处理结果描述
+				handleResultStr := handleResultMap[record.HandleResult]
+				if handleResultStr == "" {
+					handleResultStr = record.HandleResult
+				}
+				// 清理处理内容中的HTML标签
+				cleanContent := cleanHtmlTags(record.HandleContent)
+
+				recordStr := fmt.Sprintf("%s-%s-%s-%s-%s", handleDate, record.HandleUserName, operateTypeStr, handleResultStr, cleanContent)
+				if i > 0 {
+					processBuilder += "\n" + recordStr
+				} else {
+					processBuilder = recordStr
+				}
+			}
+		}
+
+		closedTime := ""
+		if item.CompleteTime != nil {
+			closedTime = item.CompleteTime.Format("Y-m-d")
+		}
+
+		feedbackDate := ""
+		if item.FeedbackDate != nil {
+			feedbackDate = item.FeedbackDate.Format("Y-m-d")
+		}
+
+		exportData := map[string]interface{}{
+			"eventNo":       item.EventNo,
+			"eventTitle":    item.EventTitle,
+			"eventStatus":   statusMap[item.EventStatus],
+			"eventType":     item.EventType,
+			"custName":      item.CustName,
+			"opsUserName":   item.OpsUserName,
+			"feedbackDate":  feedbackDate,
+			"priorityLevel": item.PriorityLevel,
+			"handleProcess": processBuilder,
+			"closedTime":    closedTime,
+		}
+		exportDataList = append(exportDataList, exportData)
+	}
+
+	// 调用公共导出方法
+	exportContent := new(opsdevmodel.OpsOperationEventHistoryExportContent)
+	contentBase64, err := service.CommonExportExcel(ctx, "运维历史", opsdevmodel.OpsOperationEventHistoryExportData{}, exportDataList)
+	if err != nil {
+		g.Log().Error(err)
+		return nil, myerrors.DbError("导出运维历史失败")
+	}
+
+	exportContent.Content = contentBase64
+	return exportContent, nil
+}
+
+func (s *OperationService) ExportNonClosed(ctx context.Context, req *opsdevmodel.OpsOperationEventExport) (content *opsdevmodel.OpsOperationEventHistoryExportContent, err error) {
+	db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus+" != ?", opsdevmodel.EventStatusClosed)
+
+	var list []*opsdevmodel.OpsOperationEvent
+	err = db.Order(s.Dao.Columns.FeedbackDate + " desc").Scan(&list)
+	if err != nil {
+		g.Log().Error(err)
+		return nil, myerrors.DbError("查询运维事件失败")
+	}
+
+	var eventIds []int
+	for _, item := range list {
+		eventIds = append(eventIds, item.Id)
+	}
+
+	var records []*opsdevmodel.OpsOperationEventRecord
+	if len(eventIds) > 0 {
+		err = s.RecordDao.WhereIn(s.RecordDao.Columns.EventId, eventIds).Order(s.RecordDao.Columns.HandleDate + " desc").Scan(&records)
+		if err != nil {
+			g.Log().Error(err)
+			return nil, myerrors.DbError("查询处理记录失败")
+		}
+	}
+
+	recordMap := make(map[int][]*opsdevmodel.OpsOperationEventRecord)
+	for _, record := range records {
+		recordMap[record.EventId] = append(recordMap[record.EventId], record)
+	}
+
+	statusMap := map[string]string{
+		opsdevmodel.EventStatusPending:          "待处理",
+		opsdevmodel.EventStatusProcessing:       "处理中(重点)",
+		opsdevmodel.EventStatusProcessingNormal: "处理中(普通)",
+		opsdevmodel.EventStatusTransfer:         "转研发",
+		opsdevmodel.EventStatusSuspended:        "挂起",
+		opsdevmodel.EventStatusClosed:           "已关闭",
+	}
+
+	operateTypeMap := map[string]string{
+		opsdevmodel.OperateTypeProcess:  "处理",
+		opsdevmodel.OperateTypeResume:   "转处理",
+		opsdevmodel.OperateTypeTransfer: "转研发",
+		opsdevmodel.OperateTypeSuspend:  "挂起",
+		opsdevmodel.OperateTypeClose:    "关闭",
+	}
+
+	handleResultMap := map[string]string{
+		opsdevmodel.HandleResultResolved:   "已解决",
+		opsdevmodel.HandleResultPartially:  "部分解决",
+		opsdevmodel.HandleResultUnresolved: "未解决",
+	}
+
+	exportDataList := make([]map[string]interface{}, 0)
+	for _, item := range list {
+		processBuilder := ""
+		if itemRecords, ok := recordMap[item.Id]; ok && len(itemRecords) > 0 {
+			for i, record := range itemRecords {
+				handleDate := ""
+				if record.HandleDate != nil {
+					handleDate = record.HandleDate.Format("Y-m-d H:i:s")
+				}
+				operateTypeStr := operateTypeMap[record.OperateType]
+				if operateTypeStr == "" {
+					operateTypeStr = record.OperateType
+				}
+				handleResultStr := handleResultMap[record.HandleResult]
+				if handleResultStr == "" {
+					handleResultStr = record.HandleResult
+				}
+				cleanContent := cleanHtmlTags(record.HandleContent)
+
+				recordStr := fmt.Sprintf("%s-%s-%s-%s-%s", handleDate, record.HandleUserName, operateTypeStr, handleResultStr, cleanContent)
+				if i > 0 {
+					processBuilder += "\n" + recordStr
+				} else {
+					processBuilder = recordStr
+				}
+			}
+		}
+
+		feedbackDate := ""
+		if item.FeedbackDate != nil {
+			feedbackDate = item.FeedbackDate.Format("Y-m-d")
+		}
+
+		exportData := map[string]interface{}{
+			"eventNo":       item.EventNo,
+			"eventTitle":    item.EventTitle,
+			"eventStatus":   statusMap[item.EventStatus],
+			"eventType":     item.EventType,
+			"custName":      item.CustName,
+			"opsUserName":   item.OpsUserName,
+			"feedbackDate":  feedbackDate,
+			"priorityLevel": item.PriorityLevel,
+			"handleProcess": processBuilder,
+		}
+		exportDataList = append(exportDataList, exportData)
+	}
+
+	exportContent := new(opsdevmodel.OpsOperationEventHistoryExportContent)
+	contentBase64, err := service.CommonExportExcel(ctx, "运维事件", opsdevmodel.OpsOperationEventExportData{}, exportDataList)
+	if err != nil {
+		g.Log().Error(err)
+		return nil, myerrors.DbError("导出运维事件失败")
+	}
+
+	exportContent.Content = contentBase64
+	return exportContent, nil
+}
+
+func cleanHtmlTags(content string) string {
+	if content == "" {
+		return ""
+	}
+
+	imgPattern := regexp.MustCompile(`src=["']([^"']+)["']`)
+	imgMatches := imgPattern.FindAllStringSubmatch(content, -1)
+
+	seen := make(map[string]bool)
+	var imgUrls []string
+	for _, match := range imgMatches {
+		if len(match) > 1 && !seen[match[1]] {
+			seen[match[1]] = true
+			imgUrls = append(imgUrls, match[1])
+		}
+	}
+
+	htmlTagPattern := regexp.MustCompile(`<[^>]*>`)
+	result := htmlTagPattern.ReplaceAllString(content, "")
+
+	result = strings.ReplaceAll(result, "&nbsp;", " ")
+	result = strings.ReplaceAll(result, "&amp;", "&")
+	result = strings.ReplaceAll(result, "&lt;", "<")
+	result = strings.ReplaceAll(result, "&gt;", ">")
+	result = strings.ReplaceAll(result, "&quot;", "\"")
+	result = strings.ReplaceAll(result, "&#39;", "'")
+
+	result = strings.TrimSpace(result)
+
+	if len(imgUrls) > 0 {
+		result += "\n图片: "
+		for i, url := range imgUrls {
+			if i > 0 {
+				result += ", "
+			}
+			result += url
+		}
+	}
+
+	return result
+}

+ 105 - 0
opms_storage/.idea/workspace.xml

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AutoImportSettings">
+    <option name="autoReloadType" value="ALL" />
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="4b134288-d3a1-4921-afb3-1d33e2bcaa16" name="更改" comment="">
+      <change beforePath="$PROJECT_DIR$/../opms_parent/app/dao/opsdev/internal/ops_operation_event.go" beforeDir="false" afterPath="$PROJECT_DIR$/../opms_parent/app/dao/opsdev/internal/ops_operation_event.go" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/../opms_parent/app/handler/opsdev/operation.go" beforeDir="false" afterPath="$PROJECT_DIR$/../opms_parent/app/handler/opsdev/operation.go" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/../opms_parent/app/model/opsdev/internal/ops_operation_event.go" beforeDir="false" afterPath="$PROJECT_DIR$/../opms_parent/app/model/opsdev/internal/ops_operation_event.go" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/../opms_parent/app/model/opsdev/operation.go" beforeDir="false" afterPath="$PROJECT_DIR$/../opms_parent/app/model/opsdev/operation.go" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/../opms_parent/app/service/base.go" beforeDir="false" afterPath="$PROJECT_DIR$/../opms_parent/app/service/base.go" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/../opms_parent/app/service/opsdev/operation.go" beforeDir="false" afterPath="$PROJECT_DIR$/../opms_parent/app/service/opsdev/operation.go" afterDir="false" />
+    </list>
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="CopilotPersistence">
+    <persistenceIdMap>
+      <entry key="_/Users/chengjian/Develop/Workspaces/Dashoo/opms/opms_backend/opms_storage" value="3CmiPwTI9Be7pc9cd8buZJAHuz2" />
+    </persistenceIdMap>
+  </component>
+  <component name="GOROOT" url="file://$USER_HOME$/go/go1.24.13" />
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
+  </component>
+  <component name="ProjectColorInfo">{
+  &quot;associatedIndex&quot;: 4
+}</component>
+  <component name="ProjectId" id="3CmiPwTI9Be7pc9cd8buZJAHuz2" />
+  <component name="ProjectViewState">
+    <option name="hideEmptyMiddlePackages" value="true" />
+    <option name="showLibraryContents" value="true" />
+  </component>
+  <component name="PropertiesComponent"><![CDATA[{
+  "keyToString": {
+    "Go 构建.go build opms_storage/cmd/server.executor": "Run",
+    "ModuleVcsDetector.initialDetectionPerformed": "true",
+    "RunOnceActivity.GoLinterPluginOnboarding": "true",
+    "RunOnceActivity.GoLinterPluginStorageMigration": "true",
+    "RunOnceActivity.ShowReadmeOnStart": "true",
+    "RunOnceActivity.git.unshallow": "true",
+    "RunOnceActivity.go.formatter.settings.were.checked": "true",
+    "RunOnceActivity.go.migrated.go.modules.settings": "true",
+    "RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
+    "git-widget-placeholder": "develop",
+    "go.import.settings.migrated": "true",
+    "last_opened_file_path": "/Users/chengjian",
+    "node.js.detected.package.eslint": "true",
+    "node.js.selected.package.eslint": "(autodetect)",
+    "nodejs_package_manager_path": "npm",
+    "settings.editor.selected.configurable": "preferences.pluginManager"
+  }
+}]]></component>
+  <component name="RunManager">
+    <configuration name="go build opms_storage/cmd/server" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
+      <module name="opms_storage" />
+      <working_directory value="$PROJECT_DIR$" />
+      <kind value="PACKAGE" />
+      <package value="opms_storage/cmd/server" />
+      <directory value="$PROJECT_DIR$" />
+      <filePath value="$PROJECT_DIR$/cmd/server/main.go" />
+      <method v="2" />
+    </configuration>
+    <recent_temporary>
+      <list>
+        <item itemvalue="Go 构建.go build opms_storage/cmd/server" />
+      </list>
+    </recent_temporary>
+  </component>
+  <component name="SharedIndexes">
+    <attachedChunks>
+      <set>
+        <option value="bundled-gosdk-3b128438d3f6-34ac7aa8f6ab-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-251.23774.430" />
+        <option value="bundled-js-predefined-d6986cc7102b-f27c65a3e318-JavaScript-GO-251.23774.430" />
+      </set>
+    </attachedChunks>
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="默认任务">
+      <changelist id="4b134288-d3a1-4921-afb3-1d33e2bcaa16" name="更改" comment="" />
+      <created>1776997126543</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1776997126543</updated>
+    </task>
+    <servers />
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="3" />
+  </component>
+  <component name="VgoProject">
+    <settings-migrated>true</settings-migrated>
+  </component>
+  <component name="github-copilot-workspace">
+    <instructionFileLocations>
+      <option value=".github/instructions" />
+    </instructionFileLocations>
+    <promptFileLocations>
+      <option value=".github/prompts" />
+    </promptFileLocations>
+  </component>
+</project>