package mysql import ( MC "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/date" "app.yhyue.com/moapp/jybase/encrypt" "database/sql" "encoding/json" "fmt" "github.com/zeromicro/go-zero/core/logx" IC "jyBXCore/rpc/init" "jyBXCore/rpc/model/es" "jyBXCore/rpc/type/bxcore" "log" "strconv" "strings" "time" ) // 投标状态更新内容 type PartStatusContent struct { BidStage []string `json:"bidStage"` //投标项目阶段 BidType int64 `json:"bidType"` //投标类型1:直接投标;2:渠道投标 ChannelName string `json:"channelName"` //渠道名称 ChannelPerson string `json:"channelPerson"` //联系人 ChannelPhone string `json:"channelPhone"` //联系电话 IsWin int64 `json:"isWin"` //渠道是否中标 Winner string `json:"winner"` //中标单位 } // 参标 type RecordsContent struct { After PartStatusContent `json:"after"` //更新前 Before PartStatusContent `json:"before"` //更新后 ChangeField []string `json:"changeField"` //更新字段 Content string `json:"content"` //更新内容 } var ( PartTable = "participate" ParticipateBidRecordsTable = "participate_bid_records" ParticipateUserTable = "participate_user" // 参标用户表 EntnicheUserTable = "entniche_user" // 企业用户表 ) // 划转参标信息 func TransferParticipateInfo(projectId string, in *bxcore.ParticipateActionReq) error { defer MC.Catch() //保存或更新新跟踪人 if !IC.BaseMysql.ExecTx("划转参标信息", func(tx *sql.Tx) bool { var ( b1 = true b2, b3 bool now = time.Now() content = "%s划转给%s%s" lastNotes = ",保留原参标人" fromEntUserNames, toEntUserNames, toEntUserIds []string ids []int ) partInfo := IC.BaseMysql.SelectBySqlByTx(tx, "SELECT id,position_id FROM "+ParticipateUserTable+" WHERE project_id = ? AND ent_id = ? AND state > -1", projectId, in.EntId) if partInfo == nil || len(*partInfo) == 0 { logx.Info("当前项目不满足划转条件") return false } else { for _, v := range *partInfo { ids = append(ids, MC.IntAll(v["id"])) positionId := MC.Int64All(v["position_id"]) userInfo := IC.Middleground.UserCenter.IdentityByPositionId(positionId) if userInfo.EntUserName != "" { fromEntUserNames = append(fromEntUserNames, userInfo.EntUserName) } } } if len(fromEntUserNames) == 0 { logx.Info("原参标人信息查询有误") return false } //是否保留原参标人 if !in.IsRetain { lastNotes = "" //不保留 原参标人,获取把原参标人信息 //当前项目有参标人 更新参标人状态 b1 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, map[string]interface{}{ "ent_id": in.EntId, "project_id": projectId, }, map[string]interface{}{ "state": -1, "mark": -2, //0:参标;1:被划入;-1:终止参标;-2:被划走 "update_date": date.FormatDate(&now, date.Date_Full_Layout), }) } //移动端 划转对象是多选 //划转对象entuserid 解密 for _, toEntUserId := range strings.Split(in.ToEntUserId, ",") { toEntUserId = encrypt.SE.Decode4HexByCheck(toEntUserId) if toEntUserId == "" { logx.Info("划转对象不能为空", in.ProjectIds, in.EntId) continue } //查询划转人信息 entUserId, _ := strconv.ParseInt(toEntUserId, 10, 64) userInfo := IC.Middleground.UserCenter.IdentityByEntUserId(entUserId) positionId := userInfo.PositionId //保存参标--participate_user //查看是否参标过当前项目 if c := IC.BaseMysql.CountBySql("SELECT count(id) FROM "+ParticipateUserTable+" WHERE position_id = ? AND project_id = ? AND ent_id = ?", positionId, projectId, in.EntId); c > 0 { //更新 b3 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, map[string]interface{}{ "position_id": positionId, "project_id": projectId, "ent_id": in.EntId, }, map[string]interface{}{ "state": 0, "mark": 1, //0:参标;1:被划入;-1:终止参标;-2:被划走 "update_date": date.FormatDate(&now, date.Date_Full_Layout), }) } else { //保存 b3 = IC.BaseMysql.InsertByTx(tx, ParticipateUserTable, map[string]interface{}{ "ent_id": in.EntId, "ent_user_id": entUserId, "position_id": positionId, "project_id": projectId, "user_id": in.MgoUserId, "state": 0, "mark": 1, //0:参标;1:被划入;-1:终止参标;-2:被划走 "create_date": date.FormatDate(&now, date.Date_Full_Layout), "update_date": date.FormatDate(&now, date.Date_Full_Layout), }) > 0 } if b3 { toEntUserIds = append(toEntUserIds, toEntUserId) toEntUserNames = append(toEntUserNames, userInfo.EntUserName) } } //保存多个用户时 如果个别用户划转参标项目异常,直接跳过此用户,保存其他用户信息 //防止最后一个用户保存异常 if len(toEntUserIds) > 0 { b3 = true } //移动端单个项目划转给多个用户,划转记录保存一份,当前企业下参过标的或当前正在参标的人都能看到次记录 //企业下 根据企业id 和项目id查询划转记录 //个人版 根据职位id 和项目id查询划转记录 //划转记录 b2 = IC.BaseMysql.InsertByTx(tx, ParticipateBidRecordsTable, map[string]interface{}{ "ent_id": in.EntId, "ent_user_id": in.EntUserId, "position_id": in.PositionId, "project_id": projectId, "record_type": 0, "transfer_ent_user_id": strings.Join(toEntUserIds, ","), "record_content": fmt.Sprintf(content, strings.Join(fromEntUserNames, "、"), strings.Join(toEntUserNames, "、"), lastNotes), "create_date": date.FormatDate(&now, date.Date_Full_Layout), }) > 0 return b1 && b2 && b3 }) { logx.Info(in.PositionId, "---终止---", projectId) return fmt.Errorf("终止参标更新信息出错") } return nil } // 终止参标 func CancelParticipateInfo(in *bxcore.ParticipateActionReq, roleId int64) error { defer MC.Catch() if !IC.BaseMysql.ExecTx("终止参标", func(tx *sql.Tx) bool { var ( b1, b2 bool now = time.Now() tip = "终止参标(被)" ) //管理员终止:当前项目 其他参标人也被终止 query := map[string]interface{}{ "project_id": in.ProjectIds, "ent_id": in.EntId, } //个人终止:仅仅终止本人参标项目 if roleId == 0 { query["position_id"] = in.PositionId tip = "终止参标" } insert := map[string]interface{}{ "state": -1, "mark": -1, //0:参标;1:被划入;-1:终止参标;-2:被划走 "update_date": date.FormatDate(&now, date.Date_Full_Layout), } //更新参标participate_user b1 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, query, insert) //保存参标记录--participate_bid_records b2 = IC.BaseMysql.InsertByTx(tx, ParticipateBidRecordsTable, map[string]interface{}{ "ent_id": in.EntId, "ent_user_id": in.EntUserId, "position_id": in.PositionId, "project_id": in.ProjectIds, "record_type": 0, "record_content": tip, "create_date": date.FormatDate(&now, date.Date_Full_Layout), }) > 0 return b1 && b2 }) { logx.Info(in.PositionId, "---终止---", in.ProjectIds) return fmt.Errorf("终止参标更新信息出错") } return nil } // 保存参标信息 func SaveParticipateInfo(in *bxcore.ParticipateActionReq) error { defer MC.Catch() if !IC.BaseMysql.ExecTx("保存|更新参标信息及保存参标记录", func(tx *sql.Tx) bool { var ( b1, b2, b3 bool now = time.Now() ) //保存参标--participate_user //查看是否参标过当前项目 if c := IC.BaseMysql.CountBySql("SELECT count(id) FROM "+ParticipateUserTable+" WHERE position_id = ? AND project_id = ? AND ent_id = ?", in.PositionId, in.ProjectIds, in.EntId); c > 0 { //更新 b1 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, map[string]interface{}{ "position_id": in.PositionId, "ent_id": in.EntId, "project_id": in.ProjectIds, }, map[string]interface{}{ "state": 0, "mark": 0, "update_date": date.FormatDate(&now, date.Date_Full_Layout), }) } else { //保存 b1 = IC.BaseMysql.InsertByTx(tx, ParticipateUserTable, map[string]interface{}{ "ent_id": in.EntId, "ent_user_id": in.EntUserId, "position_id": in.PositionId, "project_id": in.ProjectIds, "user_id": in.MgoUserId, "state": 0, "mark": 0, "create_date": date.FormatDate(&now, date.Date_Full_Layout), "update_date": date.FormatDate(&now, date.Date_Full_Layout), }) > 0 } if !b1 { return false } //保存参标记录participate_bid_records b2 = IC.BaseMysql.InsertByTx(tx, ParticipateBidRecordsTable, map[string]interface{}{ "ent_id": in.EntId, "ent_user_id": in.EntUserId, "position_id": in.PositionId, "project_id": in.ProjectIds, "record_type": 0, "record_content": "参标", "create_date": date.FormatDate(&now, date.Date_Full_Layout), }) > 0 if !b2 { return false } //保存或更新项目信息 //有问题 其他回滚,项目信息不用回滚 b3 = UpdateProjectInfo(in.ProjectIds, es.GetProjectInfo(in.ProjectIds)) == nil return b1 && b2 && b3 }) { logx.Info(in.PositionId, "---保存---", in.ProjectIds) return fmt.Errorf("保存参标信息出错") } return nil } // 查询当前招标信息是否已被参标 func IsParticipatedByBidId(in *bxcore.ParticipateActionReq) bool { defer MC.Catch() //如果不允许多人参标 当前项目是否已经有企业其他人员参标 query := fmt.Sprintf(`SELECT count(id) FROM `+ParticipateUserTable+` WHERE %s AND project_id = %s AND state >-1`, "%s", in.ProjectIds) if in.PositionType > 0 { //企业版 query = fmt.Sprintf(query, fmt.Sprintf("ent_id = %d", in.EntId)) } else { //个人版 query = fmt.Sprintf(query, fmt.Sprintf("position_id = %d", in.PositionId)) } return IC.BaseMysql.CountBySql(query) > 0 } // 获取参标权限 func GetParticipateIsAllow(query map[string]interface{}) (b bool) { defer MC.Catch() if info, ok := IC.Mgo.FindOne(PartTable, query); ok { if info != nil { if (*info)["i_isallow"] != nil { b = MC.IntAll((*info)["i_isallow"]) > 0 } } } return } // 更新设置信息 func UpdateParticipateSetInfo(in *bxcore.ParticipateSetUpInfoReq) error { defer MC.Catch() query := map[string]interface{}{ "i_positionid": in.PositionId, } if in.PositionType > 0 { query["i_entid"] = in.EntId } upsert := map[string]interface{}{ "i_entid": in.EntId, "i_entuserid": in.EntUserId, "i_positionid": in.PositionId, "l_createtime": time.Now().Unix(), } if in.IsAllow != "" { if in.IsAllow == "0" { //修改为允许单人参标 //判断是否有多人参标的项目 sql := `SELECT project_id,COUNT(id) AS c FROM ` + ParticipateUserTable + ` WHERE ent_id = ? GROUP BY project_id ORDER BY c DESC;` datas := IC.BaseMysql.SelectBySql(sql, in.EntId) if datas != nil && len(*datas) > 0 { if max := MC.IntAll((*datas)[0]["c"]); max > 1 { return fmt.Errorf("存在多人参标的项目,暂时无法更新配置") } } } isAllow, _ := strconv.Atoi(in.IsAllow) upsert["i_isallow"] = isAllow } if len(in.BidType) > 0 { upsert["o_bidtype"] = in.BidType } if len(in.RemindRule) > 0 { upsert["o_remindrule"] = in.RemindRule } if in.NecessaryField != "" { upsert["s_requiredField"] = in.NecessaryField } if ok := IC.Mgo.Update(PartTable, query, map[string]interface{}{ "$set": upsert, }, true, false); ok { return nil } return fmt.Errorf("更新失败") } // 查询企业|个人参标设置信息 func GetParticipateSetInfo(in *bxcore.ParticipateSetUpInfoReq) (*bxcore.ParticipateSetUpInfo, error) { defer MC.Catch() query := map[string]interface{}{ "i_positionid": in.PositionId, } if in.PositionType > 0 { query["i_entid"] = in.EntId } if setInfo, ok := IC.Mgo.FindOne(PartTable, query); ok { var ( isAllow, isRequird string bidType []*bxcore.BidTypeReq remindRule []*bxcore.RemindRuleReq ) bidType = append(bidType, &bxcore.BidTypeReq{ Name: "直接投标", Content: []string{"未报名", "已报名", "投标决策", "编制投标文件", "递交投标文件", "中标公示", "签合同", "已结束"}, }, &bxcore.BidTypeReq{ Name: "渠道投标", Content: []string{"已报名", "签合同", "已结束"}, }) remindRule = append(remindRule, &bxcore.RemindRuleReq{ BidState: "直接投标", Remainder: 72, Node: "编制投标文件", }) if setInfo != nil { //必填字段 if (*setInfo)["s_requiredField"] != nil { isRequird = MC.ObjToString((*setInfo)["s_requiredField"]) } else { isRequird = "bidType" } if (*setInfo)["i_isallow"] != nil { isAllow = strconv.Itoa(MC.IntAll((*setInfo)["i_isallow"])) } if (*setInfo)["o_bidtype"] != nil { if sbb, err := json.Marshal((*setInfo)["o_bidtype"]); err == nil { if err := json.Unmarshal(sbb, &bidType); err != nil { logx.Info("bidType json un err:", err.Error()) return nil, err } } else { logx.Info("bidType json err:", err.Error()) return nil, err } } if (*setInfo)["o_remindrule"] != nil { if sbr, err := json.Marshal((*setInfo)["o_remindrule"]); err == nil { if err := json.Unmarshal(sbr, &remindRule); err != nil { logx.Info("remindRule json un err:", err.Error()) return nil, err } } else { logx.Info("remindRule json err:", err.Error()) return nil, err } } } return &bxcore.ParticipateSetUpInfo{ NecessaryField: isRequird, IsAllow: isAllow, BidType: bidType, RemindRule: remindRule, }, nil } return nil, nil } // 保存或更新tidb 项目信息 func UpdateProjectInfo(id string, pInfo map[string]interface{}) error { //id 项目id //name 项目名称 //area 省份 //city 城市 //buyer 采购单位 //budget 预算 //bid_open_time 开标时间 //zbtime 招标时间 //bid_end_time 开标结束时间 bidding表 由 数据组 重新生索引到project表 //pici 批次 轮询更新数据 // projectInfo := map[string]interface{}{ "id": id, "name": MC.ObjToString(pInfo["projectname"]), "area": MC.ObjToString(pInfo["area"]), "city": MC.ObjToString(pInfo["city"]), "buyer": MC.ObjToString(pInfo["buyer"]), "budget": MC.Int64All(pInfo["budget"]), } if pInfo["bidopentime"] != nil { openTime := pInfo["bidopentime"] projectInfo["bid_open_time"] = date.FormatDateWithObj(&openTime, date.Date_Full_Layout) } if pInfo["pici"] != nil { pici := pInfo["pici"] projectInfo["pici"] = date.FormatDateWithObj(&pici, date.Date_Full_Layout) } // 项目表:zbtime 招标时间是 biding表:publishtime发布时间 if pInfo["zbtime"] != nil { bidTime := pInfo["zbtime"] projectInfo["bid_time"] = date.FormatDateWithObj(&bidTime, date.Date_Full_Layout) } if pInfo["bidendtime"] != nil { bidEndTime := pInfo["bidendtime"] projectInfo["bid_end_time"] = date.FormatDateWithObj(&bidEndTime, date.Date_Full_Layout) } if c := IC.BaseMysql.CountBySql(`SELECT COUNT(id) FROM project WHERE id = ?`, id); c > 0 { if ok := IC.BaseMysql.Update("project", map[string]interface{}{ "id": id, }, projectInfo); !ok { return fmt.Errorf("项目信息更新异常", id) } } else { if i := IC.BaseMysql.Insert("project", projectInfo); i < 0 { return fmt.Errorf("项目信息插入异常", id) } } return nil } // 参标列表其他条件 func ParticipateListSql(in *bxcore.ParticipateListReq) string { //b project表 //a participate_user表 now := time.Now() nowDate := date.FormatDate(&now, date.Date_Full_Layout) //查询tidb base_service.project conditionSql := ` WHERE 1=1 ` //地区 if in.Area != "" { conditionSql += fmt.Sprintf(" AND pt.area IN ('%s') ", strings.ReplaceAll(in.Area, ",", "','")) } //城市 if in.City != "" { conditionSql += fmt.Sprintf(" AND pt.city IN ('%s') ", strings.ReplaceAll(in.City, ",", "','")) } //关键词 if in.Keywords != "" { kSql := ` AND (` for kk, kv := range strings.Split(in.Keywords, " ") { if kk > 0 { kSql += " OR " } kSql += " pt.name like '%" + kv + "%'" } kSql += `)` conditionSql += kSql } //招标日期 if in.BidTime != "" && strings.Contains(in.BidTime, "-") { startTime := strings.Split(in.BidTime, "-")[0] entTime := strings.Split(in.BidTime, "-")[1] if startTime != "" { startTimeInt, _ := strconv.ParseInt(startTime, 10, 64) conditionSql += ` AND pt.bid_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'` } if entTime != "" { entTimeInt, _ := strconv.ParseInt(entTime, 10, 64) conditionSql += ` AND pt.bid_time < '` + date.FormatDateByInt64(&entTimeInt, date.Date_Full_Layout) + `'` } } //招标截止日期 if in.BidEndTime != "" { //投标截止日期规则: //1、开始时间小于当前时间 ,结束时间大于当前时间,投标截止状态按钮未截止和已截止可用; //2、结束时间小于当前时间|开始时间大于当前时间,投标截止状态按钮未截止和已截止不可用; //3、需要前端做成连动 startTime := strings.Split(in.BidEndTime, "-")[0] endTime := strings.Split(in.BidEndTime, "-")[1] startTimeInt, _ := strconv.ParseInt(startTime, 10, 64) endTimeInt, _ := strconv.ParseInt(endTime, 10, 64) if startTimeInt > 0 && endTimeInt > 0 && startTimeInt > endTimeInt { logx.Info(fmt.Sprintf("投标截止日期 %d 开始时间 大于 结束时间%d!!!", startTimeInt, endTimeInt)) } else { switch in.BidEndStatus { case 0: if startTimeInt > 0 { conditionSql += ` AND pt.bid_end_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'` } if endTimeInt > 0 { conditionSql += ` AND pt.bid_end_time < '` + date.FormatDateByInt64(&endTimeInt, date.Date_Full_Layout) + `'` } case 1: //投标截止状态:1:未截止;2:已截止;3:终止参标 //未截止: var ( endBool = true ) //如果结束时间存在且小于当前时间,投标截止日期 范围都是已截止 不会存在未截止的数据 if endTimeInt > 0 { conditionSql += ` AND pt.bid_end_time < '` + date.FormatDateByInt64(&endTimeInt, date.Date_Full_Layout) + `'` endBool = endTimeInt > now.Unix() } //开始时间小于 当前时间 if endBool && now.Unix() > startTimeInt { startTimeInt = now.Unix() } //存在开始时间为0的情况 if startTimeInt > 0 { conditionSql += ` AND pt.bid_end_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'` } case 2: //投标截止状态:1:未截止;2:已截止;3:终止参标 //如果开始时间存在且大于当前时间,投标截止日期 范围都是未截止 不会存在已截止的数据 var ( startBool = true ) if startTimeInt > 0 { conditionSql += ` AND pt.bid_end_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'` startBool = startTimeInt < now.Unix() } if startBool && (endTimeInt == 0 || now.Unix() < endTimeInt) { endTimeInt = now.Unix() } //存在结束时间为0的情况 if endTimeInt > 0 { conditionSql += ` AND pt.bid_end_time < '` + date.FormatDateByInt64(&endTimeInt, date.Date_Full_Layout) + `'` } case 3: conditionSql += ` AND pug.state < 0 ` } } } else if in.BidEndStatus > 0 { //投标截止状态1:未截止;2:已截止;3:终止参标 switch in.BidEndStatus { case 1: conditionSql += ` AND pt.bid_end_time > '` + nowDate + `'` case 2: conditionSql += ` AND pt.bid_end_time < '` + nowDate + `'` case 3: conditionSql += ` AND pug.state < 0 ` } } //开标时间 if in.BidOpenTime != "" { startTime := strings.Split(in.BidOpenTime, "-")[0] entTime := strings.Split(in.BidOpenTime, "-")[1] if startTime != "" { startTimeInt, _ := strconv.ParseInt(startTime, 10, 64) conditionSql += ` AND pt.bid_open_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'` } if entTime != "" { entTimeInt, _ := strconv.ParseInt(entTime, 10, 64) conditionSql += ` AND pt.bid_open_time < '` + date.FormatDateByInt64(&entTimeInt, date.Date_Full_Layout) + `'` } } //开标状态1:未开标;2:已开标 if in.BidOpenStatus > 0 { switch in.BidOpenStatus { case 1: conditionSql += ` AND pt.bid_open_time > '` + nowDate + `'` case 2: conditionSql += ` AND pt.bid_open_time < '` + nowDate + `'` } } //参标人 管理员权限 if in.EntUserIds != "" && in.PositionType > 0 { conditionSql += ` AND (` for k, v := range strings.Split(in.EntUserIds, ",") { if k > 0 { conditionSql += " OR " } conditionSql += ` FIND_IN_SET(` + v + ` , pug.ent_user_id) ` } conditionSql += `)` } //默认按照投标截止日期正序排列、1:开标时间正序、2:更新状态时间倒序 //投标结束时间和开标时间 很多项目数据没有这两个字段值 switch in.OrderNum { case 1: conditionSql += ` ORDER BY pt.bid_open_time ASC,pt.bid_end_time ASC,pug.update_date DESC` case 2: conditionSql += ` ORDER BY pug.update_date DESC` default: conditionSql += ` ORDER BY pt.bid_end_time ASC,pt.bid_open_time ASC,pug.update_date DESC` } logx.Info(conditionSql) return conditionSql } // 个人或员工查询参标列表 func SingleParticipateList(in *bxcore.ParticipateListReq, conditionSql string) (data *bxcore.ParticipateData, err error) { defer MC.Catch() data = &bxcore.ParticipateData{ NowTime: time.Now().Unix(), Count: 0, List: []*bxcore.ParticipateList{}, } //员工|个人列表 singlePersonSql := `SELECT %s FROM ` + ParticipateUserTable + ` pug LEFT JOIN project pt ON pug.project_id = pt.id WHERE pug.position_id = ? ` singlePersonSql += conditionSql countSql := fmt.Sprintf(singlePersonSql, " COUNT(pt.id) ") count := IC.BaseMysql.CountBySql(countSql, in.PositionId) if count > 0 { data.Count = count listSql := fmt.Sprintf(singlePersonSql, " pug.update_date,pt.* ") //分页 listSql += fmt.Sprintf(` LIMIT %d,%d`, in.PageNum, in.PageSize) list := IC.BaseMysql.SelectBySql(listSql, in.PositionId) if list != nil && len(*list) > 0 { for _, v := range *list { bidTimeStr := MC.ObjToString(v["bid_time"]) bidEndTimeStr := MC.ObjToString(v["bid_end_time"]) bidOpenTimeStr := MC.ObjToString(v["bid_open_time"]) updateStatusTimeStr := MC.ObjToString(v["update_date"]) var bidTime, bidEndTime, bidOpenTime, updateStatusTime int64 if bidTimeStr != "" { bidTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidTimeStr, time.Local) bidTime = bidTime_.Unix() } if bidEndTimeStr != "" { bidEndTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidEndTimeStr, time.Local) bidEndTime = bidEndTime_.Unix() } if bidOpenTimeStr != "" { bidOpenTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidOpenTimeStr, time.Local) bidOpenTime = bidOpenTime_.Unix() } if updateStatusTimeStr != "" { updateStatusTime_, _ := time.ParseInLocation(date.Date_Full_Layout, updateStatusTimeStr, time.Local) updateStatusTime = updateStatusTime_.Unix() } data.List = append(data.List, &bxcore.ParticipateList{ Id: encrypt.EncodeArticleId2ByCheck(MC.ObjToString(v["id"])), ProjectName: MC.ObjToString(v["name"]), Buyer: MC.ObjToString(v["buyer"]), Budget: MC.ObjToString(v["budget"]), BidTime: bidTime, BidEndTime: bidEndTime, BidOpenTime: bidOpenTime, UpdateStatusTime: updateStatusTime, //UpdateStatusCon: GetParticipateContent("s", in.PositionId, MC.ObjToString(v["id"])), //查询最后一次 投标状态更新, }) } return data, nil } return nil, fmt.Errorf("数据异常") } return data, nil } // 管理员获取参标列表数据 func AdminParticipateList(in *bxcore.ParticipateListReq, conditionSql string) (data *bxcore.ParticipateData, err error) { defer MC.Catch() data = &bxcore.ParticipateData{ IsAllow: IsALLow(in.EntId), NowTime: time.Now().Unix(), Count: 0, List: []*bxcore.ParticipateList{}, } adminSql := `SELECT %s FROM (SELECT pu.ent_id, pu.project_id, GROUP_CONCAT(pu.ent_user_id SEPARATOR ',') ent_user_id, MAX(pu.update_date) update_date,MAX(pu.state) state FROM ` + ParticipateUserTable + ` pu WHERE pu.ent_id = ? AND NOT EXISTS ( SELECT 1 FROM ` + ParticipateUserTable + ` WHERE project_id = pu.project_id AND state > pu. state ) GROUP BY pu.project_id ) pug LEFT JOIN project pt ON pug.project_id = pt.id` adminCountSql := fmt.Sprintf(adminSql, "COUNT(pt.id)") + conditionSql log.Println(adminCountSql) count := IC.BaseMysql.CountBySql(adminCountSql, in.EntId) if count > 0 { data.Count = count in.PageNum = (in.PageNum - 1) * in.PageSize adminListSql := fmt.Sprintf(adminSql, " pt.*, pug.ent_user_id,pug.update_date ") + conditionSql + fmt.Sprintf(" LIMIT %d,%d", in.PageNum, in.PageSize) list := IC.BaseMysql.SelectBySql(adminListSql, in.EntId) if list != nil && len(*list) > 0 { for _, v := range *list { bidTimeStr := MC.ObjToString(v["bid_time"]) bidEndTimeStr := MC.ObjToString(v["bid_end_time"]) bidOpenTimeStr := MC.ObjToString(v["bid_open_time"]) updateStatusTimeStr := MC.ObjToString(v["update_date"]) var bidTime, bidEndTime, bidOpenTime, updateStatusTime int64 if bidTimeStr != "" { bidTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidTimeStr, time.Local) bidTime = bidTime_.Unix() } if bidEndTimeStr != "" { bidEndTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidEndTimeStr, time.Local) bidEndTime = bidEndTime_.Unix() } if bidOpenTimeStr != "" { bidOpenTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidOpenTimeStr, time.Local) bidOpenTime = bidOpenTime_.Unix() } if updateStatusTimeStr != "" { updateStatusTime_, _ := time.ParseInLocation(date.Date_Full_Layout, updateStatusTimeStr, time.Local) updateStatusTime = updateStatusTime_.Unix() } data.List = append(data.List, &bxcore.ParticipateList{ Id: encrypt.EncodeArticleId2ByCheck(MC.ObjToString(v["id"])), ProjectName: MC.ObjToString(v["name"]), Buyer: MC.ObjToString(v["buyer"]), Budget: MC.ObjToString(v["budget"]), BidTime: bidTime, BidEndTime: bidEndTime, BidOpenTime: bidOpenTime, UpdateStatusTime: updateStatusTime, //UpdateStatusCon: GetParticipateContent("e", in.EntId, MC.ObjToString(v["id"])), //查询最后一次 投标状态更新 Participants: GetParticipateUserName(MC.ObjToString(v["ent_user_id"])), //参标人信息 }) } return data, nil } return nil, fmt.Errorf("数据异常") } return data, nil } // 获取最新参标 更新内容 func GetParticipateContent(s string, id int64, projectId string) string { identitySql := `ent_id = ?` if s == "s" { identitySql = `position_id = ?` } recordsSql := `SELECT record_content,record_type FROM ` + ParticipateBidRecordsTable + ` WHERE ` + identitySql + ` AND project_id = ? ORDER BY create_date DESC LIMIT 1;` records := IC.BaseMysql.SelectBySql(recordsSql, id, projectId) if records != nil && len(*records) > 0 { rec := (*records)[0] switch MC.IntAll(rec["record_type"]) { case 0: return MC.ObjToString(rec["record_content"]) case 1: recordContent := *MC.ObjToMap(rec["record_content"]) rb, err := json.Marshal(recordContent) if err != nil { log.Println(err.Error()) return "" } var rc = RecordsContent{ After: PartStatusContent{}, Before: PartStatusContent{}, } err1 := json.Unmarshal(rb, &rc) if err1 == nil { return rc.Content } } } return "" } // 根据ent_user_id 获取参标人昵称,企业管理员现在都是“我” func GetParticipateUserName(entUserId string) string { if entUserId != "" { var userNames []string for _, v := range strings.Split(entUserId, ",") { entUserInfos := IC.MainMysql.SelectBySql(`SELECT * FROM entniche_user WHERE id = ?`, v) if entUserInfos != nil && len(*entUserInfos) > 0 { entUserInfo := (*entUserInfos)[0] if entUserInfo["name"] != nil { if userName := MC.ObjToString(entUserInfo["name"]); userName != "" { userNames = append(userNames, userName) } } } } return strings.Join(userNames, ",") } return "" } // GetBidContentEnt 企业版 获取投标状态更新内容 func GetBidContentEnt(projectId string, entId int64) *[]map[string]interface{} { // 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) } // GetBidContentPersonal 个人版 获取投标状态更新内容 func GetBidContentPersonal(projectId string, positionId int64) *[]map[string]interface{} { query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? and record_type=1 order by create_date desc limit 1;" return IC.BaseMysql.SelectBySql(query, projectId, positionId) } // UpdateBidContent 更新投标状态信息以及操作记录 func UpdateBidContent(recordData map[string]interface{}) (flag bool) { r2 := IC.BaseMysql.Insert(ParticipateBidRecordsTable, recordData) return r2 > 0 } // 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 int64) (rs *[]map[string]interface{}, total int64) { query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and ent_id=? order by create_date desc limit ?,?" countQuery := "SELECT count(id) FROM " + ParticipateBidRecordsTable + " where project_id=? and ent_id=? ;" rs = IC.BaseMysql.SelectBySql(query, projectId, entId, (page-1)*pageSize, pageSize) total = IC.BaseMysql.CountBySql(countQuery, projectId, entId) return rs, total } // GetBidRecordsPersonal 获取操作记录列表个人 func GetBidRecordsPersonal(projectId string, positionId, page, pageSize int64) (rs *[]map[string]interface{}, total int64) { query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? order by create_date desc limit ?,?;" countQuery := "SELECT count(id) FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? ;" rs = IC.BaseMysql.SelectBySql(query, projectId, positionId, (page-1)*pageSize, pageSize) total = IC.BaseMysql.CountBySql(countQuery, projectId, positionId) return rs, total } // GetUserMap 查询用户id的姓名 func GetUserMap(userIds string) (rs *[]map[string]interface{}) { query := fmt.Sprintf("select id,name from entniche_user where id in (%s)", userIds) rs = IC.MainMysql.SelectBySql(query) return rs } // CheckParticipateManager 验证项目id是否是该管理员企业下的参标项目 func CheckParticipateManager(projectId string, entId int64, valid bool) (flag bool) { stateStr := "" // 是否需要验证是正在参标 if valid { stateStr = " and state=0" } query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and ent_id=?" + stateStr return IC.BaseMysql.CountBySql(query, projectId, entId) > 0 } // CheckParticipateEntUser 验证项目id是否是该企业用户参标的项目 func CheckParticipateEntUser(projectId string, entUserId int64, valid bool) (flag bool) { stateStr := "" // 是否需要验证是正在参标 if valid { stateStr = " and state=0" } query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and ent_user_id=?" + stateStr return IC.BaseMysql.CountBySql(query, projectId, entUserId) > 0 } // CheckParticipatePersonal 查询项目id是否是该用户参标项目 func CheckParticipatePersonal(projectId string, positionId int64, valid bool) (flag bool) { stateStr := "" // 是否需要验证是正在参标 终止参标的用户还能查看记录,但是不能更新状态 if valid { stateStr = " and state=0" } query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and position_id=?" + stateStr return IC.BaseMysql.CountBySql(query, projectId, positionId) > 0 } // GetNameByUserIds 获取用户名字符串 // // 参数:逗号分割的用户id "11,22,333..." // 返回: "张三,李四,王五..." func GetNameByUserIds(ids string) *[]map[string]interface{} { query := "select group_concat(name) as name from " + EntnicheUserTable + " where id in (" + ids + ") " rs := IC.MainMysql.SelectBySql(query) return rs } // ParticipateProjectPersonal 查询给定项目id中已经参标的项目id func ParticipateProjectPersonal(positionId int64, projectId []string) *[]map[string]interface{} { // 1. 查询出已经参标的 var arg []string var value []interface{} value = append(value, positionId) for i := 0; i < len(projectId); i++ { arg = append(arg, "?") value = append(value, projectId[i]) } argStr := strings.Join(arg, ",") query := "select project_id from " + ParticipateUserTable + " where position_id = ? and project_id in (%s) and state=0" rs := IC.BaseMysql.SelectBySql(fmt.Sprintf(query, argStr), value...) return rs } // ParticipateProjectEnt 查询给定项目id中已经参标的项目id func ParticipateProjectEnt(entId int64, projectId []string) *[]map[string]interface{} { // 1. 查询出已经参标的 var arg []string var value []interface{} value = append(value, entId) for i := 0; i < len(projectId); i++ { arg = append(arg, "?") value = append(value, projectId[i]) } argStr := strings.Join(arg, ",") query := "select GROUP_CONCAT(ent_user_id) as personIds ,project_id from " + ParticipateUserTable + " where ent_id=? and project_id in (%s) and state=0 group by project_id " rs := IC.BaseMysql.SelectBySql(fmt.Sprintf(query, argStr), value...) return rs } // 查询企业人员信息 func GetPersonInfo(entId, entUserId int64, participateMap map[int64]bool) []*bxcore.ParticipatePerson { r := IC.MainMysql.SelectBySql(`SELECT a.id,a.pid,a.name,c.id as user_id,c.name as user_name,c.phone as user_phone,c.power as user_power,e.name as role from entniche_department a INNER JOIN entniche_department_user b on (a.ent_id=? and a.id=b.dept_id) INNER JOIN entniche_user c on (b.user_id=c.id) LEFT JOIN entniche_user_role d on (c.id=d.user_id) LEFT JOIN entniche_role e on (d.role_id=e.id) order by a.id,convert(c.name using gbk) COLLATE gbk_chinese_ci asc`, entId) var ( list []*bxcore.ParticipatePerson prevId int64 = 0 ) for _, v := range *r { //if entUserId == MC.Int64All(v["user_id"]) { // continue //} id := MC.Int64All(v["id"]) userId := strconv.FormatInt(MC.Int64All(v["user_id"]), 10) user := &bxcore.ParticipatePerson{ Id: encrypt.SE.Encode2HexByCheck(userId), Power: MC.Int64All(v["user_power"]), Name: MC.ObjToString(v["user_name"]), Phone: MC.ObjToString(v["user_phone"]), Role: MC.ObjToString(v["role"]), } if participateMap != nil { if participateMap[MC.Int64All(v["user_id"])] { user.IsPart = 1 } } if prevId == id { users := list[len(list)-1].Users users = append(users, user) list[len(list)-1].Users = users } else { seId := strconv.FormatInt(id, 10) list = append(list, &bxcore.ParticipatePerson{ Id: encrypt.SE.Encode2HexByCheck(seId), Name: MC.ObjToString(v["name"]), Pid: MC.Int64All(v["pid"]), Users: []*bxcore.ParticipatePerson{user}, }) } prevId = id } return list } // 是否允许多人参标 func IsALLow(entId int64) bool { return GetParticipateIsAllow(map[string]interface{}{ "i_entid": entId, }) }