participateBid.go 25 KB

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