Explorar o código

feature: 添加合同创建审批、去掉 sys 相关表

liuyaqi %!s(int64=2) %!d(string=hai) anos
pai
achega
fae1523b30

+ 1 - 1
opms_parent/app/dao/contract/internal/ctr_contract.go

@@ -33,7 +33,7 @@ type ctrContractColumns struct {
 	CustName          string // 客户名称
 	NboId             string // 关联项目
 	NboName           string // 项目名称
-	ApproStatus       string // 审批状态
+	ApproStatus       string // 审核状态 10 待提交审核 20 待审核 30 审核已同意 40 审核已拒绝 50 审核已撤销
 	ContractType      string // 合同类型
 	ContractAmount    string // 合同金额
 	InvoiceAmount     string // 已开票金额

+ 0 - 459
opms_parent/app/dao/sys/internal/sys_user.go

@@ -1,459 +0,0 @@
-// ==========================================================================
-// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
-// ==========================================================================
-
-package internal
-
-import (
-	"context"
-	"database/sql"
-	"github.com/gogf/gf/database/gdb"
-	"github.com/gogf/gf/frame/g"
-	"github.com/gogf/gf/frame/gmvc"
-	"time"
-
-	model "dashoo.cn/micro/app/model/sys"
-)
-
-// SysUserDao is the manager for logic model data accessing
-// and custom defined data operations functions management.
-type SysUserDao struct {
-	gmvc.M
-	DB      gdb.DB
-	Table   string
-	Columns sysUserColumns
-}
-
-// SysUserColumns defines and stores column names for table sys_user.
-type sysUserColumns struct {
-	Id          string // 用户ID
-	DeptId      string // 部门ID
-	UserName    string // 用户账号
-	NickName    string // 用户昵称
-	UserType    string // 用户类型(00系统用户)
-	Email       string // 用户邮箱
-	Phone       string // 手机号码
-	Sex         string // 用户性别(10男20女30未知)
-	Avatar      string // 头像地址
-	Password    string // 密码
-	LoginIp     string // 最后登录IP
-	LoginDate   string // 最后登录时间
-	Remark      string // 备注
-	CreatedBy   string // 创建者
-	CreatedName string // 创建人
-	CreatedTime string // 创建时间
-	UpdatedBy   string // 更新者
-	UpdatedName string // 更新人
-	UpdatedTime string // 更新时间
-	DeletedTime string // 删除时间
-	Status      string // 帐号状态(10正常20停用)
-	UserSalt    string // 加密盐
-}
-
-var (
-	// SysUser is globally public accessible object for table sys_user operations.
-	SysUser = SysUserDao{
-		M:     g.DB("default").Model("sys_user").Safe(),
-		DB:    g.DB("default"),
-		Table: "sys_user",
-		Columns: sysUserColumns{
-			Id:          "id",
-			DeptId:      "dept_id",
-			UserName:    "user_name",
-			NickName:    "nick_name",
-			UserType:    "user_type",
-			Email:       "email",
-			Phone:       "phone",
-			Sex:         "sex",
-			Avatar:      "avatar",
-			Password:    "password",
-			LoginIp:     "login_ip",
-			LoginDate:   "login_date",
-			Remark:      "remark",
-			CreatedBy:   "created_by",
-			CreatedName: "created_name",
-			CreatedTime: "created_time",
-			UpdatedBy:   "updated_by",
-			UpdatedName: "updated_name",
-			UpdatedTime: "updated_time",
-			DeletedTime: "deleted_time",
-			Status:      "status",
-			UserSalt:    "user_salt",
-		},
-	}
-)
-
-func NewSysUserDao(tenant string) SysUserDao {
-	var dao SysUserDao
-	dao = SysUserDao{
-		M:     g.DB(tenant).Model("sys_user").Safe(),
-		DB:    g.DB(tenant),
-		Table: "sys_user",
-		Columns: sysUserColumns{
-			Id:          "id",
-			DeptId:      "dept_id",
-			UserName:    "user_name",
-			NickName:    "nick_name",
-			UserType:    "user_type",
-			Email:       "email",
-			Phone:       "phone",
-			Sex:         "sex",
-			Avatar:      "avatar",
-			Password:    "password",
-			LoginIp:     "login_ip",
-			LoginDate:   "login_date",
-			Remark:      "remark",
-			CreatedBy:   "created_by",
-			CreatedName: "created_name",
-			CreatedTime: "created_time",
-			UpdatedBy:   "updated_by",
-			UpdatedName: "updated_name",
-			UpdatedTime: "updated_time",
-			DeletedTime: "deleted_time",
-			Status:      "status",
-			UserSalt:    "user_salt",
-		},
-	}
-	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 *SysUserDao) Ctx(ctx context.Context) *SysUserDao {
-	return &SysUserDao{M: d.M.Ctx(ctx)}
-}
-
-// As sets an alias name for current table.
-func (d *SysUserDao) As(as string) *SysUserDao {
-	return &SysUserDao{M: d.M.As(as)}
-}
-
-// TX sets the transaction for current operation.
-func (d *SysUserDao) TX(tx *gdb.TX) *SysUserDao {
-	return &SysUserDao{M: d.M.TX(tx)}
-}
-
-// Master marks the following operation on master node.
-func (d *SysUserDao) Master() *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Slave() *SysUserDao {
-	return &SysUserDao{M: d.M.Slave()}
-}
-
-// Args sets custom arguments for model operation.
-func (d *SysUserDao) Args(args ...interface{}) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) LeftJoin(table ...string) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) RightJoin(table ...string) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) InnerJoin(table ...string) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysUserDao {
-	return &SysUserDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
-}
-
-// Option sets the extra operation option for the model.
-func (d *SysUserDao) Option(option int) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) OmitEmpty() *SysUserDao {
-	return &SysUserDao{M: d.M.OmitEmpty()}
-}
-
-// Filter marks filtering the fields which does not exist in the fields of the operated table.
-func (d *SysUserDao) Filter() *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Where(where interface{}, args ...interface{}) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) WherePri(where interface{}, args ...interface{}) *SysUserDao {
-	return &SysUserDao{M: d.M.WherePri(where, args...)}
-}
-
-// And adds "AND" condition to the where statement.
-func (d *SysUserDao) And(where interface{}, args ...interface{}) *SysUserDao {
-	return &SysUserDao{M: d.M.And(where, args...)}
-}
-
-// Or adds "OR" condition to the where statement.
-func (d *SysUserDao) Or(where interface{}, args ...interface{}) *SysUserDao {
-	return &SysUserDao{M: d.M.Or(where, args...)}
-}
-
-// Group sets the "GROUP BY" statement for the model.
-func (d *SysUserDao) Group(groupBy string) *SysUserDao {
-	return &SysUserDao{M: d.M.Group(groupBy)}
-}
-
-// Order sets the "ORDER BY" statement for the model.
-func (d *SysUserDao) Order(orderBy ...string) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Limit(limit ...int) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Offset(offset int) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Page(page, limit int) *SysUserDao {
-	return &SysUserDao{M: d.M.Page(page, limit)}
-}
-
-// Batch sets the batch operation number for the model.
-func (d *SysUserDao) Batch(batch int) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Cache(duration time.Duration, name ...string) *SysUserDao {
-	return &SysUserDao{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 *SysUserDao) Data(data ...interface{}) *SysUserDao {
-	return &SysUserDao{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.SysUser.
-// 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 *SysUserDao) All(where ...interface{}) ([]*model.SysUser, error) {
-	all, err := d.M.All(where...)
-	if err != nil {
-		return nil, err
-	}
-	var entities []*model.SysUser
-	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.SysUser.
-// 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 *SysUserDao) One(where ...interface{}) (*model.SysUser, error) {
-	one, err := d.M.One(where...)
-	if err != nil {
-		return nil, err
-	}
-	var entity *model.SysUser
-	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 *SysUserDao) FindOne(where ...interface{}) (*model.SysUser, error) {
-	one, err := d.M.FindOne(where...)
-	if err != nil {
-		return nil, err
-	}
-	var entity *model.SysUser
-	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 *SysUserDao) FindAll(where ...interface{}) ([]*model.SysUser, error) {
-	all, err := d.M.FindAll(where...)
-	if err != nil {
-		return nil, err
-	}
-	var entities []*model.SysUser
-	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 *SysUserDao) 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 *SysUserDao) 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 *SysUserDao) Scan(pointer interface{}, where ...interface{}) error {
-	return d.M.Scan(pointer, where...)
-}
-
-// Chunk iterates the table with given size and callback function.
-func (d *SysUserDao) Chunk(limit int, callback func(entities []*model.SysUser, err error) bool) {
-	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
-		var entities []*model.SysUser
-		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 *SysUserDao) LockUpdate() *SysUserDao {
-	return &SysUserDao{M: d.M.LockUpdate()}
-}
-
-// LockShared sets the lock in share mode for current operation.
-func (d *SysUserDao) LockShared() *SysUserDao {
-	return &SysUserDao{M: d.M.LockShared()}
-}
-
-// Unscoped enables/disables the soft deleting feature.
-func (d *SysUserDao) Unscoped() *SysUserDao {
-	return &SysUserDao{M: d.M.Unscoped()}
-}

+ 0 - 36
opms_parent/app/dao/sys/sys_user.go

@@ -1,36 +0,0 @@
-// ============================================================================
-// This is auto-generated by gf cli tool only once. Fill this file as you wish.
-// ============================================================================
-
-package dao
-
-import (
-	"dashoo.cn/micro/app/dao/sys/internal"
-)
-
-// sysUserDao 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 sysUserDao struct {
-	internal.SysUserDao
-}
-
-var (
-	// SysUser is globally public accessible object for table sys_user operations.
-	SysUser = sysUserDao{
-		internal.SysUser,
-	}
-)
-
-type SysUserDao struct {
-	internal.SysUserDao
-}
-
-func NewSysUserDao(tenant string) *SysUserDao {
-	dao := internal.NewSysUserDao(tenant)
-	return &SysUserDao{
-		dao,
-	}
-}
-
-// Fill with you ideas below.

+ 14 - 0
opms_parent/app/handler/contract/ctr_contract.go

@@ -100,6 +100,20 @@ func (c *CtrContract) Add(ctx context.Context, req *model.CtrContractAddReq, rsp
 	return nil
 }
 
+// Swagger:CtrContract 合同,测试tag 提交审核
+func (c *CtrContract) Commit(ctx context.Context, req *model.CtrContractCommitReq, rsp *comm_def.CommonMsg) error {
+	g.Log().Infof("CtrContract.Commit request %#v ", *req)
+	s, err := service.NewCtrContractService(ctx)
+	if err != nil {
+		return err
+	}
+	err = s.Commit(ctx, req)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
 // Swagger:CtrContract 合同,测试tag 更新合同
 func (c *CtrContract) Update(ctx context.Context, req *model.CtrContractUpdateReq, rsp *comm_def.CommonMsg) error {
 	g.Log().Infof("CtrContract.Update request %#v ", *req)

+ 14 - 11
opms_parent/app/handler/dingtalk/ding_event.go

@@ -169,6 +169,20 @@ func (h *DingHandler) handleBpmsInstanceChange(msg *message.MixMessage, ctx *din
 			return err.Error()
 		}
 		return "success"
+	case model.ContractCreate:
+		if msg.ProcessType == "finish" || msg.ProcessType == "terminate" {
+			err = contractSrv.ContractApplyApproval(ctx.SubsMessage.Ctx, instance, msg)
+			if err != nil {
+				glog.Error(err)
+				return err.Error()
+			}
+		}
+		err = s.Update(instance, msg)
+		if err != nil {
+			glog.Error(err)
+			return err.Error()
+		}
+		return "success"
 	case model.ProjectUpGrade:
 		if msg.ProcessType == "finish" || msg.ProcessType == "terminate" {
 			srv, err := projService.NewBusinessService(ctx.SubsMessage.Ctx)
@@ -245,17 +259,6 @@ func (h *DingHandler) handleBpmsInstanceChange(msg *message.MixMessage, ctx *din
 			return err.Error()
 		}
 		return "success"
-
-	case model.ContractCreate:
-		if msg.ProcessType == "finish" || msg.ProcessType == "terminate" {
-			//srv.Handle(instance, msg)
-		}
-		err = s.Update(instance, msg)
-		if err != nil {
-			glog.Error(err)
-			return err.Error()
-		}
-		return "success"
 	}
 
 	// 以下的代码需要调用钉钉接口查询数据,并且以下接口需要审批实例的数据

+ 16 - 0
opms_parent/app/model/contract/ctr_contract.go

@@ -122,3 +122,19 @@ type CtrContractTransferReq struct {
 	InchargeId   int    `json:"inchargeId"`   // 负责人ID
 	InchargeName string `json:"inchargeName"` // 负责人
 }
+
+type DingFileInfo struct {
+	SpaceId  string `json:"spaceId"`  // 空间ID
+	FileId   string `json:"fileId"`   // 文件ID
+	FileName string `json:"fileName"` //文件名
+	FileSize int    `json:"fileSize"` // 文件大小
+	FileType string `json:"fileType"` // 文件类型
+}
+
+type CtrContractCommitReq struct {
+	Id            int            `json:"id" v:"required#请输入Id"`
+	ContractModel string         `json:"contractModel"` // 合同模板 值可以是:大数模板, 客户模板
+	Terms         string         `json:"terms"`         // 条款情况 值可以是:接纳全部条款, 不接纳全部条款
+	PayTerms      string         `json:"payTerms"`      // 付款条件
+	File          []DingFileInfo `json:"file"`          // 附件
+}

+ 1 - 1
opms_parent/app/model/contract/internal/ctr_contract.go

@@ -17,7 +17,7 @@ type CtrContract struct {
 	CustName          string      `orm:"cust_name"           json:"custName"`          // 客户名称
 	NboId             int         `orm:"nbo_id"              json:"nboId"`             // 关联项目
 	NboName           string      `orm:"nbo_name"            json:"nboName"`           // 项目名称
-	ApproStatus       string      `orm:"appro_status"        json:"approStatus"`       // 审批状态
+	ApproStatus       string      `orm:"appro_status"        json:"approStatus"`       // 审核状态 10 待提交审核 20 待审核 30 审核已同意 40 审核已拒绝 50 审核已撤销
 	ContractType      string      `orm:"contract_type"       json:"contractType"`      // 合同类型
 	ContractAmount    float64     `orm:"contract_amount"     json:"contractAmount"`    // 合同金额
 	InvoiceAmount     float64     `orm:"invoice_amount"      json:"invoiceAmount"`     // 已开票金额

+ 0 - 35
opms_parent/app/model/sys/internal/sys_user.go

@@ -1,35 +0,0 @@
-// ==========================================================================
-// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
-// ==========================================================================
-
-package internal
-
-import (
-	"github.com/gogf/gf/os/gtime"
-)
-
-// SysUser is the golang structure for table sys_user.
-type SysUser struct {
-	Id          int         `orm:"id,primary"   json:"id"`          // 用户ID
-	DeptId      int         `orm:"dept_id"      json:"deptId"`      // 部门ID
-	UserName    string      `orm:"user_name"    json:"userName"`    // 用户账号
-	NickName    string      `orm:"nick_name"    json:"nickName"`    // 用户昵称
-	UserType    string      `orm:"user_type"    json:"userType"`    // 用户类型(00系统用户)
-	Email       string      `orm:"email"        json:"email"`       // 用户邮箱
-	Phone       string      `orm:"phone"        json:"phone"`       // 手机号码
-	Sex         string      `orm:"sex"          json:"sex"`         // 用户性别(10男20女30未知)
-	Avatar      string      `orm:"avatar"       json:"avatar"`      // 头像地址
-	Password    string      `orm:"password"     json:"password"`    // 密码
-	LoginIp     string      `orm:"login_ip"     json:"loginIp"`     // 最后登录IP
-	LoginDate   *gtime.Time `orm:"login_date"   json:"loginDate"`   // 最后登录时间
-	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"` // 删除时间
-	Status      string      `orm:"status"       json:"status"`      // 帐号状态(10正常20停用)
-	UserSalt    string      `orm:"user_salt"    json:"userSalt"`    // 加密盐
-}

+ 0 - 12
opms_parent/app/model/sys/sys_user.go

@@ -1,12 +0,0 @@
-// ==========================================================================
-// This is auto-generated by gf cli tool. Fill this file as you wish.
-// ==========================================================================
-
-package model
-
-import (
-	"dashoo.cn/micro/app/model/sys/internal"
-)
-
-// SysUser is the golang structure for table sys_user.
-type SysUser internal.SysUser

+ 173 - 20
opms_parent/app/service/contract/ctr_contract.go

@@ -5,20 +5,26 @@ import (
 	"database/sql"
 	"encoding/json"
 	"fmt"
+	"strconv"
 	"time"
 
 	basedao "dashoo.cn/micro/app/dao/base"
 	dao "dashoo.cn/micro/app/dao/contract"
 	custdao "dashoo.cn/micro/app/dao/cust"
 	projdao "dashoo.cn/micro/app/dao/proj"
-	sysdao "dashoo.cn/micro/app/dao/sys"
 	model "dashoo.cn/micro/app/model/contract"
 	proj "dashoo.cn/micro/app/model/proj"
+	workflowModel "dashoo.cn/micro/app/model/workflow"
 	"dashoo.cn/micro/app/service"
+	projsrv "dashoo.cn/micro/app/service/proj"
+	workflowService "dashoo.cn/micro/app/service/workflow"
 
 	"dashoo.cn/opms_libary/micro_srv"
 	"dashoo.cn/opms_libary/myerrors"
+	"dashoo.cn/opms_libary/plugin/dingtalk/message"
+	"dashoo.cn/opms_libary/plugin/dingtalk/workflow"
 	"dashoo.cn/opms_libary/request"
+	"dashoo.cn/opms_libary/utils"
 	"github.com/gogf/gf/database/gdb"
 	"github.com/gogf/gf/os/gtime"
 	"github.com/gogf/gf/util/gvalid"
@@ -28,7 +34,6 @@ type CtrContractService struct {
 	Dao             *dao.CtrContractDao
 	ProjBusinessDao *projdao.ProjBusinessDao
 	CustomerDao     *custdao.CustCustomerDao
-	UserDao         *sysdao.SysUserDao
 	CtrProductDao   *dao.CtrContractProductDao
 	ProductDao      *basedao.BaseProductDao
 	DynamicsDao     *dao.CtrContractDynamicsDao
@@ -52,7 +57,6 @@ func NewCtrContractService(ctx context.Context) (*CtrContractService, error) {
 		Dao:             dao.NewCtrContractDao(tenant),
 		ProjBusinessDao: projdao.NewProjBusinessDao(tenant),
 		CustomerDao:     custdao.NewCustCustomerDao(tenant),
-		UserDao:         sysdao.NewSysUserDao(tenant),
 		CtrProductDao:   dao.NewCtrContractProductDao(tenant),
 		ProductDao:      basedao.NewBaseProductDao(tenant),
 		DynamicsDao:     dao.NewCtrContractDynamicsDao(tenant),
@@ -233,7 +237,7 @@ func (s CtrContractService) List(ctx context.Context, req *model.CtrContractList
 func (s CtrContractService) BindProduct(tx *gdb.TX, id int, product []model.CtrAddProduct) error {
 	var amount float64
 	for _, p := range product {
-		amount += p.TranPrice
+		amount += (p.TranPrice * float64(p.ProdNum))
 	}
 
 	_, err := tx.Delete("ctr_contract_product", "contract_id = ?", id)
@@ -309,40 +313,47 @@ func (s CtrContractService) Add(ctx context.Context, req *model.CtrContractAddRe
 		return 0, myerrors.TipsError(validErr.Current().Error())
 	}
 
-	sequence, err := service.Sequence(s.Dao.DB, "contract_code")
+	c, err := s.Dao.Where("contract_name = ?", req.ContractName).One()
 	if err != nil {
 		return 0, err
 	}
-	if req.ContractCode == "" {
-		req.ContractCode = fmt.Sprintf("DS%s%s%s", req.ContractType, time.Now().Format("0601"), sequence)
+	if c != nil {
+		return 0, myerrors.TipsError(fmt.Sprintf("合同名称:%s 已存在", req.ContractName))
 	}
-
-	c, err := s.Dao.Where("contract_code = ?", req.ContractCode).One()
+	nbo, err := s.ProjBusinessDao.Where("id = ?", req.NboId).One()
 	if err != nil {
 		return 0, err
 	}
-	if c != nil {
-		return 0, myerrors.TipsError(fmt.Sprintf("合同编号:%s 已存在", req.ContractCode))
+	if nbo == nil {
+		return 0, myerrors.TipsError("项目不存在")
 	}
-	c, err = s.Dao.Where("contract_name = ?", req.ContractName).One()
+	c, err = s.Dao.Where("nbo_id = ?", req.NboId).One()
 	if err != nil {
 		return 0, err
 	}
 	if c != nil {
-		return 0, myerrors.TipsError(fmt.Sprintf("合同名称:%s 已存在", req.ContractName))
+		return 0, myerrors.TipsError("所选项目已添加合同")
 	}
-	nbo, err := s.ProjBusinessDao.Where("id = ?", req.NboId).One()
+
+	sequence, err := service.Sequence(s.Dao.DB, "contract_code")
 	if err != nil {
 		return 0, err
 	}
-	if nbo == nil {
-		return 0, myerrors.TipsError("项目不存在")
+	if req.ContractCode == "" {
+		req.ContractCode = fmt.Sprintf("DS%s%s%s", req.ContractType, time.Now().Format("0601"), sequence)
+	}
+	c, err = s.Dao.Where("contract_code = ?", req.ContractCode).One()
+	if err != nil {
+		return 0, err
 	}
+	if c != nil {
+		return 0, myerrors.TipsError(fmt.Sprintf("合同编号:%s 已存在", req.ContractCode))
+	}
+
 	var contractAmount float64
 	for _, p := range req.Product {
-		contractAmount += p.TranPrice
+		contractAmount += (p.TranPrice * float64(p.ProdNum))
 	}
-
 	ctr := model.CtrContract{
 		ContractCode:      req.ContractCode,
 		ContractName:      req.ContractName,
@@ -350,7 +361,7 @@ func (s CtrContractService) Add(ctx context.Context, req *model.CtrContractAddRe
 		CustName:          nbo.CustName,
 		NboId:             nbo.Id,
 		NboName:           nbo.NboName,
-		ApproStatus:       "",
+		ApproStatus:       "10",
 		ContractType:      req.ContractType,
 		ContractAmount:    contractAmount,
 		InvoiceAmount:     0,
@@ -389,12 +400,154 @@ func (s CtrContractService) Add(ctx context.Context, req *model.CtrContractAddRe
 		if err != nil {
 			return err
 		}
+		_, err = tx.Update("proj_business", map[string]interface{}{
+			"nbo_type": projsrv.StatusDeal,
+		}, "id = ?", nbo.Id)
+		if err != nil {
+			return err
+		}
 		id = int(ctrid)
 		return nil
 	})
 	return id, txerr
 }
 
+var ContractApplyProcessCode = "PROC-7057E20A-2066-4644-9B35-9331E4DA912C" // 创建合同
+
+func (s CtrContractService) Commit(ctx context.Context, req *model.CtrContractCommitReq) error {
+	validErr := gvalid.CheckStruct(ctx, req, nil)
+	if validErr != nil {
+		return myerrors.TipsError(validErr.Current().Error())
+	}
+	if !(req.ContractModel == "大数模板" || req.ContractModel == "客户模板") {
+		return myerrors.TipsError("合同模板不合法")
+	}
+	if !(req.Terms == "接纳全部条款" || req.Terms == "不接纳全部条款") {
+		return myerrors.TipsError("条款情况不合法")
+	}
+	if req.PayTerms == "" {
+		return myerrors.TipsError("付款条件不能为空")
+	}
+	if len(req.File) == 0 {
+		return myerrors.TipsError("附件不能为空")
+	}
+
+	ent, err := s.Dao.Where("id = ?", req.Id).One()
+	if err != nil {
+		return err
+	}
+	if ent == nil {
+		return myerrors.TipsError(fmt.Sprintf("合同不存在: %d", req.Id))
+	}
+
+	fileinfoByte, err := json.Marshal(req.File)
+	if err != nil {
+		return err
+	}
+
+	workflowSrv, err := workflowService.NewFlowService(ctx)
+	if err != nil {
+		return err
+	}
+	bizCode := strconv.Itoa(ent.Id)
+	_, err = workflowSrv.StartProcessInstance(bizCode, "30", "", &workflow.StartProcessInstanceRequest{
+		ProcessCode: &ContractApplyProcessCode,
+		FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
+			{
+				Id:    utils.String("DDSelectField_ESX8H30W3VK0"),
+				Name:  utils.String("合同模板"),
+				Value: utils.String(req.ContractModel),
+			},
+			{
+				Id:    utils.String("DDSelectField_13IQX96C2KAK0"),
+				Name:  utils.String("条款情况"),
+				Value: utils.String(req.Terms),
+			},
+			{
+				Id:    utils.String("TextField_1A5SA7VOG5TS0"),
+				Name:  utils.String("合同编号"),
+				Value: utils.String(ent.ContractCode),
+			},
+			{
+				Id:    utils.String("TextField_1EX61DPS3LA80"),
+				Name:  utils.String("客户名称"),
+				Value: utils.String(ent.CustName),
+			},
+			{
+				Id:    utils.String("MoneyField_X1XV4KIR0GW0"),
+				Name:  utils.String("合同金额(元)"),
+				Value: utils.String(strconv.FormatFloat(ent.ContractAmount, 'f', 2, 64)),
+			},
+			{
+				Id:    utils.String("TextareaField_1WZ5ILKBUVSW0"),
+				Name:  utils.String("付款条件"),
+				Value: utils.String(req.PayTerms),
+			},
+			{
+				Id:   utils.String("DDAttachment_1051KJYC3MBK0"),
+				Name: utils.String("附件"),
+				// Details: productForm,
+				Value: utils.String(string(fileinfoByte)),
+			},
+		},
+	})
+	if err != nil {
+		return err
+	}
+
+	_, err = s.Dao.Where("id = ?", ent.Id).Data(map[string]interface{}{
+		"appro_status": 20,
+	}).Update()
+	return err
+}
+
+func ContractApplyApproval(ctx context.Context, flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
+	tenant, err := micro_srv.GetTenant(ctx)
+	if err != nil {
+		return fmt.Errorf("获取租户码异常:%s", err.Error())
+	}
+	contractDao := dao.NewCtrContractDao(tenant)
+
+	contractId, err := strconv.Atoi(flow.BizCode)
+	if err != nil {
+		return fmt.Errorf("创建合同审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
+	}
+	contract, err := contractDao.Where("id = ?", contractId).One()
+	if err != nil {
+		return err
+	}
+	if contract == nil {
+		return fmt.Errorf("合同不存在:%s Id: %d", flow.BizCode, flow.Id)
+	}
+
+	if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
+		return fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
+	}
+	if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
+		return fmt.Errorf("无法识别的 Result :%s", msg.Result)
+	}
+
+	if msg.ProcessType == "terminate" {
+		_, err = contractDao.Where("id = ?", contractId).Data(map[string]interface{}{
+			"appro_status": "50",
+		}).Update()
+		return err
+	}
+
+	pass := msg.Result == "agree"
+	if !pass {
+		_, err = contractDao.Where("id = ?", contractId).Data(map[string]interface{}{
+			"appro_status": "40",
+		}).Update()
+		return err
+	}
+
+	_, err = contractDao.Where("id = ?", contractId).Data(map[string]interface{}{
+		"appro_status": "30",
+	}).Update()
+	return err
+}
+
 func (s CtrContractService) Update(ctx context.Context, req *model.CtrContractUpdateReq) error {
 	validErr := gvalid.CheckStruct(ctx, req, nil)
 	if validErr != nil {
@@ -506,7 +659,7 @@ func (s CtrContractService) Update(ctx context.Context, req *model.CtrContractUp
 	if req.Product != nil {
 		var contractAmount float64
 		for _, p := range *req.Product {
-			contractAmount += p.TranPrice
+			contractAmount += (p.TranPrice * float64(p.ProdNum))
 		}
 		toupdate["contract_amount"] = contractAmount
 	}

+ 1 - 16
opms_parent/app/service/contract/ctr_contract_invoice.go

@@ -10,7 +10,6 @@ import (
 
 	dao "dashoo.cn/micro/app/dao/contract"
 	customerDao "dashoo.cn/micro/app/dao/cust"
-	sysDao "dashoo.cn/micro/app/dao/sys"
 	model "dashoo.cn/micro/app/model/contract"
 	workflowModel "dashoo.cn/micro/app/model/workflow"
 	workflowService "dashoo.cn/micro/app/service/workflow"
@@ -30,7 +29,6 @@ type CtrContractInvoiceService struct {
 	Dao         *dao.CtrContractInvoiceDao
 	ContractDao *dao.CtrContractDao
 	CustomerDao *customerDao.CustCustomerDao
-	UserDao     *sysDao.SysUserDao
 	ctrSrv      *CtrContractService
 	Tenant      string
 	userInfo    request.UserInfo
@@ -55,7 +53,6 @@ func NewCtrContractInvoiceService(ctx context.Context) (*CtrContractInvoiceServi
 		Dao:         dao.NewCtrContractInvoiceDao(tenant),
 		ContractDao: dao.NewCtrContractDao(tenant),
 		CustomerDao: customerDao.NewCustCustomerDao(tenant),
-		UserDao:     sysDao.NewSysUserDao(tenant),
 		ctrSrv:      ctrSrv,
 		Tenant:      tenant,
 		userInfo:    userInfo,
@@ -391,7 +388,7 @@ func (s CtrContractInvoiceService) InvoiceApply(ctx context.Context, req *model.
 		strconv.Itoa(invoice.Id),
 		strconv.Itoa(s.userInfo.Id),
 	}, ":")
-	_, err = workflowSrv.StartProcessInstance(bizCode, "31", &workflow.StartProcessInstanceRequest{
+	_, err = workflowSrv.StartProcessInstance(bizCode, "31", "", &workflow.StartProcessInstanceRequest{
 		ProcessCode: &InvoiceApplyProcessCode,
 		FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 			{
@@ -453,7 +450,6 @@ func InvoiceApplyApproval(ctx context.Context, flow *workflowModel.PlatWorkflow,
 		return fmt.Errorf("获取租户码异常:%s", err.Error())
 	}
 	invoiceDao := dao.NewCtrContractInvoiceDao(tenant)
-	userDao := sysDao.NewSysUserDao(tenant)
 
 	bizCode := strings.Split(flow.BizCode, ":")
 	if len(bizCode) != 2 {
@@ -463,17 +459,6 @@ func InvoiceApplyApproval(ctx context.Context, flow *workflowModel.PlatWorkflow,
 	if err != nil {
 		return fmt.Errorf("申请发票审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
 	}
-	userId, err := strconv.Atoi(bizCode[1])
-	if err != nil {
-		return fmt.Errorf("申请发票审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
-	}
-	user, err := userDao.Where("id = ?", userId).One()
-	if err != nil {
-		return err
-	}
-	if user == nil {
-		return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id)
-	}
 	invoice, err := invoiceDao.Where("id = ?", invoiceId).One()
 	if err != nil {
 		return err

+ 19 - 0
opms_parent/app/service/contract/ctr_contract_test.go

@@ -37,3 +37,22 @@ func TestAssignInvoiceApplyApproval(t *testing.T) {
 		panic(err)
 	}
 }
+
+func TestContractApplyApproval(t *testing.T) {
+	ctx := fakeCtx(context.Background(), testTenant)
+
+	instance := modelWorkflow.PlatWorkflow{}
+	err := g.DB(testTenant).Table("plat_workflow").Where("id = ?", 47).Struct(&instance)
+	if err != nil {
+		panic(err)
+	}
+	err = ContractApplyApproval(ctx, &instance, &message.MixMessage{
+		ProcessType: "finish",
+		// ProcessType: "terminate",
+		// Result: "agree",
+		Result: "refuse",
+	})
+	if err != nil {
+		panic(err)
+	}
+}

+ 80 - 58
opms_parent/app/service/cust/cust_customer.go

@@ -3,6 +3,7 @@ package cust
 import (
 	"bytes"
 	"context"
+	"encoding/json"
 	"fmt"
 	"math"
 	"strconv"
@@ -26,7 +27,6 @@ import (
 
 	"dashoo.cn/micro/app/dao/cust"
 	platdao "dashoo.cn/micro/app/dao/plat"
-	sysDao "dashoo.cn/micro/app/dao/sys"
 	model "dashoo.cn/micro/app/model/cust"
 	workflowModel "dashoo.cn/micro/app/model/workflow"
 	"dashoo.cn/micro/app/service"
@@ -40,7 +40,6 @@ type CustomerService struct {
 	DynamicsDao    *cust.CustCustomerDynamicsDao
 	ContactDao     *cust.CustCustomerContactDao
 	FollowDao      *platdao.PlatFollowupDao
-	UserDao        *sysDao.SysUserDao
 	BelongServer   *CustomerbelongService
 	ContanctServer *CustomercontactService
 }
@@ -64,7 +63,6 @@ func NewCustomerService(ctx context.Context) (svc *CustomerService, err error) {
 	svc.FollowDao = platdao.NewPlatFollowupDao(svc.Tenant)
 	svc.BelongServer, _ = NewCustomerBelongService(ctx)
 	svc.ContanctServer, _ = NewCustomerContactService(ctx)
-	svc.UserDao = sysDao.NewSysUserDao(svc.Tenant)
 	return svc, nil
 }
 
@@ -326,13 +324,20 @@ func (s *CustomerService) AssignCustomerRequest(ctx context.Context, req *model.
 		}
 	}
 
+	remark, err := json.Marshal(map[string]string{
+		"applyUserId":   strconv.Itoa(s.GetCxtUserId()),
+		"applyUserName": s.GetCxtUserName(),
+	})
+	if err != nil {
+		return err
+	}
 	workflowSrv, err := workflowService.NewFlowService(ctx)
 	if err != nil {
 		return err
 	}
 	for _, u := range data {
 		bizCode := strconv.Itoa(u.Id) + ":" + strconv.Itoa(s.GetCxtUserId())
-		_, err = workflowSrv.StartProcessInstance(bizCode, "11", &workflow.StartProcessInstanceRequest{
+		_, err = workflowSrv.StartProcessInstance(bizCode, "11", string(remark), &workflow.StartProcessInstanceRequest{
 			ProcessCode: &AssignCustomerRequestProcessCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 				{
@@ -388,6 +393,12 @@ func (s *CustomerService) AssignCustomerRequest(ctx context.Context, req *model.
 }
 
 func (s *CustomerService) AssignCustomerRequestApproval(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
+	remark := map[string]string{}
+	err := json.Unmarshal([]byte(flow.Remark), &remark)
+	if err != nil {
+		return err
+	}
+	userName := remark["applyUserName"]
 	bizCode := strings.Split(flow.BizCode, ":")
 	if len(bizCode) != 2 {
 		return fmt.Errorf("客户领取审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
@@ -400,13 +411,6 @@ func (s *CustomerService) AssignCustomerRequestApproval(flow *workflowModel.Plat
 	if err != nil {
 		return fmt.Errorf("客户领取审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
 	}
-	user, err := s.UserDao.Where("id = ?", userId).One()
-	if err != nil {
-		return err
-	}
-	if user == nil {
-		return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id)
-	}
 	cust, err := s.Dao.Where("id = ?", custId).One()
 	if err != nil {
 		return err
@@ -439,15 +443,15 @@ func (s *CustomerService) AssignCustomerRequestApproval(flow *workflowModel.Plat
 		return err
 	}
 
-	s.CxtUser = &request.UserInfo{Id: user.Id, UserName: user.NickName}
-	err = s.ChangeCustBelong([]int64{int64(custId)}, int64(userId), user.NickName)
+	s.CxtUser = &request.UserInfo{Id: userId, UserName: userName}
+	err = s.ChangeCustBelong([]int64{int64(custId)}, int64(userId), remark["applyUserName"])
 	if err != nil {
 		return err
 	}
 	err = s.BatchCreatebelong([]*model.CustCustomer{cust}, &model.AssignCustomerReq{
 		Ids:       []int64{int64(custId)},
-		SalesId:   int64(user.Id),
-		SalesName: user.NickName,
+		SalesId:   int64(userId),
+		SalesName: userName,
 		Remark:    "",
 		Receive:   Receive,
 	})
@@ -455,9 +459,9 @@ func (s *CustomerService) AssignCustomerRequestApproval(flow *workflowModel.Plat
 		return err
 	}
 
-	s.CxtUser = &request.UserInfo{Id: user.Id, UserName: user.NickName}
+	s.CxtUser = &request.UserInfo{Id: userId, UserName: userName}
 	return s.CreateDynamics("领取客户", map[string]interface{}{
-		"userId": user.Id,
+		"userId": userId,
 		"custId": cust.Id,
 	}, int64(cust.Id))
 }
@@ -493,13 +497,21 @@ func (s *CustomerService) MoveToPublicRequest(ctx context.Context, req *model.Mo
 		}
 	}
 
+	remark, err := json.Marshal(map[string]string{
+		"applyUserId":   strconv.Itoa(s.GetCxtUserId()),
+		"applyUserName": s.GetCxtUserName(),
+	})
+	if err != nil {
+		return err
+	}
+
 	workflowSrv, err := workflowService.NewFlowService(ctx)
 	if err != nil {
 		return err
 	}
 	for _, u := range data {
 		bizCode := strconv.Itoa(u.Id) + ":" + strconv.Itoa(s.GetCxtUserId())
-		_, err = workflowSrv.StartProcessInstance(bizCode, "12", &workflow.StartProcessInstanceRequest{
+		_, err = workflowSrv.StartProcessInstance(bizCode, "12", string(remark), &workflow.StartProcessInstanceRequest{
 			ProcessCode: &MoveToPubicRequestProcessCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 				{
@@ -555,6 +567,12 @@ func (s *CustomerService) MoveToPublicRequest(ctx context.Context, req *model.Mo
 
 // 移入公海回调
 func (s *CustomerService) MoveToPublicApproval(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
+	remark := map[string]string{}
+	err := json.Unmarshal([]byte(flow.Remark), &remark)
+	if err != nil {
+		return err
+	}
+	userName := remark["applyUserName"]
 	bizCode := strings.Split(flow.BizCode, ":")
 	if len(bizCode) != 2 {
 		return fmt.Errorf("客户移回审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
@@ -567,13 +585,6 @@ func (s *CustomerService) MoveToPublicApproval(flow *workflowModel.PlatWorkflow,
 	if err != nil {
 		return fmt.Errorf("客户移回审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
 	}
-	user, err := s.UserDao.Where("id = ?", userId).One()
-	if err != nil {
-		return err
-	}
-	if user == nil {
-		return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id)
-	}
 	cust, err := s.Dao.Where("id = ?", custId).One()
 	if err != nil {
 		return err
@@ -613,21 +624,15 @@ func (s *CustomerService) MoveToPublicApproval(flow *workflowModel.PlatWorkflow,
 			"sales_id":     0,
 			"dept_id":      0,
 			"dept_name":    "",
-			"create_time":  now,
-			"updated_by":   user.Id,
-			"updated_name": user.NickName,
 			"updated_time": now,
 		}).Where("id = ?", cust.Id).Update()
 		if err != nil {
 			return err
 		}
 		//更新销售归属表结束时间
-		_, err = s.BelongDao.TX(tx).Data(
-			g.Map{
-				"updated_by":   user.Id,
-				"updated_name": user.NickName,
-				"end_date":     now,
-			}).Where("cust_id = ?", cust.Id).Update()
+		_, err = s.BelongDao.TX(tx).Data(g.Map{
+			"end_date": now,
+		}).Where("cust_id = ?", cust.Id).Update()
 		if err != nil {
 			return err
 		}
@@ -637,9 +642,9 @@ func (s *CustomerService) MoveToPublicApproval(flow *workflowModel.PlatWorkflow,
 		return err
 	}
 
-	s.CxtUser = &request.UserInfo{Id: user.Id, UserName: user.NickName}
+	s.CxtUser = &request.UserInfo{Id: userId, UserName: userName}
 	return s.CreateDynamics("移入公海", map[string]interface{}{
-		"userId": user.Id,
+		"userId": userId,
 		"custId": cust.Id,
 	}, int64(cust.Id))
 }
@@ -675,6 +680,16 @@ func (s *CustomerService) TransCustomerRequest(ctx context.Context, req *model.A
 		}
 	}
 
+	remark, err := json.Marshal(map[string]string{
+		"applyUserId":   strconv.Itoa(s.GetCxtUserId()),
+		"applyUserName": s.GetCxtUserName(),
+		"toUserId":      strconv.FormatInt(req.SalesId, 10),
+		"toUserName":    req.SalesName,
+	})
+	if err != nil {
+		return err
+	}
+
 	workflowSrv, err := workflowService.NewFlowService(ctx)
 	if err != nil {
 		return err
@@ -685,7 +700,7 @@ func (s *CustomerService) TransCustomerRequest(ctx context.Context, req *model.A
 			strconv.Itoa(s.GetCxtUserId()),
 			strconv.FormatInt(req.SalesId, 10),
 		}, ":")
-		_, err = workflowSrv.StartProcessInstance(bizCode, "13", &workflow.StartProcessInstanceRequest{
+		_, err = workflowSrv.StartProcessInstance(bizCode, "13", string(remark), &workflow.StartProcessInstanceRequest{
 			ProcessCode: &TransCustomerRequestProcessCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 				{
@@ -741,6 +756,13 @@ func (s *CustomerService) TransCustomerRequest(ctx context.Context, req *model.A
 
 // 转移客户回调
 func (s *CustomerService) TransCustomerApproval(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
+	remark := map[string]string{}
+	err := json.Unmarshal([]byte(flow.Remark), &remark)
+	if err != nil {
+		return err
+	}
+	userName := remark["applyUserName"]
+	toUserName := remark["toUserName"]
 	bizCode := strings.Split(flow.BizCode, ":")
 	if len(bizCode) != 3 {
 		return fmt.Errorf("转移客户审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
@@ -757,20 +779,20 @@ func (s *CustomerService) TransCustomerApproval(flow *workflowModel.PlatWorkflow
 	if err != nil {
 		return fmt.Errorf("转移客户审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
 	}
-	user, err := s.UserDao.Where("id = ?", userId).One()
-	if err != nil {
-		return err
-	}
-	if user == nil {
-		return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id)
-	}
-	toUser, err := s.UserDao.Where("id = ?", toUserId).One()
-	if err != nil {
-		return err
-	}
-	if toUser == nil {
-		return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id)
-	}
+	// user, err := s.UserDao.Where("id = ?", userId).One()
+	// if err != nil {
+	// 	return err
+	// }
+	// if user == nil {
+	// 	return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id)
+	// }
+	// toUser, err := s.UserDao.Where("id = ?", toUserId).One()
+	// if err != nil {
+	// 	return err
+	// }
+	// if toUser == nil {
+	// 	return fmt.Errorf("用户不存在:%s Id: %d", flow.BizCode, flow.Id)
+	// }
 	cust, err := s.Dao.Where("id = ?", custId).One()
 	if err != nil {
 		return err
@@ -801,15 +823,15 @@ func (s *CustomerService) TransCustomerApproval(flow *workflowModel.PlatWorkflow
 		return err
 	}
 
-	s.CxtUser = &request.UserInfo{Id: user.Id, UserName: user.NickName}
-	err = s.ChangeCustBelong([]int64{int64(custId)}, int64(toUserId), toUser.NickName)
+	s.CxtUser = &request.UserInfo{Id: userId, UserName: userName}
+	err = s.ChangeCustBelong([]int64{int64(custId)}, int64(toUserId), toUserName)
 	if err != nil {
 		return err
 	}
 	err = s.BatchCreatebelong([]*model.CustCustomer{cust}, &model.AssignCustomerReq{
 		Ids:       []int64{int64(custId)},
-		SalesId:   int64(toUser.Id),
-		SalesName: toUser.NickName,
+		SalesId:   int64(toUserId),
+		SalesName: toUserName,
 		Remark:    "",
 		Receive:   OperaTion,
 	})
@@ -817,11 +839,11 @@ func (s *CustomerService) TransCustomerApproval(flow *workflowModel.PlatWorkflow
 		return err
 	}
 
-	s.CxtUser = &request.UserInfo{Id: user.Id, UserName: user.NickName}
+	s.CxtUser = &request.UserInfo{Id: userId, UserName: userName}
 	return s.CreateDynamics("转移客户", map[string]interface{}{
-		"userId":   user.Id,
+		"userId":   userId,
 		"custId":   cust.Id,
-		"toUserId": toUser.Id,
+		"toUserId": toUserId,
 	}, int64(cust.Id))
 }
 

+ 3 - 3
opms_parent/app/service/cust/cust_customer_test.go

@@ -27,7 +27,7 @@ func TestAssignCustomerRequestApproval(t *testing.T) {
 		panic(err)
 	}
 	instance := modelWorkflow.PlatWorkflow{}
-	err = g.DB(testTenant).Table("plat_workflow").Where("id = ?", 55).Struct(&instance)
+	err = g.DB(testTenant).Table("plat_workflow").Where("id = ?", 66).Struct(&instance)
 	if err != nil {
 		panic(err)
 	}
@@ -49,7 +49,7 @@ func TestAssignMoveToPublicApproval(t *testing.T) {
 		panic(err)
 	}
 	instance := modelWorkflow.PlatWorkflow{}
-	err = g.DB(testTenant).Table("plat_workflow").Where("id = ?", 25).Struct(&instance)
+	err = g.DB(testTenant).Table("plat_workflow").Where("id = ?", 65).Struct(&instance)
 	if err != nil {
 		panic(err)
 	}
@@ -71,7 +71,7 @@ func TestAssignTransCustomerApproval(t *testing.T) {
 		panic(err)
 	}
 	instance := modelWorkflow.PlatWorkflow{}
-	err = g.DB(testTenant).Table("plat_workflow").Where("id = ?", 27).Struct(&instance)
+	err = g.DB(testTenant).Table("plat_workflow").Where("id = ?", 67).Struct(&instance)
 	if err != nil {
 		panic(err)
 	}

+ 4 - 4
opms_parent/app/service/proj/business.go

@@ -355,7 +355,7 @@ func (p *businessService) BusinessTransfer(req *model.BusinessTransferReq) error
 
 		// OMS项目转移 审批
 		bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
-		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectTransfer, &workflow.StartProcessInstanceRequest{
+		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectTransfer, "", &workflow.StartProcessInstanceRequest{
 			ProcessCode: &BusinessTransferRequestProcessCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 				{
@@ -535,7 +535,7 @@ func (p *businessService) BusinessUpgrade(req *model.BusinessUpgradeReq) error {
 		}
 		// OMS项目降级 审批
 		bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
-		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectUpGrade, &workflow.StartProcessInstanceRequest{
+		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectUpGrade, "", &workflow.StartProcessInstanceRequest{
 			ProcessCode: &BusinessUpgradeRequestProcessCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 				{
@@ -698,7 +698,7 @@ func (p *businessService) BusinessDowngrade(req *model.BusinessDowngradeReq) err
 		}
 		// OMS项目降级 审批
 		bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
-		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectDownGrade, &workflow.StartProcessInstanceRequest{
+		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectDownGrade, "", &workflow.StartProcessInstanceRequest{
 			ProcessCode: &BusinessDowngradeRequestProcessCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 				{
@@ -932,7 +932,7 @@ func (p *businessService) ConvertToReserve(req *model.BusinessToReserveReq) erro
 
 		// OMS项目转储备 审批
 		bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
-		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectToReserve, &workflow.StartProcessInstanceRequest{
+		_, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectToReserve, "", &workflow.StartProcessInstanceRequest{
 			ProcessCode: &ConvertToReserveRequestProcessCode,
 			FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
 				{

+ 4 - 3
opms_parent/app/service/workflow/work_flow.go

@@ -49,7 +49,7 @@ func (s *workflowService) GetProcessInstanceDetail(instId string) (*workflow.Que
 // ProcessCode = utils.String("每种审批对应固定的code")
 // bizType:业务类型(10领用20项目创建30合同创建
 // 详情参照文档:https://open.dingtalk.com/document/orgapp/create-an-approval-instance
-func (s *workflowService) StartProcessInstance(bizCode, bizType string, flow *workflow.StartProcessInstanceRequest) (insertId int64, err error) {
+func (s *workflowService) StartProcessInstance(bizCode, bizType, remark string, flow *workflow.StartProcessInstanceRequest) (insertId int64, err error) {
 	// 参数调整
 	if flow.OriginatorUserId == nil {
 		flow.OriginatorUserId = utils.String(s.GetCxtUserDingtalkUid())
@@ -66,7 +66,7 @@ func (s *workflowService) StartProcessInstance(bizCode, bizType string, flow *wo
 		return 0, err
 	}
 
-	return s.saveWorkflowInstance(bizCode, bizType, resp.InstanceId)
+	return s.saveWorkflowInstance(bizCode, bizType, remark, resp.InstanceId)
 }
 
 // RevokeProcessInstance 撤销审批实例(钉钉接口)
@@ -83,7 +83,7 @@ func (s *workflowService) RevokeProcessInstance(instId, remark string) (string,
 }
 
 // 将审批实例同步到数据库中
-func (s *workflowService) saveWorkflowInstance(bizCode, bizType, instanceId string) (insertId int64, err error) {
+func (s *workflowService) saveWorkflowInstance(bizCode, bizType, remark, instanceId string) (insertId int64, err error) {
 	now := gtime.Now()
 
 	// 构造基础数据
@@ -93,6 +93,7 @@ func (s *workflowService) saveWorkflowInstance(bizCode, bizType, instanceId stri
 	instance.CurrentNode = "create"
 	instance.CurrentNodeTime = now.Format("Y-m-d H:i:s")
 	instance.ProcessInstId = instanceId
+	instance.Remark = remark
 	// 填充创建信息
 	service.SetCreatedInfo(&instance, s.GetCxtUserId(), s.GetCxtUserName())
 

+ 1 - 1
opms_parent/schema/contract.sql

@@ -6,7 +6,7 @@ CREATE TABLE `ctr_contract` (
     `cust_name` varchar(90) NOT NULL COMMENT '客户名称',
     `nbo_id` int(11) NOT NULL COMMENT '关联项目',
     `nbo_name` varchar(90) NOT NULL COMMENT '项目名称',
-    `appro_status` varchar(4) NOT NULL COMMENT '审批状态',
+    `appro_status` varchar(4) NOT NULL COMMENT '审核状态 10 待提交审核 20 待审核 30 审核已同意 40 审核已拒绝 50 审核已撤销',
     `contract_type` varchar(255) NOT NULL COMMENT '合同类型',
     `contract_amount` decimal(24, 6) NOT NULL COMMENT '合同金额',
     `invoice_amount` decimal(24, 6) NOT NULL COMMENT '已开票金额',

+ 2 - 0
opms_parent/schema/tmp.sql

@@ -10,3 +10,5 @@ alter table ctr_contract_invoice modify `appro_status` varchar(4) DEFAULT NULL C
 
 alter table ctr_contract add `signatory_type` varchar(255) DEFAULT NULL COMMENT '签订单位类型 10 终端用户 20 经销商 30 代理商' after signatory_name;
 alter table ctr_contract modify `incharge_name` varchar(90) COMMENT '负责人(销售工程师)';
+
+alter table ctr_contract modify `appro_status` varchar(4) NOT NULL COMMENT '审核状态 10 待提交审核 20 待审核 30 审核已同意 40 审核已拒绝 50 审核已撤销',