participateBid.go 39 KB

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