Răsfoiți Sursa

feat:core 提交更新投标记录rpc接口

fuwencai 2 ani în urmă
părinte
comite
a1b31495cf

+ 2 - 10
jyBXCore/go.mod

@@ -6,8 +6,8 @@ require (
 	app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a
 	app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a
 	app.yhyue.com/moapp/jypkg v0.0.0-20230313120532-c305dbfd6a62
 	app.yhyue.com/moapp/jypkg v0.0.0-20230313120532-c305dbfd6a62
 	bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4
 	bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4
-	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20230222052351-9d6fad062447
 	github.com/go-sql-driver/mysql v1.7.0
 	github.com/go-sql-driver/mysql v1.7.0
+	github.com/gogf/gf/v2 v2.0.6
 	github.com/zeromicro/go-zero v1.4.4
 	github.com/zeromicro/go-zero v1.4.4
 	google.golang.org/grpc v1.53.0
 	google.golang.org/grpc v1.53.0
 	google.golang.org/protobuf v1.28.1
 	google.golang.org/protobuf v1.28.1
@@ -16,8 +16,8 @@ require (
 require (
 require (
 	app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d // indirect
 	app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d // indirect
 	app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547 // indirect
 	app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547 // indirect
-	app.yhyue.com/moapp/message v0.0.0-20221223100203-6402e389d9ae // indirect
 	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20230214091519-89a98c01ab0e // indirect
 	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20230214091519-89a98c01ab0e // indirect
+	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20230222052351-9d6fad062447 // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.7 // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.7 // indirect
 	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.13 // indirect
 	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.13 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
@@ -48,19 +48,15 @@ require (
 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.1 // indirect
 	github.com/jinzhu/now v1.1.1 // indirect
-	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/klauspost/compress v1.13.6 // indirect
 	github.com/klauspost/compress v1.13.6 // indirect
-	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.9 // indirect
 	github.com/mattn/go-colorable v0.1.9 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
-	github.com/nsqio/go-nsq v1.1.0 // indirect
 	github.com/olivere/elastic v6.2.37+incompatible // indirect
 	github.com/olivere/elastic v6.2.37+incompatible // indirect
-	github.com/olivere/elastic/v7 v7.0.22 // indirect
 	github.com/openzipkin/zipkin-go v0.4.0 // indirect
 	github.com/openzipkin/zipkin-go v0.4.0 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -69,13 +65,10 @@ require (
 	github.com/prometheus/common v0.37.0 // indirect
 	github.com/prometheus/common v0.37.0 // indirect
 	github.com/prometheus/procfs v0.8.0 // indirect
 	github.com/prometheus/procfs v0.8.0 // indirect
 	github.com/spaolacci/murmur3 v1.1.0 // indirect
 	github.com/spaolacci/murmur3 v1.1.0 // indirect
-	github.com/tealeg/xlsx v1.0.5 // indirect
-	github.com/thinxer/go-word2vec v0.0.0-20150917053916-5c19ec7379ed // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/scram v1.1.1 // indirect
 	github.com/xdg-go/scram v1.1.1 // indirect
 	github.com/xdg-go/stringprep v1.0.3 // indirect
 	github.com/xdg-go/stringprep v1.0.3 // indirect
 	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
 	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
-	github.com/ziutek/blas v0.0.0-20190227122918-da4ca23e90bb // indirect
 	go.etcd.io/etcd/api/v3 v3.5.5 // indirect
 	go.etcd.io/etcd/api/v3 v3.5.5 // indirect
 	go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
 	go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
 	go.etcd.io/etcd/client/v3 v3.5.5 // indirect
 	go.etcd.io/etcd/client/v3 v3.5.5 // indirect
@@ -104,7 +97,6 @@ require (
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
 	google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
-	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect

+ 32 - 2
jyBXCore/rpc/internal/logic/participaterecordslogic.go

@@ -1,9 +1,13 @@
 package logic
 package logic
 
 
 import (
 import (
+	"app.yhyue.com/moapp/jybase/common"
 	"context"
 	"context"
-
+	"fmt"
+	IC "jyBXCore/rpc/init"
 	"jyBXCore/rpc/internal/svc"
 	"jyBXCore/rpc/internal/svc"
+	"jyBXCore/rpc/model/es"
+	"jyBXCore/rpc/service"
 	"jyBXCore/rpc/type/bxcore"
 	"jyBXCore/rpc/type/bxcore"
 
 
 	"github.com/zeromicro/go-zero/core/logx"
 	"github.com/zeromicro/go-zero/core/logx"
@@ -26,6 +30,32 @@ func NewParticipateRecordsLogic(ctx context.Context, svcCtx *svc.ServiceContext)
 //  参标操作记录
 //  参标操作记录
 func (l *ParticipateRecordsLogic) ParticipateRecords(in *bxcore.ParticipateRecordsReq) (*bxcore.ParticipateRecordsRes, error) {
 func (l *ParticipateRecordsLogic) ParticipateRecords(in *bxcore.ParticipateRecordsReq) (*bxcore.ParticipateRecordsRes, error) {
 	// todo: add your logic here and delete this line
 	// todo: add your logic here and delete this line
-
+	// 验证权限
+	result := &bxcore.ParticipateRecordsRes{}
+	// 1. 判断身份是否有权限 不是超级订阅也不是大会员  则直接返回不展示
+	userInfo := IC.Middleground.PowerCheckCenter.Check(in.AppId, in.UserId, in.NewUserId, in.AccountId, in.EntId, in.PositionType, in.PositionId)
+	// 不是超级订阅 也不是大会员
+	if userInfo.Vip.Status <= 0 && userInfo.Member.Status <= 0 {
+		return result, fmt.Errorf("没权限")
+	}
+	participateService := service.NewParticipateBid(in.EntId, in.EntUserId, in.PositionType, in.PositionId)
+	participateService.EntRoleId = userInfo.Ent.EntRoleId
+	// 信息id解密
+	infoList, _ := service.DecodeId(in.Sid)
+	if len(infoList) == 0 {
+		return result, fmt.Errorf("信息id无效")
+	}
+	// 根据标讯id 查询项目信息
+	projectInfos := es.GetProjectByInfoId(infoList)
+	if projectInfos == nil || len(*projectInfos) == 0 {
+		return result, fmt.Errorf("无效的信息id")
+	}
+	// 验证身份
+	projectId := common.ObjToString((*projectInfos)[0]["_id"])
+	if !participateService.CheckUpdateBidPower(projectId) {
+		return result, fmt.Errorf("没有权限")
+	}
+	// todo 查询
+	//participateService.GetBidRecords(in.Page, in.PageSize)
 	return &bxcore.ParticipateRecordsRes{}, nil
 	return &bxcore.ParticipateRecordsRes{}, nil
 }
 }

+ 2 - 0
jyBXCore/rpc/internal/logic/updatebidstatuslogic.go

@@ -65,7 +65,9 @@ func (l *UpdateBidStatusLogic) UpdateBidStatus(in *bxcore.UpdateBidStatusReq) (*
 		return result, fmt.Errorf("没有权限")
 		return result, fmt.Errorf("没有权限")
 	}
 	}
 	// 2. 更新
 	// 2. 更新
+	// todo 取锁
 	flag := participateService.UpdateBidStatus(in, projectId)
 	flag := participateService.UpdateBidStatus(in, projectId)
+	// 释放锁
 	return &bxcore.UpdateBidStatusRes{
 	return &bxcore.UpdateBidStatusRes{
 		Data: flag,
 		Data: flag,
 	}, nil
 	}, nil

+ 28 - 38
jyBXCore/rpc/model/tidb/tidb.go

@@ -17,9 +17,8 @@ import (
 
 
 var (
 var (
 	PartTable                  = "participate"
 	PartTable                  = "participate"
-	TableParticipateBidContent = "participate_bid_content"
-	TableParticipateBidRecords = "participate_bid_records"
-	TableParticipateUser       = "participate_user" // 参标用户表
+	ParticipateBidRecordsTable = "participate_bid_records"
+	ParticipateUserTable       = "participate_user" // 参标用户表
 
 
 )
 )
 
 
@@ -333,65 +332,56 @@ func UpdateProjectInfo(id string, pInfo map[string]interface{}, bInfo map[string
 
 
 // GetBidContentEnt 企业版 获取投标状态更新内容
 // GetBidContentEnt 企业版 获取投标状态更新内容
 func GetBidContentEnt(projectId string, entId int64) *[]map[string]interface{} {
 func GetBidContentEnt(projectId string, entId int64) *[]map[string]interface{} {
-	query := "SELECT * FROM " + TableParticipateBidContent + " where project_id=? and ent_id=? ; "
+	// record_type '默认0:参标、划转、取消参标;1:投标状态更新存储'
+	query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and ent_id=? and record_type=1 order by create_date desc limit 1; "
 	return IC.BaseMysql.SelectBySql(query, projectId, entId)
 	return IC.BaseMysql.SelectBySql(query, projectId, entId)
 }
 }
 
 
 // GetBidContentPersonal 个人版 获取投标状态更新内容
 // GetBidContentPersonal 个人版 获取投标状态更新内容
 func GetBidContentPersonal(projectId string, positionId int64) *[]map[string]interface{} {
 func GetBidContentPersonal(projectId string, positionId int64) *[]map[string]interface{} {
-	query := "SELECT * FROM " + TableParticipateBidContent + " where project_id=? and position_id=?;"
+	query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? and and record_type=1  order by create_date desc limit 1;"
 	return IC.BaseMysql.SelectBySql(query, projectId, positionId)
 	return IC.BaseMysql.SelectBySql(query, projectId, positionId)
 }
 }
 
 
-// UpdateBidContent 更新投标状态信息以及存操作记录
-func UpdateBidContent(query, contentData, recordData map[string]interface{}) (flag bool) {
-	b := IC.BaseMysql.ExecTx("更新投标状态信息以及存操作记录", func(tx *sql.Tx) bool {
-		// 1.  更新投标状态
-		r1 := IC.BaseMysql.UpdateByTx(tx, TableParticipateBidContent, query, contentData)
-		if !r1 {
-			return false
-		}
-		// 2. 存更新记录
-		r2 := IC.BaseMysql.InsertByTx(tx, TableParticipateBidRecords, recordData)
-		return (r2 > 0)
-	})
-	return b
+// UpdateBidContent 更新投标状态信息以及操作记录
+func UpdateBidContent(recordData map[string]interface{}) (flag bool) {
+	r2 := IC.BaseMysql.Insert(ParticipateBidRecordsTable, recordData)
+	return r2 > 0
 }
 }
 
 
-// InsertBidContent 新增投标状态信息操作记录
-func InsertBidContent(contentData, recordData map[string]interface{}) (flag bool) {
-	b := IC.BaseMysql.ExecTx("更新投标状态信息以及存操作记录", func(tx *sql.Tx) bool {
-		// 1. 新增一条投标状态信息
-		r1 := IC.BaseMysql.InsertByTx(tx, TableParticipateBidContent, contentData)
-		if !(r1 > 0) {
-			return false
-		}
-		// 2. 存更新记录
-		r2 := IC.BaseMysql.InsertByTx(tx, TableParticipateBidRecords, recordData)
-		if !(r2 > 0) {
-			return false
-		}
-		return true
-	})
-	return b
+// InsertBidContent 新增投标状态信息及操作记录
+func InsertBidContent(recordData map[string]interface{}) (flag bool) {
+	r2 := IC.BaseMysql.Insert(ParticipateBidRecordsTable, recordData)
+	return r2 > 0
+}
+
+// GetBidRecordsEnt 获取操作记录列表
+func GetBidRecordsEnt(projectId string, entId, page, pageSize int) *[]map[string]interface{} {
+	query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and ent_id=? and and record_type=1  order by create_date desc limit ?,?;"
+	return IC.BaseMysql.SelectBySql(query, projectId, entId, page, pageSize*(page-1))
+}
+
+// GetBidRecordsPersonal 获取操作记录列表 todo 测试
+func GetBidRecordsPersonal(projectId string, positionId, page, pageSize int) *[]map[string]interface{} {
+	query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? and and record_type=1  order by create_date desc limit ?,?;"
+	return IC.BaseMysql.SelectBySql(query, projectId, positionId, page, pageSize*(page-1))
 }
 }
 
 
 // CheckParticipateManager 验证项目id是否是该管理员企业下的参标项目
 // CheckParticipateManager 验证项目id是否是该管理员企业下的参标项目
 func CheckParticipateManager(projectId string, entId int64) (flag bool) {
 func CheckParticipateManager(projectId string, entId int64) (flag bool) {
-	query := "SELECT count(id) FROM " + TableParticipateUser + " where project_id=? and ent_id=?;"
+	query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and ent_id=?;"
 	return IC.BaseMysql.CountBySql(query, projectId, entId) > 0
 	return IC.BaseMysql.CountBySql(query, projectId, entId) > 0
 }
 }
 
 
 // CheckParticipateEntUser 验证项目id是否是该企业用户参标的项目
 // CheckParticipateEntUser 验证项目id是否是该企业用户参标的项目
 func CheckParticipateEntUser(projectId string, entUserId int64) (flag bool) {
 func CheckParticipateEntUser(projectId string, entUserId int64) (flag bool) {
-	query := "SELECT count(id) FROM " + TableParticipateUser + " where project_id=? and ent_user_id=?;"
+	query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and ent_user_id=?;"
 	return IC.BaseMysql.CountBySql(query, projectId, entUserId) > 0
 	return IC.BaseMysql.CountBySql(query, projectId, entUserId) > 0
 
 
 }
 }
 
 
 // CheckParticipatePersonal 查询项目id是否是该用户参标项目
 // CheckParticipatePersonal 查询项目id是否是该用户参标项目
 func CheckParticipatePersonal(projectId string, positionId int64) (flag bool) {
 func CheckParticipatePersonal(projectId string, positionId int64) (flag bool) {
-	query := "SELECT count(id) FROM " + TableParticipateUser + " where project_id=? and position_id=?;"
+	query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and position_id=?;"
 	return IC.BaseMysql.CountBySql(query, projectId, positionId) > 0
 	return IC.BaseMysql.CountBySql(query, projectId, positionId) > 0
-
 }
 }

+ 143 - 103
jyBXCore/rpc/service/participateBid.go

@@ -6,24 +6,32 @@ import (
 	"app.yhyue.com/moapp/jybase/encrypt"
 	"app.yhyue.com/moapp/jybase/encrypt"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
+	"github.com/gogf/gf/v2/container/gset"
+	"github.com/zeromicro/go-zero/core/logx"
 	IC "jyBXCore/rpc/init"
 	IC "jyBXCore/rpc/init"
 	"jyBXCore/rpc/model/tidb"
 	"jyBXCore/rpc/model/tidb"
 	"jyBXCore/rpc/type/bxcore"
 	"jyBXCore/rpc/type/bxcore"
-	"log"
 	"strings"
 	"strings"
 )
 )
 
 
 const (
 const (
-	TableEntnicheUser       = "entniche_user"    // 企业用户表
-	TableParticipateUser    = "participate_user" // 参标用户表
-	PositionTypeEnt         = 1                  // 职位类型企业
-	PositionTypePersonal    = 0                  // 职位类型个人
-	ButtonValueParticipate  = 0                  // 参标按钮 显示值 0-参标
-	ButtonValueParticipated = 1                  // 按钮显示值 列表页面 1-已参标
-	RoleEntManager          = 1                  //  企业管理员角色
-	RoleDepartManager       = 2                  //  部门管理员角色
-	BidTypeDirect           = 1                  //  直接投标
-	BidTypeChanel           = 2                  //  渠道投标
+	TableEntnicheUser    = "entniche_user"    // 企业用户表
+	TableParticipateUser = "participate_user" // 参标用户表
+
+	PositionTypeEnt      = 1 // 职位类型企业
+	PositionTypePersonal = 0 // 职位类型个人
+
+	ButtonValueParticipate  = 0 // 参标按钮 显示值 0-参标
+	ButtonValueParticipated = 1 // 按钮显示值 列表页面 1-已参标
+
+	RoleEntManager    = 1 //  企业管理员角色
+	RoleDepartManager = 2 //  部门管理员角色
+
+	BidTypeDirect = 1 //  直接投标
+	BidTypeChanel = 2 //  渠道投标
+
+	RecordTypeBidStatus = 1 //  存储类型 1:投标状态更新
+
 )
 )
 
 
 type ParticipateBid struct {
 type ParticipateBid struct {
@@ -276,24 +284,9 @@ func (p *ParticipateBid) CheckUpdateBidPower(projectId string) (b bool) {
 
 
 // UpdateBidStatus 更新投标状态
 // UpdateBidStatus 更新投标状态
 func (p *ParticipateBid) UpdateBidStatus(in *bxcore.UpdateBidStatusReq, projectId string) (flag bool) {
 func (p *ParticipateBid) UpdateBidStatus(in *bxcore.UpdateBidStatusReq, projectId string) (flag bool) {
-	// 查询项目投标信息 区分企业和个人
-	var exist bool
-	var rs *[]map[string]interface{}
-	switch p.PositionType {
-	case PositionTypeEnt:
-		rs = tidb.GetBidContentEnt(projectId, p.EntId)
-	case PositionTypePersonal:
-		rs = tidb.GetBidContentPersonal(projectId, p.PositionId)
-
-	}
-	oldMap := map[string]interface{}{}
-	id := 0
-	if rs != nil && len(*rs) > 0 {
-		exist = true
-		oldMap = *common.ObjToMap((*rs)[0]["records_data"])
-		id = common.IntAll((*rs)[0]["id"])
-	}
-	// 处理操作记录
+	// 如果查出来旧的 那么就需要做新旧对比
+	oldMap := p.GetLastBidStatus(projectId) // 查询出最新的招标状态信息
+	// 新的
 	newMap := map[string]interface{}{
 	newMap := map[string]interface{}{
 		"bidType":       in.BidType,
 		"bidType":       in.BidType,
 		"bidStage":      in.BidStage,
 		"bidStage":      in.BidStage,
@@ -303,56 +296,55 @@ func (p *ParticipateBid) UpdateBidStatus(in *bxcore.UpdateBidStatusReq, projectI
 		"channelPhone":  in.ChannelPhone,
 		"channelPhone":  in.ChannelPhone,
 		"winner":        in.Winner,
 		"winner":        in.Winner,
 	}
 	}
-	recordsData_, _ := json.Marshal(newMap)
-	recordsData := string(recordsData_)
-	// todo
-	recordContent := processRecordStr(oldMap, newMap)
+	// 新旧对比 处理成要保存的字段
+	recordContent, err := processRecordStr(oldMap, newMap)
+	if err != nil {
+		return false
+	}
+	// 保存
 	recordData := map[string]interface{}{
 	recordData := map[string]interface{}{
 		"ent_id":         p.EntId,
 		"ent_id":         p.EntId,
 		"ent_user_id":    p.EntUserId,
 		"ent_user_id":    p.EntUserId,
 		"position_id":    p.PositionId,
 		"position_id":    p.PositionId,
 		"project_id":     projectId,
 		"project_id":     projectId,
 		"record_content": recordContent,
 		"record_content": recordContent,
+		"record_type":    RecordTypeBidStatus,
 		"create_date":    date.NowFormat(date.Date_Full_Layout),
 		"create_date":    date.NowFormat(date.Date_Full_Layout),
 	}
 	}
-	if exist {
-		// 已经存在 则进行更新
-		if id == 0 {
-			log.Println("id有误")
-			return false
-		}
-		query := map[string]interface{}{
-			"id": id,
-		}
-		updateData := map[string]interface{}{
-			"records_data": recordsData,
-			"update_date":  date.NowFormat(date.Date_Full_Layout),
-		}
-		flag = tidb.UpdateBidContent(query, updateData, recordData)
-	} else {
-		// 否则进行新增操作
-		insertData := map[string]interface{}{
-			"ent_id":       p.EntId,
-			"ent_user_id":  p.EntUserId,
-			"position_id":  p.PositionId,
-			"project_id":   projectId,
-			"records_data": recordsData,
-			"create_date":  date.NowFormat(date.Date_Full_Layout),
-		}
-
-		flag = tidb.InsertBidContent(insertData, recordData)
-	}
+	flag = tidb.InsertBidContent(recordData)
 	return
 	return
 
 
 }
 }
 
 
-// 获取投标状态信息
+// GetLastBidStatus 获取投标状态信息
+func (p *ParticipateBid) GetLastBidStatus(projectId string) map[string]interface{} {
+	rs := map[string]interface{}{}
+	// 查询项目投标信息 区分企业和个人
+	var result *[]map[string]interface{}
+	switch p.PositionType {
+	case PositionTypeEnt:
+		result = tidb.GetBidContentEnt(projectId, p.EntId)
+	case PositionTypePersonal:
+		result = tidb.GetBidContentPersonal(projectId, p.PositionId)
+	}
+	if rs != nil && len(*result) > 0 {
+		content := common.ObjToMap((*result)[0]["record_content"])
+		if content != nil {
+			bidStatus := common.ObjToMap((*content)["after"])
+			if bidStatus != nil {
+				rs = *bidStatus
+			}
+		}
+	}
+	return rs
 
 
-// 获取操作记录
-func (p ParticipateBid) GetXXX() {
+}
 
 
-	// 1. 查询出操作记录
+// GetBidRecords 获取操作记录
+func (p *ParticipateBid) GetBidRecords(page, pageSize int) {
 
 
+	// 1. 查询出操作记录
+	//tidb.GetBidRecordsEnt()
 	// 2. todo 补充上操作人姓名
 	// 2. todo 补充上操作人姓名
 }
 }
 
 
@@ -367,45 +359,93 @@ var (
 		"channelPhone":  "联系电话",
 		"channelPhone":  "联系电话",
 		"winner":        "中标单位",
 		"winner":        "中标单位",
 	}
 	}
+	BidTypeMap = map[int]interface{}{
+		BidTypeDirect: "直接投标",
+		BidTypeChanel: "渠道投标",
+	}
+	WinMap = map[int]interface{}{
+		1: "是",
+		2: "否",
+		0: "未选择",
+	}
 )
 )
 
 
-func processRecordStr(old, new map[string]interface{}) (recordContent string) {
-	//	actonStr := "%s%s%s"
-	//	var rs []string
-	//	for k, v := range ParticipateBidContentKey {
-	//		changeStr := ""
-	//		if k == "bidType" || k == "isWin" {
-	//			oldv := common.IntAll(old[k])
-	//			newv := common.IntAll(new[k])
-	//			if oldv == newv {
-	//				continue
-	//			}
-	//			if oldv == 0 && newv != 0 { // 说明是新增
-	//
-	//			} else { // 调整
-	//
-	//			}
-	//			rs = append(rs, changeStr)
-	//			continue
-	//		}
-	//		if k == "bidStage" {
-	//			// todo  计算差集
-	//
-	//			continue
-	//		}
-	//		oldv := common.ObjToString(old[k])
-	//		newv := common.ObjToString(new[k])
-	//		if oldv == newv {
-	//			continue
-	//		}
-	//		//actionType := "(调整):"
-	//		if oldv == "" && newv != "" { // 说明是新增
-	//			actionType = ""
-	//		}
-	//		changeStr = fmt.Sprintf(actonStr, v, newv)
-	//
-	//		rs = append(rs, changeStr)
-	//	}
-	//
-	return
+func processRecordStr(oldMap, newMap map[string]interface{}) (recordContent string, err error) {
+	actonStr := "%s%s%s"
+	changeField := []string{}
+	result := []string{}
+	for k, fieldName := range ParticipateBidContentKey {
+		changeStr := ""
+		switch k {
+		case "bidType":
+			oldv := common.IntAll(oldMap[k])
+			newv := common.IntAll(newMap[k])
+			if oldv == newv { // 没有改变
+				continue
+			}
+			if oldv == 0 && newv != 0 { // 说明是新增
+				changeStr = fmt.Sprintf(actonStr, fieldName, ": (新增)", BidTypeMap[newv])
+			} else { // 调整
+				changeStr = fmt.Sprintf(actonStr, fieldName, "(调整):", BidTypeMap[newv])
+
+			}
+		case "isWin":
+			oldV := common.IntAll(oldMap[k])
+			newV := common.IntAll(newMap[k])
+			if oldV == newV { // 没有改变
+				continue
+			}
+			fieldName := fieldName
+			if common.IntAll(newMap["bidType"]) == BidTypeChanel {
+				fieldName = fmt.Sprintf("%s%s", "渠道", fieldName)
+			}
+			changeStr = fmt.Sprintf(actonStr, fieldName, "(调整) 为", WinMap[newV])
+		case "bidStage":
+			bidAction := "%s%s"
+			bidChangeArr := []string{}
+			oldSet := gset.NewFrom(oldMap[k])
+			newSet := gset.NewFrom(newMap[k])
+			// 判断相等
+			if oldSet.Equal(newSet) {
+				continue
+			}
+			// 差集计算
+			// 取消勾选的
+			cancleSet := oldSet.Diff(newSet)
+			cancleSet.Iterator(func(v interface{}) bool {
+				bidChangeArr = append(bidChangeArr, fmt.Sprintf(bidAction, "(取消勾选)", v))
+				return true
+			})
+			// 新增的
+			addSet := newSet.Diff(oldSet)
+			addSet.Iterator(func(v interface{}) bool {
+				bidChangeArr = append(bidChangeArr, fmt.Sprintf(bidAction, "(新增)", v))
+				fmt.Println(v)
+				return true
+			})
+			tmpStr := strings.Join(bidChangeArr, " ")
+			changeStr = fmt.Sprintf(actonStr, fieldName, " :", tmpStr)
+		default:
+			oldV := common.ObjToString(oldMap[k])
+			newV := common.ObjToString(newMap[k])
+			if oldV == newV { // 没有变化
+				continue
+			}
+			changeStr = fmt.Sprintf(actonStr, fieldName, "(调整)为", fmt.Sprintf("\"%s\"", newV))
+		}
+		result = append(result, changeStr)
+		changeField = append(changeField, k)
+	}
+	recordMap := map[string]interface{}{
+		"content":     strings.Join(result, ";"), // 变更内容 文字描述
+		"before":      oldMap,                    // 变更前
+		"after":       newMap,                    // 变更后
+		"changeField": changeField,               // 涉及变更的字段
+	}
+	tmp, err := json.Marshal(recordMap)
+	if err != nil {
+		logx.Error("序列化操作记录失败:", err)
+		return "", err
+	}
+	return string(tmp), nil
 }
 }