participateBid.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. package mysql
  2. import (
  3. MC "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/date"
  5. "app.yhyue.com/moapp/jybase/encrypt"
  6. "database/sql"
  7. "encoding/json"
  8. "fmt"
  9. "github.com/zeromicro/go-zero/core/logx"
  10. IC "jyBXCore/rpc/init"
  11. "jyBXCore/rpc/model/es"
  12. "jyBXCore/rpc/type/bxcore"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. var (
  18. PartTable = "participate"
  19. )
  20. //划转参标信息
  21. func TransferParticipateInfo(projectId string, in *bxcore.ParticipateActionReq) error {
  22. defer MC.Catch()
  23. //保存或更新新跟踪人
  24. if !IC.BaseMysql.ExecTx("划转参标信息", func(tx *sql.Tx) bool {
  25. var (
  26. b1 = true
  27. b2, b3 bool
  28. now = time.Now()
  29. content = "%s划转给%s%s"
  30. lastNotes = ",保留原参标人"
  31. fromUserNames []string
  32. ids []int
  33. )
  34. partInfo := IC.BaseMysql.SelectBySqlByTx(tx, "SELECT id,position_id FROM `participate_user` WHERE project_id = ? AND ent_id = ? AND state > -1", projectId, in.EntId)
  35. if partInfo == nil || len(*partInfo) == 0 {
  36. logx.Info("当前项目不满足划转条件")
  37. return false
  38. } else {
  39. for _, v := range *partInfo {
  40. ids = append(ids, MC.IntAll(v["id"]))
  41. positionId := MC.Int64All(v["position_id"])
  42. userInfo := IC.Middleground.UserCenter.IdentityByPositionId(positionId)
  43. if userInfo.EntUserName != "" {
  44. fromUserNames = append(fromUserNames, userInfo.EntUserName)
  45. }
  46. }
  47. }
  48. if len(fromUserNames) == 0 {
  49. logx.Info("原参标人信息查询有误")
  50. return false
  51. }
  52. //是否保留原参标人
  53. if !in.IsRetain {
  54. lastNotes = ""
  55. //不保留 原参标人,获取把原参标人信息
  56. //当前项目有参标人 更新参标人状态
  57. b1 = IC.BaseMysql.UpdateByTx(tx, "participate_user", map[string]interface{}{
  58. "ent_id": in.EntId,
  59. "project_id": projectId,
  60. }, map[string]interface{}{
  61. "state": -1,
  62. "mark": -2, //0:参标;1:被划入;-1:终止参标;-2:被划走
  63. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  64. })
  65. }
  66. //查询划转人信息
  67. entUserId, _ := strconv.ParseInt(in.ToEntUserId, 10, 64)
  68. userInfo := IC.Middleground.UserCenter.IdentityByEntUserId(entUserId)
  69. positionId := userInfo.PositionId
  70. content = fmt.Sprintf(content, strings.Join(fromUserNames, ","), userInfo.EntUserName, lastNotes)
  71. //划转记录
  72. b2 = IC.BaseMysql.InsertByTx(tx, "participate_bid_records", map[string]interface{}{
  73. "ent_id": in.EntId,
  74. "ent_user_id": entUserId,
  75. "position_id": positionId,
  76. "project_id": projectId,
  77. "record_content": content,
  78. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  79. }) > 0
  80. //保存参标--participate_user
  81. //查看是否参标过当前项目
  82. if c := IC.BaseMysql.CountBySql("SELECT count(id) FROM `participate_user` WHERE position_id = ? AND project_id = ? AND ent_id = ?", positionId, projectId, in.EntId); c > 0 {
  83. //更新
  84. b3 = IC.BaseMysql.UpdateByTx(tx, "participate_user", map[string]interface{}{
  85. "position_id": positionId,
  86. "project_id": projectId,
  87. "ent_id": in.EntId,
  88. }, map[string]interface{}{
  89. "state": 0,
  90. "mark": 1, //0:参标;1:被划入;-1:终止参标;-2:被划走
  91. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  92. })
  93. } else {
  94. //保存
  95. b3 = IC.BaseMysql.InsertByTx(tx, "participate_user", map[string]interface{}{
  96. "ent_id": in.EntId,
  97. "ent_user_id": entUserId,
  98. "position_id": positionId,
  99. "project_id": projectId,
  100. "state": 0,
  101. "mark": 1, //0:参标;1:被划入;-1:终止参标;-2:被划走
  102. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  103. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  104. }) > 0
  105. }
  106. return b1 && b2 && b3
  107. }) {
  108. logx.Info(in.PositionId, "---终止---", projectId)
  109. return fmt.Errorf("终止参标更新信息出错")
  110. }
  111. return nil
  112. }
  113. //终止参标
  114. func CancelParticipateInfo(in *bxcore.ParticipateActionReq, roleId int64) error {
  115. defer MC.Catch()
  116. if !IC.BaseMysql.ExecTx("终止参标", func(tx *sql.Tx) bool {
  117. var (
  118. b1, b2 bool
  119. now = time.Now()
  120. tip = "终止参标(被)"
  121. )
  122. //管理员终止:当前项目 其他参标人也被终止
  123. query := map[string]interface{}{
  124. "project_id": in.ProjectIds,
  125. "ent_id": in.EntId,
  126. }
  127. //个人终止:仅仅终止本人参标项目
  128. if roleId == 0 {
  129. query["position_id"] = in.PositionId
  130. tip = "终止参标"
  131. }
  132. insert := map[string]interface{}{
  133. "state": -1,
  134. "mark": -1, //0:参标;1:被划入;-1:终止参标;-2:被划走
  135. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  136. }
  137. //更新参标participate_user
  138. b1 = IC.BaseMysql.UpdateByTx(tx, "participate_user", query, insert)
  139. //保存参标记录--participate_bid_records
  140. b2 = IC.BaseMysql.InsertByTx(tx, "participate_bid_records", map[string]interface{}{
  141. "ent_id": in.EntId,
  142. "ent_user_id": in.EntUserId,
  143. "position_id": in.PositionId,
  144. "project_id": in.ProjectIds,
  145. "record_content": tip,
  146. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  147. }) > 0
  148. return b1 && b2
  149. }) {
  150. logx.Info(in.PositionId, "---终止---", in.ProjectIds)
  151. return fmt.Errorf("终止参标更新信息出错")
  152. }
  153. return nil
  154. }
  155. //保存参标信息
  156. func SaveParticipateInfo(in *bxcore.ParticipateActionReq) error {
  157. defer MC.Catch()
  158. if !IC.BaseMysql.ExecTx("保存|更新参标信息及保存参标记录", func(tx *sql.Tx) bool {
  159. var (
  160. b1, b2, b3 bool
  161. now = time.Now()
  162. )
  163. //保存参标--participate_user
  164. //查看是否参标过当前项目
  165. if c := IC.BaseMysql.CountBySql("SELECT count(id) FROM `participate_user` WHERE position_id = ? AND project_id = ? AND ent_id = ?", in.PositionId, in.ProjectIds, in.EntId); c > 0 {
  166. //更新
  167. b1 = IC.BaseMysql.UpdateByTx(tx, "participate_user", map[string]interface{}{
  168. "state": 0,
  169. "mark": 0,
  170. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  171. }, map[string]interface{}{
  172. "position_id": in.PositionId,
  173. "ent_id": in.EntId,
  174. "project_id": in.ProjectIds,
  175. })
  176. } else {
  177. //保存
  178. b1 = IC.BaseMysql.InsertByTx(tx, "participate_user", map[string]interface{}{
  179. "ent_id": in.EntId,
  180. "ent_user_id": in.EntUserId,
  181. "position_id": in.PositionId,
  182. "project_id": in.ProjectIds,
  183. "state": 0,
  184. "mark": 0,
  185. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  186. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  187. }) > 0
  188. }
  189. if !b1 {
  190. return false
  191. }
  192. //保存参标记录participate_bid_records
  193. b2 = IC.BaseMysql.InsertByTx(tx, "participate_bid_records", map[string]interface{}{
  194. "ent_id": in.EntId,
  195. "ent_user_id": in.EntUserId,
  196. "position_id": in.PositionId,
  197. "project_id": in.ProjectIds,
  198. "record_content": "参标",
  199. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  200. }) > 0
  201. if !b2 {
  202. return false
  203. }
  204. //保存或更新项目信息
  205. //有问题 其他回滚,项目信息不用回滚
  206. b3 = UpdateProjectInfo(in.ProjectIds, es.GetProjectInfo(in.ProjectIds), es.GetBiddingInfo(in.BidIds)) == nil
  207. return b1 && b2 && b3
  208. }) {
  209. logx.Info(in.PositionId, "---保存---", in.BidIds)
  210. return fmt.Errorf("保存参标信息出错")
  211. }
  212. return nil
  213. }
  214. //查询当前招标信息是否已被参标
  215. func IsParticipatedByBidId(in *bxcore.ParticipateActionReq) bool {
  216. defer MC.Catch()
  217. //如果不允许多人参标 当前项目是否已经有企业其他人员参标
  218. query := fmt.Sprintf(`SELECT count(id) FROM participate_user WHERE %s AND project_id = %s AND state >-1`, "%s", in.BidIds)
  219. if in.PositionType > 0 { //企业版
  220. query = fmt.Sprintf(query, fmt.Sprintf("ent_id = %d", in.EntId))
  221. } else { //个人版
  222. query = fmt.Sprintf(query, fmt.Sprintf("position_id = %d", in.PositionId))
  223. }
  224. return IC.BaseMysql.CountBySql(query) > 0
  225. }
  226. //获取参标权限
  227. func GetParticipateIsAllow(query map[string]interface{}) (b bool) {
  228. defer MC.Catch()
  229. if info, ok := IC.Mgo.FindOne(PartTable, query); ok {
  230. if info != nil {
  231. if (*info)["i_isallow"] != nil {
  232. b = MC.IntAll((*info)["i_isallow"]) > 0
  233. }
  234. }
  235. }
  236. return
  237. }
  238. //更新设置信息
  239. func UpdateParticipateSetInfo(in *bxcore.ParticipateSetUpInfoReq) error {
  240. defer MC.Catch()
  241. query := map[string]interface{}{
  242. "i_positionid": in.PositionId,
  243. }
  244. if in.PositionType > 0 {
  245. //企业版 判断是否是管理员
  246. //判断用户身份
  247. userInfo := IC.Middleground.PowerCheckCenter.Check(in.AppId, in.UserId, in.NewUserId, in.AccountId, in.EntId, in.PositionType, in.PositionId)
  248. if userInfo.Ent.EntRoleId == 0 {
  249. return fmt.Errorf("当前企业身份无权限")
  250. }
  251. query["i_entid"] = in.EntId
  252. }
  253. upsert := map[string]interface{}{
  254. "i_entid": in.EntId,
  255. "i_entuserid": in.EntUserId,
  256. "i_positionid": in.PositionId,
  257. "l_createtime": time.Now().Unix(),
  258. }
  259. if in.IsAllow != "" {
  260. isAllow, _ := strconv.Atoi(in.IsAllow)
  261. upsert["i_isallow"] = isAllow
  262. }
  263. if len(in.BidType) > 0 {
  264. upsert["o_bidtype"] = in.BidType
  265. }
  266. if len(in.RemindRule) > 0 {
  267. upsert["o_remindrule"] = in.RemindRule
  268. }
  269. if ok := IC.Mgo.Update(PartTable, query, map[string]interface{}{
  270. "$set": upsert,
  271. }, true, false); ok {
  272. return nil
  273. }
  274. return fmt.Errorf("更新失败")
  275. }
  276. //查询企业|个人参标设置信息
  277. func GetParticipateSetInfo(in *bxcore.ParticipateSetUpInfoReq) (*bxcore.ParticipateSetUpInfo, error) {
  278. defer MC.Catch()
  279. query := map[string]interface{}{
  280. "i_positionid": in.PositionId,
  281. }
  282. if in.PositionType > 0 {
  283. query["i_entid"] = in.EntId
  284. }
  285. if setInfo, ok := IC.Mgo.FindOne(PartTable, query); ok {
  286. var (
  287. isAllow = ""
  288. bidType []*bxcore.BidTypeReq
  289. remindRule []*bxcore.RemindRuleReq
  290. )
  291. bidType = append(bidType, &bxcore.BidTypeReq{
  292. Name: "直接投标",
  293. Content: []string{"未报名", "已报名", "投标决策", "编制投标文件", "递交投标文件", "中标公示", "签合同", "已结束"},
  294. }, &bxcore.BidTypeReq{
  295. Name: "渠道投标",
  296. Content: []string{"已报名", "签合同", "已结束"},
  297. })
  298. remindRule = append(remindRule, &bxcore.RemindRuleReq{
  299. BidState: "直接投标",
  300. Remainder: 72,
  301. Node: "编制投标文件",
  302. })
  303. if setInfo != nil {
  304. if (*setInfo)["i_isallow"] != nil {
  305. isAllow = strconv.Itoa(MC.IntAll((*setInfo)["i_isallow"]))
  306. }
  307. if (*setInfo)["bidType"] != nil {
  308. if sbb, err := json.Marshal((*setInfo)["o_bidtype"]); err == nil {
  309. if err := json.Unmarshal(sbb, &bidType); err != nil {
  310. logx.Info("bidType json un err:", err.Error())
  311. return nil, err
  312. }
  313. } else {
  314. logx.Info("bidType json err:", err.Error())
  315. return nil, err
  316. }
  317. }
  318. if (*setInfo)["o_remindrule"] != nil {
  319. if sbr, err := json.Marshal((*setInfo)["o_remindrule"]); err == nil {
  320. if err := json.Unmarshal(sbr, &remindRule); err != nil {
  321. logx.Info("remindRule json un err:", err.Error())
  322. return nil, err
  323. }
  324. } else {
  325. logx.Info("remindRule json err:", err.Error())
  326. return nil, err
  327. }
  328. }
  329. }
  330. return &bxcore.ParticipateSetUpInfo{
  331. IsAllow: isAllow,
  332. BidType: bidType,
  333. RemindRule: remindRule,
  334. }, nil
  335. }
  336. return nil, nil
  337. }
  338. //保存或更新tidb 项目信息
  339. func UpdateProjectInfo(id string, pInfo map[string]interface{}, bInfo map[string]interface{}) error {
  340. //id 项目id
  341. //name 项目名称
  342. //area 省份
  343. //city 城市
  344. //buyer 采购单位
  345. //budget 预算
  346. //bid_open_time 开标时间
  347. //bid_time 招标时间 bidding表
  348. //bid_end_time 开标结束时间 bidding表
  349. //pici 批次 轮询更新数据
  350. //
  351. projectInfo := map[string]interface{}{
  352. "id": id,
  353. "name": MC.ObjToString(pInfo["projectname"]),
  354. "area": MC.ObjToString(pInfo["area"]),
  355. "city": MC.ObjToString(pInfo["city"]),
  356. "buyer": MC.ObjToString(pInfo["buyer"]),
  357. "budget": MC.Int64All(pInfo["budget"]),
  358. }
  359. if pInfo["bidopentime"] != nil {
  360. openTime := pInfo["bidopentime"]
  361. projectInfo["bid_open_time"] = date.FormatDateWithObj(&openTime, date.Date_Full_Layout)
  362. }
  363. if pInfo["pici"] != nil {
  364. pici := pInfo["pici"]
  365. projectInfo["pici"] = date.FormatDateWithObj(&pici, date.Date_Full_Layout)
  366. }
  367. // 项目表:zbtime 招标时间是 biding表:publishtime发布时间
  368. if pInfo["zbtime"] != nil {
  369. bidTime := pInfo["zbtime"]
  370. projectInfo["bid_time"] = date.FormatDateWithObj(&bidTime, date.Date_Full_Layout)
  371. }
  372. if bInfo["bidendtime"] != nil {
  373. bidEndTime := bInfo["bidendtime"]
  374. projectInfo["bid_end_time"] = date.FormatDateWithObj(&bidEndTime, date.Date_Full_Layout)
  375. }
  376. if c := IC.BaseMysql.CountBySql(`SELECT COUNT(id) FROM project WHERE id = ?`, id); c > 0 {
  377. if ok := IC.BaseMysql.Update("project", map[string]interface{}{
  378. "id": id,
  379. }, projectInfo); !ok {
  380. return fmt.Errorf("项目信息更新异常", id)
  381. }
  382. } else {
  383. if i := IC.BaseMysql.Insert("project", projectInfo); i < 0 {
  384. return fmt.Errorf("项目信息插入异常", id)
  385. }
  386. }
  387. return nil
  388. }
  389. //参标列表其他条件
  390. func ParticipateListSql(in *bxcore.ParticipateListReq) string {
  391. //b project表
  392. //a participate_user表
  393. now := time.Now()
  394. nowDate := date.FormatDate(&now, date.Date_Full_Layout)
  395. //查询tidb base_service.project
  396. sql := ` `
  397. //地区
  398. if in.Area != "" {
  399. sql += fmt.Sprintf(" AND pt.area IN ('%s') ", strings.ReplaceAll(in.Area, ",", "','"))
  400. }
  401. //城市
  402. if in.City != "" {
  403. sql += fmt.Sprintf(" AND pt.city IN ('%s') ", strings.ReplaceAll(in.City, ",", "','"))
  404. }
  405. //关键词
  406. if in.Keywords != "" {
  407. kSql := ` AND (`
  408. for kk, kv := range strings.Split(in.Keywords, " ") {
  409. if kk > 0 {
  410. kSql += " OR "
  411. }
  412. kSql += " pt.name like '%" + kv + "%'"
  413. }
  414. kSql += `)`
  415. sql += kSql
  416. }
  417. //招标日期
  418. if in.BidTime != "" && strings.Contains(in.BidTime, "-") {
  419. startTime := strings.Split(in.BidTime, "-")[0]
  420. entTime := strings.Split(in.BidTime, "-")[1]
  421. if startTime != "" {
  422. sql += ` AND pt.bid_time > ` + startTime
  423. }
  424. if entTime != "" {
  425. sql += ` AND pt.bid_time < ` + entTime
  426. }
  427. }
  428. //招标截止日期
  429. if in.BidEndTime != "" {
  430. startTime := strings.Split(in.BidEndTime, "-")[0]
  431. entTime := strings.Split(in.BidEndTime, "-")[1]
  432. if startTime != "" {
  433. sql += ` AND pt.bid_end_time > ` + startTime
  434. }
  435. if entTime != "" {
  436. sql += ` AND pt.bid_end_time < ` + entTime
  437. }
  438. }
  439. //开标时间
  440. if in.BidOpenTime != "" {
  441. startTime := strings.Split(in.BidOpenTime, "-")[0]
  442. entTime := strings.Split(in.BidOpenTime, "-")[1]
  443. if startTime != "" {
  444. sql += ` AND pt.bid_open_time > ` + startTime
  445. }
  446. if entTime != "" {
  447. sql += ` AND pt.bid_open_time < ` + entTime
  448. }
  449. }
  450. //投标截止状态1:未截止;2:已截止;3:终止参标
  451. if in.BidEndStatus > 0 {
  452. switch in.BidEndStatus {
  453. case 1:
  454. sql += ` AND pt.bid_end_time > ` + nowDate
  455. case 2:
  456. sql += ` AND pt.bid_end_time < ` + nowDate
  457. case 3:
  458. sql += ` AND pug.state < 0 `
  459. }
  460. }
  461. //开标状态1:未开标;2:已开标
  462. if in.BidOpenStatus > 0 {
  463. switch in.BidOpenStatus {
  464. case 1:
  465. sql += ` AND pt.bid_open_time > ` + nowDate
  466. case 2:
  467. sql += ` AND pt.bid_open_time < ` + nowDate
  468. }
  469. }
  470. //参标人 管理员权限
  471. if in.EntUserIds != "" && in.PositionType > 0 {
  472. sql += ` AND pug.ent_user_id in ('` + strings.ReplaceAll(in.EntUserIds, ",", "','") + `')`
  473. }
  474. //默认按照投标截止日期正序排列、1:开标时间正序、2:更新状态时间倒序
  475. switch in.OrderNum {
  476. case 1:
  477. sql += ` ORDER BY pug.update_date DESC`
  478. case 2:
  479. sql += ` ORDER BY pt.bid_time ASC`
  480. default:
  481. sql += ` ORDER BY pt.bid_end_time ASC`
  482. }
  483. logx.Info(sql)
  484. return sql
  485. }
  486. //个人或员工查询参标列表
  487. func SingleParticipateList(in *bxcore.ParticipateListReq, otherSql string) (data *bxcore.ParticipateData, err error) {
  488. defer MC.Catch()
  489. data = &bxcore.ParticipateData{
  490. Count: 0,
  491. List: []*bxcore.ParticipateList{},
  492. }
  493. //员工|个人列表
  494. singlePersonSql := `SELECT %s FROM participate_user pug LEFT JOIN project pt ON pug.project_id = pt.id WHERE pug.position_id = ? `
  495. singlePersonSql += otherSql
  496. countSql := fmt.Sprintf(singlePersonSql, " COUNT(pt.id) ")
  497. count := IC.BaseMysql.CountBySql(countSql, in.PositionId)
  498. if count > 0 {
  499. data.Count = count
  500. listSql := fmt.Sprintf(singlePersonSql, " pug.update_date,pt.* ")
  501. //分页
  502. listSql += fmt.Sprintf(` LIMIT %d,%d`, in.PageNum, in.PageSize)
  503. list := IC.BaseMysql.SelectBySql(listSql, in.PositionId)
  504. if list != nil && len(*list) > 0 {
  505. for _, v := range *list {
  506. data.List = append(data.List, &bxcore.ParticipateList{
  507. Id: encrypt.EncodeArticleId2ByCheck(MC.ObjToString(v["id"])),
  508. ProjectName: MC.ObjToString(v["name"]),
  509. Buyer: MC.ObjToString(v["buyer"]),
  510. Budget: MC.ObjToString(v["budget"]),
  511. BidTime: MC.ObjToString(v["bid_time"]),
  512. BidEndTime: MC.ObjToString(v["bid_end_time"]),
  513. BidOpenTime: MC.ObjToString(v["bid_open_time"]),
  514. UpdateStatusTime: MC.ObjToString(v["update_date"]),
  515. UpdateStatusCon: GetParticipateContent(in.PositionId, MC.ObjToString(v["id"])), //查询最后一次 投标状态更新,
  516. })
  517. }
  518. return data, nil
  519. }
  520. return nil, fmt.Errorf("数据异常")
  521. }
  522. return data, nil
  523. }
  524. //管理员获取参标列表数据
  525. func AdminParticipateList(in *bxcore.ParticipateListReq, otherSql string) (data *bxcore.ParticipateData, err error) {
  526. defer MC.Catch()
  527. data = &bxcore.ParticipateData{
  528. Count: 0,
  529. List: []*bxcore.ParticipateList{},
  530. }
  531. 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 FROM participate_user pu WHERE pu.ent_id = ? AND NOT EXISTS ( SELECT 1 FROM participate_user 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`
  532. adminSql += otherSql
  533. adminCountSql := fmt.Sprintf(adminSql, "COUNT(pt.id)")
  534. count := IC.BaseMysql.CountBySql(adminCountSql, in.EntId)
  535. if count > 0 {
  536. data.Count = count
  537. adminListSql := fmt.Sprintf(adminSql, "pt.*, pug.ent_user_id,pug.update_date")
  538. list := IC.BaseMysql.SelectBySql(adminListSql, in.EntId)
  539. if list != nil && len(*list) > 0 {
  540. for _, v := range *list {
  541. data.List = append(data.List, &bxcore.ParticipateList{
  542. Id: encrypt.EncodeArticleId2ByCheck(MC.ObjToString(v["id"])),
  543. ProjectName: MC.ObjToString(v["name"]),
  544. Buyer: MC.ObjToString(v["buyer"]),
  545. Budget: MC.ObjToString(v["budget"]),
  546. BidTime: MC.ObjToString(v["bid_time"]),
  547. BidEndTime: MC.ObjToString(v["bid_end_time"]),
  548. BidOpenTime: MC.ObjToString(v["bid_open_time"]),
  549. UpdateStatusTime: MC.ObjToString(v["update_date"]),
  550. UpdateStatusCon: GetParticipateContent(in.EntId, MC.ObjToString(v["id"])), //查询最后一次 投标状态更新
  551. Participants: GetParticipateUserName(MC.ObjToString(v["ent_user_id"])), //参标人信息
  552. })
  553. }
  554. return data, nil
  555. }
  556. return nil, fmt.Errorf("数据异常")
  557. }
  558. return data, nil
  559. }
  560. //获取最新参标 更新内容
  561. func GetParticipateContent(userId int64, projectId string) string {
  562. recordsSql := `SELECT record_content FROM participate_bid_records WHERE (ent_id = ? OR position_id = ?) AND project_id = ? ORDER BY create_date DESC LIMIT 1;`
  563. records := IC.BaseMysql.SelectBySql(recordsSql, userId, userId, projectId)
  564. if records != nil && len(*records) > 0 {
  565. rec := (*records)[0]
  566. return MC.ObjToString(rec["record_content"])
  567. }
  568. return ""
  569. }
  570. //根据ent_user_id 获取参标人昵称,企业管理员现在都是“我”
  571. func GetParticipateUserName(entUserId string) string {
  572. if entUserId != "" {
  573. var userNames []string
  574. for _, v := range strings.Split(entUserId, ",") {
  575. entUserInfos := IC.MainMysql.SelectBySql(`SELECT * FROM entniche_user WHERE id = ?`, v)
  576. if entUserInfos != nil && len(*entUserInfos) > 0 {
  577. entUserInfo := (*entUserInfos)[0]
  578. if entUserInfo["name"] != nil {
  579. if userName := MC.ObjToString(entUserInfo["name"]); userName != "" {
  580. userNames = append(userNames, userName)
  581. }
  582. }
  583. }
  584. }
  585. return strings.Join(userNames, ",")
  586. }
  587. return ""
  588. }