participateBid.go 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  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. IC "jyBXCore/rpc/init"
  10. "jyBXCore/rpc/model/es"
  11. "jyBXCore/rpc/type/bxcore"
  12. "log"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. // 投标状态更新内容
  18. type PartStatusContent struct {
  19. BidStage []string `json:"bidStage"` //投标项目阶段
  20. BidType int64 `json:"bidType"` //投标类型1:直接投标;2:渠道投标
  21. ChannelName string `json:"channelName"` //渠道名称
  22. ChannelPerson string `json:"channelPerson"` //联系人
  23. ChannelPhone string `json:"channelPhone"` //联系电话
  24. IsWin int64 `json:"isWin"` //渠道是否中标
  25. Winner string `json:"winner"` //中标单位
  26. }
  27. // 参标
  28. type RecordsContent struct {
  29. After PartStatusContent `json:"after"` //更新前
  30. Before PartStatusContent `json:"before"` //更新后
  31. ChangeField []string `json:"changeField"` //更新字段
  32. Content string `json:"content"` //更新内容
  33. }
  34. var (
  35. PartTable = "participate"
  36. ParticipateBidRecordsTable = "participate_bid_records"
  37. ParticipateUserTable = "participate_user" // 参标用户表
  38. EntnicheUserTable = "entniche_user" // 企业用户表
  39. ParticipateStage = "participate_stage_statistics" //阶段信息
  40. )
  41. type PostionIdEntUserId struct {
  42. PositionId int64
  43. EntUserId int64
  44. }
  45. // 划转参标信息
  46. func TransferParticipateInfo(projectId string, in *bxcore.ParticipateActionReq) error {
  47. defer MC.Catch()
  48. //保存或更新新跟踪人
  49. if !IC.BaseMysql.ExecTx("划转参标信息", func(tx *sql.Tx) bool {
  50. var (
  51. b1 = true
  52. b2, b3 bool
  53. now = time.Now()
  54. content = "从%s名下划转给%s%s"
  55. lastNotes = ",保留原参标人"
  56. fromEntUserNames, fromEntUserIds, toEntUserNames, toEntUserIds []string
  57. ids []int
  58. )
  59. partInfo := IC.BaseMysql.SelectBySqlByTx(tx, "SELECT id,position_id FROM "+ParticipateUserTable+" WHERE project_id = ? AND ent_id = ? AND state > -1", projectId, in.EntId)
  60. if partInfo == nil || len(*partInfo) == 0 {
  61. log.Println("当前项目不满足划转条件")
  62. return false
  63. } else {
  64. for _, v := range *partInfo {
  65. ids = append(ids, MC.IntAll(v["id"]))
  66. positionId := MC.Int64All(v["position_id"])
  67. userInfo := IC.Middleground.UserCenter.IdentityByPositionId(positionId)
  68. if userInfo.EntUserName != "" {
  69. fromEntUserNames = append(fromEntUserNames, userInfo.EntUserName)
  70. fromEntUserIds = append(fromEntUserIds, strconv.FormatInt(userInfo.EntUserId, 10))
  71. }
  72. }
  73. }
  74. if len(fromEntUserNames) == 0 {
  75. log.Println("原参标人信息查询有误")
  76. return false
  77. }
  78. //是否保留原参标人
  79. if !in.IsRetain {
  80. lastNotes = ""
  81. //不保留 原参标人,获取把原参标人信息
  82. //当前项目有参标人 更新参标人状态
  83. b1 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, map[string]interface{}{
  84. "ent_id": in.EntId,
  85. "project_id": projectId,
  86. }, map[string]interface{}{
  87. "state": -1,
  88. "mark": -2, //0:参标;1:被划入;-1:终止参标;-2:被划走
  89. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  90. })
  91. } else {
  92. //划转参标项目,如果不保留原参标人,原参标人 更新参标记录表
  93. fromEntUserIds = []string{}
  94. }
  95. //移动端 划转对象是多选
  96. //划转对象entuserid 解密
  97. for _, toEntUserId := range strings.Split(in.ToEntUserId, ",") {
  98. toEntUserId = encrypt.SE.Decode4HexByCheck(toEntUserId)
  99. if toEntUserId == "" {
  100. log.Println("划转对象不能为空", in.ProjectIds, in.EntId)
  101. continue
  102. }
  103. //查询划转人信息
  104. entUserId, _ := strconv.ParseInt(toEntUserId, 10, 64)
  105. userInfo := IC.Middleground.UserCenter.IdentityByEntUserId(entUserId)
  106. positionId := userInfo.PositionId
  107. //保存参标--participate_user
  108. //查看是否参标过当前项目
  109. 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 {
  110. //更新
  111. b3 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, map[string]interface{}{
  112. "position_id": positionId,
  113. "project_id": projectId,
  114. "ent_id": in.EntId,
  115. }, map[string]interface{}{
  116. "state": 0,
  117. "mark": 1, //0:参标;1:被划入;-1:终止参标;-2:被划走
  118. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  119. })
  120. } else {
  121. //保存
  122. b3 = IC.BaseMysql.InsertByTx(tx, ParticipateUserTable, map[string]interface{}{
  123. "ent_id": in.EntId,
  124. "ent_user_id": entUserId,
  125. "position_id": positionId,
  126. "project_id": projectId,
  127. "user_id": in.MgoUserId,
  128. "state": 0,
  129. "mark": 1, //0:参标;1:被划入;-1:终止参标;-2:被划走
  130. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  131. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  132. }) > 0
  133. }
  134. if b3 {
  135. toEntUserIds = append(toEntUserIds, toEntUserId)
  136. toEntUserNames = append(toEntUserNames, userInfo.EntUserName)
  137. }
  138. }
  139. //保存多个用户时 如果个别用户划转参标项目异常,直接跳过此用户,保存其他用户信息
  140. //防止最后一个用户保存异常
  141. if len(toEntUserIds) > 0 {
  142. b3 = true
  143. }
  144. //移动端单个项目划转给多个用户,划转记录保存一份,当前企业下参过标的或当前正在参标的人都能看到次记录
  145. //企业下 根据企业id 和项目id查询划转记录
  146. //个人版 根据职位id 和项目id查询划转记录
  147. //划转记录
  148. b2 = IC.BaseMysql.InsertByTx(tx, ParticipateBidRecordsTable, map[string]interface{}{
  149. "ent_id": in.EntId,
  150. "ent_user_id": in.EntUserId,
  151. "position_id": in.PositionId,
  152. "project_id": projectId,
  153. "record_type": 0,
  154. "transfer_from_user_id": strings.Join(fromEntUserIds, ","),
  155. "transfer_ent_user_id": strings.Join(toEntUserIds, ","),
  156. "record_content": fmt.Sprintf(content, strings.Join(fromEntUserNames, "、"), strings.Join(toEntUserNames, "、"), lastNotes),
  157. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  158. }) > 0
  159. log.Println(b1, "--", b2, "--", b3)
  160. return b1 && b2 && b3
  161. }) {
  162. log.Println(in.PositionId, "---终止---", projectId)
  163. return fmt.Errorf("终止参标更新信息出错")
  164. }
  165. return nil
  166. }
  167. // 终止参标
  168. func CancelParticipateInfo(in *bxcore.ParticipateActionReq, roleId int64) error {
  169. defer MC.Catch()
  170. if !IC.BaseMysql.ExecTx("终止参标", func(tx *sql.Tx) bool {
  171. var (
  172. b1, b2 bool
  173. now = time.Now()
  174. tip = "终止参标"
  175. )
  176. //管理员终止:当前项目 其他参标人也被终止
  177. query := map[string]interface{}{
  178. "project_id": in.ProjectIds,
  179. "ent_id": in.EntId,
  180. }
  181. //个人终止:仅仅终止本人参标项目
  182. if roleId == 0 {
  183. query["position_id"] = in.PositionId
  184. tip = "终止参标"
  185. } else {
  186. }
  187. insert := map[string]interface{}{
  188. "state": -1,
  189. "mark": -1, //0:参标;1:被划入;-1:终止参标;-2:被划走
  190. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  191. }
  192. //更新参标participate_user
  193. b1 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, query, insert)
  194. //保存参标记录--participate_bid_records
  195. b2 = IC.BaseMysql.InsertByTx(tx, ParticipateBidRecordsTable, map[string]interface{}{
  196. "ent_id": in.EntId,
  197. "ent_user_id": in.EntUserId,
  198. "position_id": in.PositionId,
  199. "project_id": in.ProjectIds,
  200. "record_type": 0,
  201. "record_content": tip,
  202. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  203. }) > 0
  204. return b1 && b2
  205. }) {
  206. log.Println(in.PositionId, "---终止---", in.ProjectIds)
  207. return fmt.Errorf("终止参标更新信息出错")
  208. }
  209. return nil
  210. }
  211. // 保存参标信息
  212. func SaveParticipateInfo(in *bxcore.ParticipateActionReq) error {
  213. defer MC.Catch()
  214. if !IC.BaseMysql.ExecTx("保存|更新参标信息及保存参标记录", func(tx *sql.Tx) bool {
  215. var (
  216. b1, b2, b3 bool
  217. now = time.Now()
  218. )
  219. //保存参标--participate_user
  220. //查看是否参标过当前项目
  221. 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 {
  222. //更新
  223. b1 = IC.BaseMysql.UpdateByTx(tx, ParticipateUserTable, map[string]interface{}{
  224. "position_id": in.PositionId,
  225. "ent_id": in.EntId,
  226. "project_id": in.ProjectIds,
  227. }, map[string]interface{}{
  228. "state": 0,
  229. "mark": 0,
  230. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  231. })
  232. } else {
  233. //保存
  234. b1 = IC.BaseMysql.InsertByTx(tx, ParticipateUserTable, map[string]interface{}{
  235. "ent_id": in.EntId,
  236. "ent_user_id": in.EntUserId,
  237. "position_id": in.PositionId,
  238. "project_id": in.ProjectIds,
  239. "user_id": in.MgoUserId,
  240. "state": 0,
  241. "mark": 0,
  242. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  243. "update_date": date.FormatDate(&now, date.Date_Full_Layout),
  244. }) > 0
  245. }
  246. if !b1 {
  247. return false
  248. }
  249. //保存参标记录participate_bid_records
  250. b2 = IC.BaseMysql.InsertByTx(tx, ParticipateBidRecordsTable, map[string]interface{}{
  251. "ent_id": in.EntId,
  252. "ent_user_id": in.EntUserId,
  253. "position_id": in.PositionId,
  254. "project_id": in.ProjectIds,
  255. "record_type": 0,
  256. "record_content": "参标",
  257. "create_date": date.FormatDate(&now, date.Date_Full_Layout),
  258. }) > 0
  259. if !b2 {
  260. return false
  261. }
  262. //保存或更新项目信息
  263. //有问题 其他回滚,项目信息不用回滚
  264. b3 = UpdateProjectInfo(in.ProjectIds, es.GetProjectInfo(in.ProjectIds)) == nil
  265. return b1 && b2 && b3
  266. }) {
  267. log.Println(in.PositionId, "---保存---", in.ProjectIds)
  268. return fmt.Errorf("保存参标信息出错")
  269. }
  270. return nil
  271. }
  272. // 查询当前招标信息是否已被参标
  273. func IsParticipatedByBidId(in *bxcore.ParticipateActionReq) (entUserName string) {
  274. defer MC.Catch()
  275. //如果不允许多人参标 当前项目是否已经有企业其他人员参标
  276. query := fmt.Sprintf(`SELECT ent_id,ent_user_id FROM `+ParticipateUserTable+` WHERE %s AND project_id = '%s' AND state >-1`, "%s", in.ProjectIds)
  277. if in.PositionType > 0 { //企业版
  278. query = fmt.Sprintf(query, fmt.Sprintf("ent_id = %d", in.EntId))
  279. } else { //个人版
  280. query = fmt.Sprintf(query, fmt.Sprintf("position_id = %d", in.PositionId))
  281. }
  282. data := IC.BaseMysql.SelectBySql(query)
  283. if data != nil && len(*data) > 0 {
  284. partInfo := (*data)[0]
  285. if entUserId := MC.Int64All(partInfo["ent_user_id"]); entUserId > 0 {
  286. userInfo := IC.Middleground.UserCenter.IdentityByEntUserId(entUserId)
  287. entUserName = userInfo.EntUserName
  288. }
  289. }
  290. return
  291. }
  292. // 获取参标权限
  293. func GetParticipateIsAllow(query map[string]interface{}) (b bool) {
  294. defer MC.Catch()
  295. if info, ok := IC.Mgo.FindOne(PartTable, query); ok {
  296. if info != nil {
  297. if (*info)["i_isallow"] != nil {
  298. b = MC.IntAll((*info)["i_isallow"]) > 0
  299. }
  300. }
  301. }
  302. return
  303. }
  304. // 更新设置信息
  305. func UpdateParticipateSetInfo(in *bxcore.ParticipateSetUpInfoReq) error {
  306. defer MC.Catch()
  307. query := map[string]interface{}{
  308. "i_positionid": in.PositionId,
  309. }
  310. if in.PositionType > 0 {
  311. query = map[string]interface{}{
  312. "i_entid": in.EntId,
  313. }
  314. }
  315. upsert := map[string]interface{}{
  316. "i_entid": in.EntId,
  317. "i_entuserid": in.EntUserId,
  318. "i_positionid": in.PositionId,
  319. "l_createtime": time.Now().Unix(),
  320. }
  321. if in.IsAllow != "" {
  322. if in.IsAllow == "0" { //修改为允许单人参标
  323. //判断是否有多人参标的项目
  324. //pSql := `SELECT project_id,COUNT(id) AS c FROM ` + ParticipateUserTable + ` WHERE ent_id = ? AND state =0 GROUP BY project_id ORDER BY c DESC;`
  325. pSql := `SELECT pu.project_id,COUNT(pu.id) AS c,p.bid_end_time,p.bid_open_time FROM ` + ParticipateUserTable + ` pu LEFT JOIN project p ON pu.project_id = p.id WHERE pu.ent_id = ? AND pu.state =0 AND ((p.bid_open_time > ? or p.bid_open_time is null) and (p.bid_end_time IS NULL or p.bid_end_time > ?)) GROUP BY pu.project_id ORDER BY c DESC`
  326. data := IC.BaseMysql.SelectBySql(pSql, in.EntId, time.Now().Format(date.Date_Full_Layout), time.Now().Format(date.Date_Full_Layout))
  327. if data != nil && len(*data) > 0 {
  328. if max := MC.IntAll((*data)[0]["c"]); max > 1 {
  329. return fmt.Errorf("公司当前有项目多人参标的情况,请先确保项目都是单人参标的前提下再调整配置。\n前往”企业参标项目列表“查看具体情况。")
  330. }
  331. }
  332. }
  333. isAllow, _ := strconv.Atoi(in.IsAllow)
  334. upsert["i_isallow"] = isAllow
  335. }
  336. if len(in.BidType) > 0 {
  337. upsert["o_bidtype"] = in.BidType
  338. }
  339. if len(in.RemindRule) > 0 {
  340. upsert["o_remindrule"] = in.RemindRule
  341. }
  342. if in.NecessaryField != "" {
  343. upsert["s_requiredField"] = in.NecessaryField
  344. }
  345. if ok := IC.Mgo.Update(PartTable, query, map[string]interface{}{
  346. "$set": upsert,
  347. }, true, false); ok {
  348. return nil
  349. }
  350. return fmt.Errorf("更新失败")
  351. }
  352. // 查询企业|个人参标设置信息
  353. func GetParticipateSetInfo(in *bxcore.ParticipateSetUpInfoReq) (*bxcore.ParticipateSetUpInfo, error) {
  354. defer MC.Catch()
  355. query := map[string]interface{}{
  356. "i_positionid": in.PositionId,
  357. }
  358. if in.PositionType > 0 {
  359. query = map[string]interface{}{
  360. "i_entid": in.EntId,
  361. }
  362. }
  363. if setInfo, ok := IC.Mgo.FindOne(PartTable, query); ok {
  364. var (
  365. isAllow int64
  366. isRequired string
  367. bidType []*bxcore.BidTypeReq
  368. remindRule []*bxcore.RemindRuleReq
  369. )
  370. bidType = append(bidType, &bxcore.BidTypeReq{
  371. Name: "直接投标",
  372. Content: []string{"未报名", "已报名", "投标决策", "编制投标文件", "递交投标文件", "中标公示", "签合同", "已结束"},
  373. }, &bxcore.BidTypeReq{
  374. Name: "渠道投标",
  375. Content: []string{"已报名", "签合同", "已结束"},
  376. })
  377. remindRule = append(remindRule, &bxcore.RemindRuleReq{
  378. BidState: "直接投标",
  379. Remainder: 72,
  380. Node: "编制投标文件",
  381. })
  382. if setInfo != nil {
  383. //必填字段
  384. if (*setInfo)["s_requiredField"] != nil {
  385. isRequired = MC.ObjToString((*setInfo)["s_requiredField"])
  386. } else {
  387. isRequired = "bidType"
  388. }
  389. isAllow = MC.Int64All((*setInfo)["i_isallow"])
  390. if (*setInfo)["o_bidtype"] != nil {
  391. if sbb, err := json.Marshal((*setInfo)["o_bidtype"]); err == nil {
  392. if err := json.Unmarshal(sbb, &bidType); err != nil {
  393. log.Println("bidType json un err:", err.Error())
  394. return nil, err
  395. }
  396. } else {
  397. log.Println("bidType json err:", err.Error())
  398. return nil, err
  399. }
  400. }
  401. if (*setInfo)["o_remindrule"] != nil {
  402. if sbr, err := json.Marshal((*setInfo)["o_remindrule"]); err == nil {
  403. if err := json.Unmarshal(sbr, &remindRule); err != nil {
  404. log.Println("remindRule json un err:", err.Error())
  405. return nil, err
  406. }
  407. } else {
  408. log.Println("remindRule json err:", err.Error())
  409. return nil, err
  410. }
  411. }
  412. }
  413. return &bxcore.ParticipateSetUpInfo{
  414. NecessaryField: isRequired,
  415. IsAllow: isAllow,
  416. BidType: bidType,
  417. RemindRule: remindRule,
  418. }, nil
  419. }
  420. return nil, nil
  421. }
  422. // 保存或更新tidb 项目信息
  423. func UpdateProjectInfo(id string, pInfo map[string]interface{}) error {
  424. //id 项目id
  425. //name 项目名称
  426. //area 省份
  427. //city 城市
  428. //buyer 采购单位
  429. //budget 预算
  430. //bid_open_time 开标时间
  431. //zbtime 招标时间
  432. //bid_end_time 开标结束时间 bidding表 由 数据组 重新生索引到project表
  433. //pici 批次 轮询更新数据
  434. //
  435. projectInfo := map[string]interface{}{
  436. "id": id,
  437. "name": MC.ObjToString(pInfo["projectname"]),
  438. "area": MC.ObjToString(pInfo["area"]),
  439. "city": MC.ObjToString(pInfo["city"]),
  440. "buyer": MC.ObjToString(pInfo["buyer"]),
  441. "budget": MC.Int64All(pInfo["budget"]),
  442. }
  443. if pInfo["bidopentime"] != nil {
  444. openTime := pInfo["bidopentime"]
  445. projectInfo["bid_open_time"] = date.FormatDateWithObj(&openTime, date.Date_Full_Layout)
  446. }
  447. if pInfo["pici"] != nil {
  448. pici := pInfo["pici"]
  449. projectInfo["pici"] = date.FormatDateWithObj(&pici, date.Date_Full_Layout)
  450. }
  451. // 项目表:zbtime 招标时间是 biding表:publishtime发布时间
  452. if pInfo["zbtime"] != nil {
  453. bidTime := pInfo["zbtime"]
  454. projectInfo["bid_time"] = date.FormatDateWithObj(&bidTime, date.Date_Full_Layout)
  455. }
  456. if pInfo["bidendtime"] != nil {
  457. bidEndTime := pInfo["bidendtime"]
  458. projectInfo["bid_end_time"] = date.FormatDateWithObj(&bidEndTime, date.Date_Full_Layout)
  459. }
  460. if c := IC.BaseMysql.CountBySql(`SELECT COUNT(id) FROM project WHERE id = ?`, id); c > 0 {
  461. if ok := IC.BaseMysql.Update("project", map[string]interface{}{
  462. "id": id,
  463. }, projectInfo); !ok {
  464. return fmt.Errorf("项目信息更新异常", id)
  465. }
  466. } else {
  467. if i := IC.BaseMysql.Insert("project", projectInfo); i < 0 {
  468. return fmt.Errorf("项目信息插入异常", id)
  469. }
  470. }
  471. return nil
  472. }
  473. // 参标列表其他条件
  474. func ParticipateListSql(in *bxcore.ParticipateListReq) string {
  475. //b project表
  476. //a participate_user表
  477. now := time.Now()
  478. nowDate := date.FormatDate(&now, date.Date_Full_Layout)
  479. //查询tidb base_service.project
  480. conditionSql := ` `
  481. //地区
  482. if in.Area != "" {
  483. conditionSql += fmt.Sprintf(" AND pt.area IN ('%s') ", strings.ReplaceAll(in.Area, ",", "','"))
  484. }
  485. //城市
  486. if in.City != "" {
  487. conditionSql += fmt.Sprintf(" AND pt.city IN ('%s') ", strings.ReplaceAll(in.City, ",", "','"))
  488. }
  489. //关键词
  490. if in.Keywords != "" {
  491. kSql := ` AND (`
  492. for kk, kv := range strings.Split(in.Keywords, " ") {
  493. log.Println(kk, "----", kv)
  494. if kk > 0 {
  495. kSql += " OR "
  496. }
  497. kSql += " pt.name like '%" + kv + "%'"
  498. }
  499. kSql += `)`
  500. conditionSql += kSql
  501. }
  502. //招标日期
  503. if in.BidTime != "" && strings.Contains(in.BidTime, "-") {
  504. startTime := strings.Split(in.BidTime, "-")[0]
  505. entTime := strings.Split(in.BidTime, "-")[1]
  506. if startTime != "" {
  507. startTimeInt, _ := strconv.ParseInt(startTime, 10, 64)
  508. conditionSql += ` AND pt.bid_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'`
  509. }
  510. if entTime != "" {
  511. entTimeInt, _ := strconv.ParseInt(entTime, 10, 64)
  512. conditionSql += ` AND pt.bid_time < '` + date.FormatDateByInt64(&entTimeInt, date.Date_Full_Layout) + `'`
  513. }
  514. }
  515. //招标截止日期
  516. if in.BidEndTime != "" {
  517. //投标截止日期规则:
  518. //1、开始时间小于当前时间 ,结束时间大于当前时间,投标截止状态按钮未截止和已截止可用;
  519. //2、结束时间小于当前时间|开始时间大于当前时间,投标截止状态按钮未截止和已截止不可用;
  520. //3、需要前端做成连动
  521. startTime := strings.Split(in.BidEndTime, "-")[0]
  522. endTime := strings.Split(in.BidEndTime, "-")[1]
  523. startTimeInt, _ := strconv.ParseInt(startTime, 10, 64)
  524. endTimeInt, _ := strconv.ParseInt(endTime, 10, 64)
  525. bidEndTimeSql := ``
  526. if startTimeInt > 0 && endTimeInt > 0 && startTimeInt > endTimeInt {
  527. log.Println(fmt.Sprintf("投标截止日期 %d 开始时间 大于 结束时间%d!!!", startTimeInt, endTimeInt))
  528. } else {
  529. if startTimeInt > 0 {
  530. bidEndTimeSql += ` AND pt.bid_end_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'`
  531. }
  532. if endTimeInt > 0 {
  533. bidEndTimeSql += ` AND pt.bid_end_time < '` + date.FormatDateByInt64(&endTimeInt, date.Date_Full_Layout) + `'`
  534. }
  535. switch in.BidEndStatus {
  536. case 1: //投标截止状态:1:未截止;2:已截止;3:终止参标
  537. bidEndTimeSql = ``
  538. //未截止:
  539. var (
  540. endBool = true
  541. )
  542. //如果结束时间存在且小于当前时间,投标截止日期 范围都是已截止 不会存在未截止的数据
  543. if endTimeInt > 0 {
  544. bidEndTimeSql += ` AND pt.bid_end_time < '` + date.FormatDateByInt64(&endTimeInt, date.Date_Full_Layout) + `'`
  545. endBool = endTimeInt > now.Unix()
  546. }
  547. //开始时间小于 当前时间
  548. if endBool && now.Unix() > startTimeInt {
  549. startTimeInt = now.Unix()
  550. }
  551. //存在开始时间为0的情况
  552. if startTimeInt > 0 {
  553. bidEndTimeSql += ` AND pt.bid_end_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'`
  554. }
  555. case 2: //投标截止状态:1:未截止;2:已截止;3:终止参标
  556. //如果开始时间存在且大于当前时间,投标截止日期 范围都是未截止 不会存在已截止的数据
  557. var (
  558. startBool = true
  559. )
  560. bidEndTimeSql = ``
  561. if startTimeInt > 0 {
  562. bidEndTimeSql += ` AND pt.bid_end_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'`
  563. startBool = startTimeInt < now.Unix()
  564. }
  565. if startBool && (endTimeInt == 0 || now.Unix() < endTimeInt) {
  566. endTimeInt = now.Unix()
  567. }
  568. //存在结束时间为0的情况
  569. if endTimeInt > 0 {
  570. bidEndTimeSql += ` AND pt.bid_end_time < '` + date.FormatDateByInt64(&endTimeInt, date.Date_Full_Layout) + `'`
  571. }
  572. case 3:
  573. bidEndTimeSql += ` AND pug.state < 0 `
  574. }
  575. }
  576. if bidEndTimeSql != "" {
  577. conditionSql += bidEndTimeSql
  578. }
  579. } else if in.BidEndStatus > 0 { //投标截止状态1:未截止;2:已截止;3:终止参标
  580. switch in.BidEndStatus {
  581. case 1:
  582. conditionSql += ` AND pt.bid_end_time > '` + nowDate + `'`
  583. case 2:
  584. conditionSql += ` AND pt.bid_end_time < '` + nowDate + `'`
  585. case 3:
  586. conditionSql += ` AND pug.state < 0 `
  587. }
  588. }
  589. //开标时间
  590. if in.BidOpenTime != "" {
  591. startTime := strings.Split(in.BidOpenTime, "-")[0]
  592. entTime := strings.Split(in.BidOpenTime, "-")[1]
  593. if startTime != "" {
  594. startTimeInt, _ := strconv.ParseInt(startTime, 10, 64)
  595. conditionSql += ` AND pt.bid_open_time > '` + date.FormatDateByInt64(&startTimeInt, date.Date_Full_Layout) + `'`
  596. }
  597. if entTime != "" {
  598. entTimeInt, _ := strconv.ParseInt(entTime, 10, 64)
  599. conditionSql += ` AND pt.bid_open_time < '` + date.FormatDateByInt64(&entTimeInt, date.Date_Full_Layout) + `'`
  600. }
  601. }
  602. //开标状态1:未开标;2:已开标
  603. if in.BidOpenStatus > 0 {
  604. switch in.BidOpenStatus {
  605. case 1:
  606. conditionSql += ` AND pt.bid_open_time > '` + nowDate + `'`
  607. case 2:
  608. conditionSql += ` AND pt.bid_open_time < '` + nowDate + `'`
  609. }
  610. }
  611. //参标人 管理员权限
  612. if in.EntUserIds != "" && in.PositionType > 0 {
  613. var entUserIdsSql = ""
  614. for k, v := range strings.Split(in.EntUserIds, ",") {
  615. v = encrypt.SE.Decode4HexByCheck(v)
  616. if v == "" {
  617. continue
  618. }
  619. if k > 0 && entUserIdsSql != "" {
  620. entUserIdsSql += " OR "
  621. }
  622. entUserIdsSql += ` FIND_IN_SET(` + v + ` , pug.ent_user_id) `
  623. }
  624. if entUserIdsSql != "" {
  625. conditionSql += ` AND (` + entUserIdsSql + `)`
  626. }
  627. }
  628. //默认按照投标截止日期正序排列、1:开标时间正序、2:更新状态时间倒序
  629. //投标结束时间和开标时间 很多项目数据没有这两个字段值
  630. switch in.OrderNum {
  631. case 1:
  632. conditionSql += ` ORDER BY (pt.bid_open_time IS NULL),pt.bid_open_time ASC,(pt.bid_end_time IS NULL),pt.bid_end_time ASC,pbr.create_date DESC`
  633. case 2:
  634. conditionSql += ` ORDER BY pbr.create_date DESC`
  635. default:
  636. conditionSql += ` ORDER BY (pt.bid_end_time IS NULL),pt.bid_end_time ASC,(pt.bid_open_time IS NULL),pt.bid_open_time ASC,pbr.create_date DESC`
  637. }
  638. log.Println(conditionSql)
  639. return conditionSql
  640. }
  641. // 个人或员工查询参标列表
  642. func SingleParticipateList(in *bxcore.ParticipateListReq, conditionSql string) (data *bxcore.ParticipateData, err error) {
  643. defer MC.Catch()
  644. data = &bxcore.ParticipateData{
  645. NowTime: time.Now().Unix(),
  646. Count: 0,
  647. List: []*bxcore.ParticipateList{},
  648. }
  649. //员工|个人列表
  650. singlePersonSql := `SELECT %s FROM ` + ParticipateUserTable + ` pug LEFT JOIN project pt ON pug.project_id = pt.id LEFT JOIN (SELECT project_id,position_id,MAX(create_date) AS create_date FROM participate_bid_records GROUP BY project_id,position_id) pbr ON pbr.project_id = pug.project_id AND pbr.position_id = pug.position_id WHERE pug.position_id = ? `
  651. //singlePersonSql += conditionSql
  652. countSql := fmt.Sprintf(singlePersonSql, " COUNT(pt.id) ") + conditionSql
  653. count := IC.BaseMysql.CountBySql(countSql, in.PositionId)
  654. log.Println(countSql, "---", count)
  655. if count > 0 {
  656. data.Count = count
  657. listSql := fmt.Sprintf(singlePersonSql, " pt.*,pbr.create_date,pug.state ") + conditionSql
  658. //分页
  659. listSql += fmt.Sprintf(` LIMIT %d,%d`, in.PageNum, in.PageSize)
  660. log.Println("listSql:", listSql)
  661. list := IC.BaseMysql.SelectBySql(listSql, in.PositionId)
  662. if list != nil && len(*list) > 0 {
  663. for _, v := range *list {
  664. bidTimeStr := MC.ObjToString(v["bid_time"])
  665. bidEndTimeStr := MC.ObjToString(v["bid_end_time"])
  666. bidOpenTimeStr := MC.ObjToString(v["bid_open_time"])
  667. updateStatusTimeStr := MC.ObjToString(v["create_date"])
  668. beTransferred := true
  669. //已终止参标
  670. stateInt64 := MC.Int64All(v["state"])
  671. if stateInt64 < 0 {
  672. beTransferred = false
  673. }
  674. var bidTime, bidEndTime, bidOpenTime, updateStatusTime int64
  675. if bidTimeStr != "" {
  676. bidTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidTimeStr, time.Local)
  677. bidTime = bidTime_.Unix()
  678. }
  679. if bidEndTimeStr != "" {
  680. bidEndTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidEndTimeStr, time.Local)
  681. bidEndTime = bidEndTime_.Unix()
  682. //招标结束时间小于当前时间
  683. if beTransferred && bidEndTime > 0 && bidEndTime < time.Now().Unix() {
  684. beTransferred = false
  685. }
  686. }
  687. if bidOpenTimeStr != "" {
  688. bidOpenTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidOpenTimeStr, time.Local)
  689. bidOpenTime = bidOpenTime_.Unix()
  690. //招标开始时间小于当前时间
  691. if beTransferred && bidOpenTime > 0 && bidOpenTime < time.Now().Unix() {
  692. beTransferred = false
  693. }
  694. }
  695. if updateStatusTimeStr != "" {
  696. updateStatusTime_, _ := time.ParseInLocation(date.Date_Full_Layout, updateStatusTimeStr, time.Local)
  697. updateStatusTime = updateStatusTime_.Unix()
  698. }
  699. data.List = append(data.List, &bxcore.ParticipateList{
  700. Id: encrypt.EncodeArticleId2ByCheck(MC.ObjToString(v["id"])),
  701. ProjectName: MC.ObjToString(v["name"]),
  702. Buyer: MC.ObjToString(v["buyer"]),
  703. Budget: MC.ObjToString(v["budget"]),
  704. BidTime: bidTime,
  705. BidEndTime: bidEndTime,
  706. BidOpenTime: bidOpenTime,
  707. UpdateStatusTime: updateStatusTime,
  708. State: stateInt64,
  709. BeTransferred: beTransferred, //是否能划转
  710. //UpdateStatusCon: GetParticipateContent("s", in.PositionId, MC.ObjToString(v["id"])), //查询最后一次 投标状态更新,
  711. })
  712. }
  713. return data, nil
  714. }
  715. return nil, fmt.Errorf("数据异常")
  716. }
  717. return data, nil
  718. }
  719. // 管理员获取参标列表数据
  720. func AdminParticipateList(in *bxcore.ParticipateListReq, conditionSql string) (data *bxcore.ParticipateData, err error) {
  721. defer MC.Catch()
  722. data = &bxcore.ParticipateData{
  723. IsAllow: IsALLow(in.EntId),
  724. NowTime: time.Now().Unix(),
  725. Count: 0,
  726. List: []*bxcore.ParticipateList{},
  727. }
  728. adminSql := `SELECT %s FROM (SELECT pu.ent_id, pu.project_id, GROUP_CONCAT(pu.ent_user_id SEPARATOR ',') ent_user_id,MAX(pu.state) state FROM ` + ParticipateUserTable + ` pu WHERE pu.ent_id = ? AND NOT EXISTS ( SELECT 1 FROM ` + ParticipateUserTable + ` ppu WHERE ppu.project_id = pu.project_id AND ppu.ent_id = pu.ent_id AND ppu.state > pu.state ) GROUP BY pu.project_id ) pug LEFT JOIN project pt ON pug.project_id = pt.id LEFT JOIN (SELECT project_id,ent_id,MAX(create_date) AS create_date FROM participate_bid_records GROUP BY project_id,ent_id) pbr ON pbr.project_id = pug.project_id AND pbr.ent_id = pug.ent_id WHERE 1=1 `
  729. //maxStateSql := ``
  730. //stateSql := ``
  731. //if in.EntUserIds == "" {
  732. // //maxStateSql = `,MAX(pu.state) state`
  733. // stateSql = ``
  734. //}
  735. //adminSql = fmt.Sprintf(adminSql, "%s", stateSql)
  736. adminCountSql := fmt.Sprintf(adminSql, "COUNT(pt.id)") + conditionSql
  737. log.Println(adminCountSql)
  738. count := IC.BaseMysql.CountBySql(adminCountSql, in.EntId)
  739. if count > 0 {
  740. data.Count = count
  741. adminListSql := fmt.Sprintf(adminSql, " pt.*, pug.ent_user_id,pbr.create_date,pug.state ") + conditionSql + fmt.Sprintf(" LIMIT %d,%d", in.PageNum, in.PageSize)
  742. list := IC.BaseMysql.SelectBySql(adminListSql, in.EntId)
  743. if list != nil && len(*list) > 0 {
  744. for _, v := range *list {
  745. bidTimeStr := MC.ObjToString(v["bid_time"])
  746. bidEndTimeStr := MC.ObjToString(v["bid_end_time"])
  747. bidOpenTimeStr := MC.ObjToString(v["bid_open_time"])
  748. updateStatusTimeStr := MC.ObjToString(v["create_date"])
  749. beTransferred := true
  750. //已终止参标
  751. stateInt64 := MC.Int64All(v["state"])
  752. if stateInt64 < 0 {
  753. beTransferred = false
  754. }
  755. var bidTime, bidEndTime, bidOpenTime, updateStatusTime int64
  756. if bidTimeStr != "" {
  757. bidTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidTimeStr, time.Local)
  758. bidTime = bidTime_.Unix()
  759. }
  760. if bidEndTimeStr != "" {
  761. bidEndTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidEndTimeStr, time.Local)
  762. bidEndTime = bidEndTime_.Unix()
  763. //招标结束时间小于当前时间
  764. if beTransferred && bidEndTime > 0 && bidEndTime < time.Now().Unix() {
  765. beTransferred = false
  766. }
  767. }
  768. if bidOpenTimeStr != "" {
  769. bidOpenTime_, _ := time.ParseInLocation(date.Date_Full_Layout, bidOpenTimeStr, time.Local)
  770. bidOpenTime = bidOpenTime_.Unix()
  771. //招标开始时间小于当前时间
  772. if beTransferred && bidOpenTime > 0 && bidOpenTime < time.Now().Unix() {
  773. beTransferred = false
  774. }
  775. }
  776. if updateStatusTimeStr != "" {
  777. updateStatusTime_, _ := time.ParseInLocation(date.Date_Full_Layout, updateStatusTimeStr, time.Local)
  778. updateStatusTime = updateStatusTime_.Unix()
  779. }
  780. data.List = append(data.List, &bxcore.ParticipateList{
  781. Id: encrypt.EncodeArticleId2ByCheck(MC.ObjToString(v["id"])),
  782. ProjectName: MC.ObjToString(v["name"]),
  783. Buyer: MC.ObjToString(v["buyer"]),
  784. Budget: MC.ObjToString(v["budget"]),
  785. BidTime: bidTime,
  786. BidEndTime: bidEndTime,
  787. BidOpenTime: bidOpenTime,
  788. UpdateStatusTime: updateStatusTime,
  789. State: stateInt64,
  790. BeTransferred: beTransferred, //是否能划转
  791. //UpdateStatusCon: GetParticipateContent("e", in.EntId, MC.ObjToString(v["id"])), //查询最后一次 投标状态更新
  792. Participants: GetParticipateUserName(MC.ObjToString(v["id"]), MC.ObjToString(v["ent_user_id"]), in.EntUserIds != ""), //参标人信息
  793. })
  794. }
  795. return data, nil
  796. }
  797. return nil, fmt.Errorf("数据异常")
  798. }
  799. return data, nil
  800. }
  801. // 获取最新参标 更新内容
  802. func GetParticipateContent(s string, id int64, projectId string) string {
  803. identitySql := `ent_id = ?`
  804. if s == "s" {
  805. identitySql = `position_id = ?`
  806. }
  807. recordsSql := `SELECT record_content,record_type FROM ` + ParticipateBidRecordsTable + ` WHERE ` + identitySql + ` AND project_id = ? ORDER BY create_date DESC LIMIT 1;`
  808. records := IC.BaseMysql.SelectBySql(recordsSql, id, projectId)
  809. if records != nil && len(*records) > 0 {
  810. rec := (*records)[0]
  811. switch MC.IntAll(rec["record_type"]) {
  812. case 0:
  813. return MC.ObjToString(rec["record_content"])
  814. case 1:
  815. recordContent := *MC.ObjToMap(rec["record_content"])
  816. rb, err := json.Marshal(recordContent)
  817. if err != nil {
  818. log.Println(err.Error())
  819. return ""
  820. }
  821. var rc = RecordsContent{
  822. After: PartStatusContent{},
  823. Before: PartStatusContent{},
  824. }
  825. err1 := json.Unmarshal(rb, &rc)
  826. if err1 == nil {
  827. return rc.Content
  828. }
  829. }
  830. }
  831. return ""
  832. }
  833. // 根据ent_user_id 获取参标人昵称,企业管理员现在都是“我”
  834. func GetParticipateUserName(projectId, entUserIdsFromData string, b bool) string {
  835. if entUserIdsFromData != "" {
  836. var userNames []string
  837. for _, v := range strings.Split(entUserIdsFromData, ",") {
  838. if b {
  839. //已终止参标
  840. if c := IC.BaseMysql.CountBySql(`SELECT count(id) FROM `+ParticipateUserTable+` WHERE project_id = ? AND ent_user_id = ? AND state <0`, projectId, v); c > 0 {
  841. continue
  842. }
  843. }
  844. entUserInfos := IC.MainMysql.SelectBySql(`SELECT * FROM entniche_user WHERE id = ?`, v)
  845. if entUserInfos != nil && len(*entUserInfos) > 0 {
  846. entUserInfo := (*entUserInfos)[0]
  847. if entUserInfo["name"] != nil {
  848. if userName := MC.ObjToString(entUserInfo["name"]); userName != "" {
  849. userNames = append(userNames, userName)
  850. }
  851. }
  852. }
  853. }
  854. return strings.Join(userNames, ",")
  855. }
  856. return ""
  857. }
  858. // GetBidContentEnt 企业版 获取投标状态更新内容
  859. func GetBidContentEnt(projectId string, entId int64) *[]map[string]interface{} {
  860. // record_type '默认0:参标、划转、取消参标;1:投标状态更新存储'
  861. query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and ent_id=? and record_type=1 order by create_date desc limit 1; "
  862. return IC.BaseMysql.SelectBySql(query, projectId, entId)
  863. }
  864. // GetBidContentPersonal 个人版 获取投标状态更新内容
  865. func GetBidContentPersonal(projectId string, positionId int64) *[]map[string]interface{} {
  866. query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? and record_type=1 order by create_date desc limit 1;"
  867. return IC.BaseMysql.SelectBySql(query, projectId, positionId)
  868. }
  869. // UpdateBidContent 更新投标状态信息以及操作记录
  870. func UpdateBidContent(recordData map[string]interface{}) (flag bool) {
  871. r2 := IC.BaseMysql.Insert(ParticipateBidRecordsTable, recordData)
  872. return r2 > 0
  873. }
  874. // InsertBidContent 新增投标状态信息及操作记录
  875. func InsertBidContent(recordData map[string]interface{}) (flag bool) {
  876. r2 := IC.BaseMysql.Insert(ParticipateBidRecordsTable, recordData)
  877. return r2 > 0
  878. }
  879. // GetBidRecordsEnt 获取操作记录列表企业
  880. func GetBidRecordsEnt(projectId string, entId, page, pageSize int64) (rs *[]map[string]interface{}, total int64) {
  881. query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and ent_id=? order by create_date desc limit ?,?"
  882. countQuery := "SELECT count(id) FROM " + ParticipateBidRecordsTable + " where project_id=? and ent_id=? ;"
  883. rs = IC.BaseMysql.SelectBySql(query, projectId, entId, (page-1)*pageSize, pageSize)
  884. total = IC.BaseMysql.CountBySql(countQuery, projectId, entId)
  885. return rs, total
  886. }
  887. // GetBidRecordsPersonal 获取操作记录列表个人
  888. func GetBidRecordsPersonal(projectId string, positionId, page, pageSize int64) (rs *[]map[string]interface{}, total int64) {
  889. query := "SELECT * FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? order by create_date desc limit ?,?;"
  890. countQuery := "SELECT count(id) FROM " + ParticipateBidRecordsTable + " where project_id=? and position_id=? ;"
  891. rs = IC.BaseMysql.SelectBySql(query, projectId, positionId, (page-1)*pageSize, pageSize)
  892. total = IC.BaseMysql.CountBySql(countQuery, projectId, positionId)
  893. return rs, total
  894. }
  895. // GetUserMap 查询用户id的姓名
  896. func GetUserMap(userIds string) (rs *[]map[string]interface{}) {
  897. query := fmt.Sprintf("select id,name from entniche_user where id in (%s)", userIds)
  898. rs = IC.MainMysql.SelectBySql(query)
  899. return rs
  900. }
  901. // CheckParticipateManager 验证项目id是否是该管理员企业下的参标项目
  902. func CheckParticipateManager(projectId string, entId int64, valid bool) (flag bool) {
  903. stateStr := "" // 是否需要验证是正在参标
  904. if valid {
  905. stateStr = " and state=0"
  906. }
  907. query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and ent_id=?" + stateStr
  908. return IC.BaseMysql.CountBySql(query, projectId, entId) > 0
  909. }
  910. // CheckParticipateEntUser 验证项目id是否是该企业用户参标的项目
  911. func CheckParticipateEntUser(projectId string, entUserId int64, valid bool) (flag bool) {
  912. stateStr := "" // 是否需要验证是正在参标
  913. if valid {
  914. stateStr = " and state=0"
  915. }
  916. query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and ent_user_id=?" + stateStr
  917. return IC.BaseMysql.CountBySql(query, projectId, entUserId) > 0
  918. }
  919. // CheckParticipatePersonal 查询项目id是否是该用户参标项目
  920. func CheckParticipatePersonal(projectId string, positionId int64, valid bool) (flag bool) {
  921. stateStr := "" // 是否需要验证是正在参标 终止参标的用户还能查看记录,但是不能更新状态
  922. if valid {
  923. stateStr = " and state=0"
  924. }
  925. query := "SELECT count(id) FROM " + ParticipateUserTable + " where project_id=? and position_id=?" + stateStr
  926. return IC.BaseMysql.CountBySql(query, projectId, positionId) > 0
  927. }
  928. // GetNameByUserIds 获取用户名字符串
  929. //
  930. // 参数:逗号分割的用户id "11,22,333..."
  931. // 返回: "张三,李四,王五..."
  932. func GetNameByUserIds(ids string) *[]map[string]interface{} {
  933. query := "select group_concat(name) as name from " + EntnicheUserTable + " where id in (" + ids + ") "
  934. rs := IC.MainMysql.SelectBySql(query)
  935. return rs
  936. }
  937. // ParticipateProjectPersonal 查询给定项目id中已经参标的项目id
  938. func ParticipateProjectPersonal(positionId int64, projectId []string) *[]map[string]interface{} {
  939. // 1. 查询出已经参标的
  940. var arg []string
  941. var value []interface{}
  942. value = append(value, positionId)
  943. for i := 0; i < len(projectId); i++ {
  944. arg = append(arg, "?")
  945. value = append(value, projectId[i])
  946. }
  947. argStr := strings.Join(arg, ",")
  948. query := "select project_id from " + ParticipateUserTable + " where position_id = ? and project_id in (%s) and state=0"
  949. rs := IC.BaseMysql.SelectBySql(fmt.Sprintf(query, argStr), value...)
  950. return rs
  951. }
  952. // ParticipateProjectEnt 查询给定项目id中已经参标的项目id
  953. func ParticipateProjectEnt(entId int64, projectId []string) *[]map[string]interface{} {
  954. // 1. 查询出已经参标的
  955. var arg []string
  956. var value []interface{}
  957. value = append(value, entId)
  958. for i := 0; i < len(projectId); i++ {
  959. arg = append(arg, "?")
  960. value = append(value, projectId[i])
  961. }
  962. argStr := strings.Join(arg, ",")
  963. 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 "
  964. rs := IC.BaseMysql.SelectBySql(fmt.Sprintf(query, argStr), value...)
  965. return rs
  966. }
  967. // 查询企业人员信息
  968. func GetPersonInfo(entId, entUserId int64, participateMap map[int64]bool) []*bxcore.ParticipatePerson {
  969. 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
  970. INNER JOIN entniche_department_user b on (a.ent_id=? and a.id=b.dept_id)
  971. INNER JOIN entniche_user c on (b.user_id=c.id)
  972. LEFT JOIN entniche_user_role d on (c.id=d.user_id)
  973. LEFT JOIN entniche_role e on (d.role_id=e.id)
  974. order by a.id,convert(c.name using gbk) COLLATE gbk_chinese_ci asc`, entId)
  975. var (
  976. list []*bxcore.ParticipatePerson
  977. prevId int64 = 0
  978. )
  979. for _, v := range *r {
  980. //if entUserId == MC.Int64All(v["user_id"]) {
  981. // continue
  982. //}
  983. id := MC.Int64All(v["id"])
  984. userId := strconv.FormatInt(MC.Int64All(v["user_id"]), 10)
  985. user := &bxcore.ParticipatePerson{
  986. Id: encrypt.SE.Encode2HexByCheck(userId),
  987. Power: MC.Int64All(v["user_power"]),
  988. Name: MC.ObjToString(v["user_name"]),
  989. Phone: MC.ObjToString(v["user_phone"]),
  990. Role: MC.ObjToString(v["role"]),
  991. }
  992. if participateMap != nil {
  993. if participateMap[MC.Int64All(v["user_id"])] {
  994. user.IsPart = 1
  995. }
  996. }
  997. if prevId == id {
  998. users := list[len(list)-1].Users
  999. users = append(users, user)
  1000. list[len(list)-1].Users = users
  1001. } else {
  1002. seId := strconv.FormatInt(id, 10)
  1003. list = append(list, &bxcore.ParticipatePerson{
  1004. Id: encrypt.SE.Encode2HexByCheck(seId),
  1005. Name: MC.ObjToString(v["name"]),
  1006. Pid: MC.Int64All(v["pid"]),
  1007. Users: []*bxcore.ParticipatePerson{user},
  1008. })
  1009. }
  1010. prevId = id
  1011. }
  1012. return list
  1013. }
  1014. // 是否允许多人参标
  1015. func IsALLow(entId int64) bool {
  1016. return GetParticipateIsAllow(map[string]interface{}{
  1017. "i_entid": entId,
  1018. })
  1019. }