participateBid.go 38 KB

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