user.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. package jyutil
  2. import (
  3. "app.yhyue.com/moapp/jybase/common"
  4. "app.yhyue.com/moapp/jybase/date"
  5. "app.yhyue.com/moapp/jybase/mongodb"
  6. "app.yhyue.com/moapp/jybase/usercenter"
  7. "bytes"
  8. "context"
  9. "encoding/json"
  10. "fmt"
  11. "github.com/gogf/gf/v2/frame/g"
  12. "github.com/gogf/gf/v2/util/gconv"
  13. "github.com/pkg/errors"
  14. "io/ioutil"
  15. "jyOrderManager/internal/consts"
  16. "jyOrderManager/internal/model"
  17. "log"
  18. "net/http"
  19. "strings"
  20. "time"
  21. )
  22. // GetCreateUserData 查询用户 不存在注册用户 isEntSign 是否需要注册企业信息(避免校验调用) 如entId不为0代办已注册企业信息
  23. func GetCreateUserData(phone, companyName string, isEntSign bool) (data map[string]interface{}, entId, userPositionId int64, err error) {
  24. data = make(map[string]interface{})
  25. userData, ok := MG.DB().FindOne("user", map[string]interface{}{
  26. "$or": []map[string]interface{}{
  27. {"s_phone": phone},
  28. {"s_m_phone": phone},
  29. },
  30. })
  31. if ok && userData != nil && len(*userData) > 0 {
  32. data = *userData
  33. } else {
  34. id := MG.DB().Save("user", map[string]interface{}{
  35. "i_appid": 2,
  36. "s_phone": phone,
  37. "s_password": "",
  38. "l_registedate": time.Now().Unix(),
  39. "i_ts_guide": 2,
  40. "o_jy": map[string]interface{}{
  41. "i_wxpush": 1,
  42. "i_apppush": 1,
  43. "i_ratemode": 2,
  44. "l_modifydate": time.Now().Unix(),
  45. },
  46. "s_regsource": "qmx_admin",
  47. })
  48. if id == "" {
  49. return nil, 0, 0, fmt.Errorf("创建用户失败")
  50. }
  51. ck := &http.Cookie{}
  52. usercenter.AddBaseUser(*MG.DB(), g.Cfg().MustGet(ctx, "userCenterUrl").String(), id, map[string]interface{}{
  53. "appid": 10000,
  54. "phone": phone,
  55. "password": "",
  56. }, ck)
  57. SaveUserLog(id, phone)
  58. uData, _ := MG.DB().FindById("user", id, "")
  59. data = *uData
  60. }
  61. data["userId"] = common.InterfaceToStr(data["_id"])
  62. //企业查询企业信息是否注册
  63. if isEntSign {
  64. entUser, err := g.DB().Ctx(ctx).GetOne(ctx, fmt.Sprintf(`SELECT a.ent_id FROM entniche_user a
  65. LEFT JOIN entniche_info b on b.name='%s' and a.ent_id = b.id
  66. WHERE phone = '%s' limit 1`, companyName, phone))
  67. if err != nil {
  68. return nil, 0, 0, errors.Wrapf(err, "查询企业是否存在异常 %s", companyName)
  69. }
  70. entId = gconv.Int64(entUser.Map()["ent_id"])
  71. if entId == 0 {
  72. entId, userPositionId, err = AutomaticallyCreatingEnt(companyName, phone, "", common.InterfaceToStr(data["_id"]))
  73. if err != nil {
  74. return nil, 0, 0, errors.Wrapf(err, "创建企业异常 %s", companyName)
  75. }
  76. } else {
  77. //查找baseUserId
  78. baseUserId := common.Int64All(data["base_user_id"])
  79. positionData, _ := g.DB().Ctx(ctx).GetOne(ctx, fmt.Sprintf(`SELECT s_name FROM base_position WHERE type=1 and user_id='%d' and ent_id=%d`, baseUserId, entId))
  80. if !positionData.IsEmpty() {
  81. userPositionId = gconv.Int64(positionData.Map()["id"])
  82. }
  83. }
  84. }
  85. return data, entId, userPositionId, nil
  86. }
  87. // 用户注册日志保存
  88. func SaveUserLog(userid, phone string) {
  89. data := map[string]interface{}{
  90. "userid": userid,
  91. "phone": phone,
  92. "way": "phone",
  93. "system": "pc",
  94. "source": "background",
  95. "create_time": date.NowFormat(date.Date_Full_Layout),
  96. }
  97. MG.DB().Save("register_log", data)
  98. }
  99. func GetUserFullId(phone, companyName string) (mongoUserId string, baseUserId, entId, entUserId int64) {
  100. userData, ok := MG.DB().FindOne("user", map[string]interface{}{
  101. "$or": []map[string]interface{}{
  102. {"s_phone": phone},
  103. {"s_m_phone": phone},
  104. },
  105. })
  106. if ok && userData != nil && len(*userData) > 0 {
  107. mongoUserId = mongodb.BsonIdToSId((*userData)["_id"])
  108. baseUserId = gconv.Int64((*userData)["base_user_id"])
  109. }
  110. if companyName == "" {
  111. entUser, err := g.DB().Ctx(ctx).GetOne(ctx, fmt.Sprintf(`SELECT a.ent_id,a.id FROM entniche_user a
  112. LEFT JOIN entniche_info b on b.name='%s' and a.ent_id = b.id
  113. WHERE phone = '%s' limit 1`, companyName, phone))
  114. if err == nil && !entUser.IsEmpty() {
  115. entId = gconv.Int64(entUser.Map()["ent_id"])
  116. entUserId = gconv.Int64(entUser.Map()["id"])
  117. }
  118. }
  119. return
  120. }
  121. var getPositionIdByMongoUserId = func(mgoUserId string) int64 {
  122. userData, ok := MG.DB().FindById("user", mgoUserId, `"base_user_id":1`)
  123. if userData != nil && len(*userData) > 0 && ok {
  124. baseUserId := common.Int64All((*userData)["base_user_id"])
  125. positionData, _ := g.DB("base").GetOne(ctx, "SELECT id FROM base_position WHERE type=0 and ent_id=0 and user_id=?", baseUserId)
  126. if !positionData.IsEmpty() {
  127. return gconv.Int64(positionData.Map()["id"])
  128. }
  129. }
  130. return -1
  131. }
  132. func ClearBigVipUserPower(ctx context.Context, userId string) {
  133. var (
  134. powerChacheKey = g.Cfg().MustGet(ctx, "bigmemberKey", "bigmember_power_3_").String()
  135. IsGetUserBaseInfoRedisKey = "baseinfo_%s"
  136. RedisMenuKeyPC = "jy_workdesktopmenu_10000_PC_menu1_%s" //剑鱼appid:10000
  137. RedisMenuKeyWX = "jy_workdesktopmenu_10000_WX_menu1_%s" //剑鱼appid:10000
  138. RedisMenuKeyAPP = "jy_workdesktopmenu_10000_APP_menu1_%s" //剑鱼appid:10000
  139. UserPowerRedisKey = "jy_userpowerredis_10000_%d_%s" //工作桌面 用户功能缓存(类似bigmember_power_3_%s)
  140. )
  141. if mongodb.IsObjectIdHex(userId) {
  142. user_id := userId
  143. //大会员主账号清理
  144. userDatas, ok := MG.DB().Find("user", map[string]interface{}{"s_member_mainid": user_id, "i_member_sub_status": 1}, nil, nil, false, -1, -1)
  145. if ok && userDatas != nil && len(*userDatas) > 0 {
  146. for _, v := range *userDatas {
  147. if pId := getPositionIdByMongoUserId(mongodb.BsonIdToSId(v["_id"])); pId > 0 {
  148. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("%s%d", powerChacheKey, pId))
  149. }
  150. }
  151. }
  152. //通过mongo查找职位标识
  153. if pId := getPositionIdByMongoUserId(userId); pId > 0 {
  154. userId = fmt.Sprint(pId)
  155. }
  156. }
  157. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf(powerChacheKey, userId))
  158. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("jy_workdesktopmenu_10000_menu1_%s", userId))
  159. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("jy_userpowerredis_10000_17_%s", userId))
  160. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("jy_workdesktopmenu_10000_menu2_%s", userId))
  161. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("jy_workdesktopmenu_10000_PC_menu2_%s", userId))
  162. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("jy_workdesktopmenu_10000_WX_menu2_%s", userId))
  163. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("jy_workdesktopmenu_10000_APP_menu2_%s", userId))
  164. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf("user_power_info_%s", userId))
  165. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf(IsGetUserBaseInfoRedisKey, userId))
  166. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf(RedisMenuKeyPC, userId))
  167. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf(RedisMenuKeyWX, userId))
  168. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf(RedisMenuKeyAPP, userId))
  169. _, _ = g.Redis("newother").Del(ctx, fmt.Sprintf(UserPowerRedisKey, time.Now().Day(), userId))
  170. _, _ = g.Redis("newother").Del(ctx, "pl_indexMessage_"+userId)
  171. }
  172. func PayUserIdentitySwitchRedis(mgoUserId string, data map[string]interface{}) {
  173. key := fmt.Sprintf("jy_identitySwitch_%s", mgoUserId)
  174. _ = g.Redis("newother").SetEX(ctx, key, data, -1)
  175. }
  176. func GetUserMsgFromCtx(ctx context.Context) *model.User {
  177. if value := ctx.Value(consts.ContextKey); value != nil {
  178. if c, ok := value.(*model.User); ok {
  179. return c
  180. }
  181. }
  182. return nil
  183. }
  184. func GetUserDeptIdFromCtx(ctx context.Context) int64 {
  185. if u := GetUserMsgFromCtx(ctx); u != nil {
  186. return u.EntDeptId
  187. }
  188. return 0
  189. }
  190. func MultipleSaveMsg(msg map[string]interface{}, userIds, positionIds string) {
  191. log.Println("开始调用MultipleSaveMsg保存消息")
  192. idsJson, _ := json.Marshal(map[string]interface{}{"msgInfo": msg, "userIds": userIds, "userNames": "对公转账审批", "positionIds": positionIds})
  193. reqData := bytes.NewBuffer([]byte(idsJson))
  194. multipleSaveMsgUrl := common.ObjToString(g.Cfg().MustGet(context.Background(), "multipleSaveMsgUrl").String())
  195. method := "POST"
  196. client := &http.Client{}
  197. req, err := http.NewRequest(method, multipleSaveMsgUrl, reqData)
  198. if err != nil {
  199. log.Println("MultipleSaveMsg构造请求出错:", err)
  200. return
  201. }
  202. req.Header.Add("Content-Type", "application/json")
  203. res, err := client.Do(req)
  204. if err != nil {
  205. log.Println("MultipleSaveMsg发送请求出错:", err)
  206. return
  207. }
  208. defer res.Body.Close()
  209. body, err := ioutil.ReadAll(res.Body)
  210. if err != nil {
  211. log.Println("MultipleSaveMsg读取返回值出错:", err)
  212. return
  213. }
  214. dat := make(map[string]interface{})
  215. err = json.Unmarshal(body, &dat)
  216. if err != nil {
  217. log.Println("MultipleSaveMsg Unmarshal 出错:", err, msg)
  218. }
  219. //log.Println("调用中台返回结果", dat)
  220. return
  221. }
  222. // GetPositionByPhone 获取当前销售人员职位id
  223. func GetPositionByPhone(phone string) (int64, error) {
  224. res, _ := g.DB().GetOne(ctx, `SELECT b.id FROM base_service.base_user u INNER JOIN base_service.base_position b on(u.id=b.user_id AND b.ent_id = '25917' AND u.phone=?)`, phone)
  225. if res.IsEmpty() {
  226. return -1, fmt.Errorf("查询职位id异常")
  227. }
  228. posId := common.Int64All(res.Map()["id"])
  229. if posId <= 0 {
  230. return -1, fmt.Errorf("获取职位id异常")
  231. }
  232. return posId, nil
  233. }
  234. // sellerCheck 查询当前销售是否有权限操作改用户
  235. // 规则 满足1和2中任意一条
  236. // 1.新增-管理后台与电销系统用户匹配:同步电销系统组织架构,根据手机号对管理后台用户与电销系统的人员进行匹配;
  237. // 2.“帮助用户下单”增加限制条件,即下单用户需在下单电销人员私海里,且近期电销人员与该用户有过沟通,“有过沟通”判断依据(满足以下任意1个条件即可):
  238. // (1)最近3天(可配置)该电销人员与用户存在通话时长≥60秒(可配置);
  239. // (2)最近3天(可配置)该电销人员与该用户存在已上传附件的跟进记录;
  240. // (3)该电销人员与该用户正在通话中。
  241. func SellerCheck(ctx context.Context, posId int64, UserPhone string) error {
  242. var (
  243. total int
  244. err error
  245. )
  246. total, err = g.DB("subject").GetCount(ctx, fmt.Sprintf("SELECT * FROM dwd_f_crm_clue_info a inner join dwd_f_userbase_contacts b on a.uid=b.baseinfo_id WHERE b.phone='%s' and a.position_id=%d", UserPhone, posId))
  247. if err != nil {
  248. return err
  249. }
  250. if total == 0 {
  251. return fmt.Errorf("不满足代用户下单条件,不支持下单")
  252. }
  253. //2(1)
  254. var (
  255. uid string
  256. phoneArr []string
  257. phonesStr string
  258. )
  259. res, err := g.DB("subject").Query(ctx, fmt.Sprintf("SELECT baseinfo_id,phone FROM dwd_f_userbase_contacts WHERE baseinfo_id=(SELECT baseinfo_id FROM dwd_f_userbase_contacts WHERE phone='%s')", UserPhone))
  260. if res.IsEmpty() {
  261. return fmt.Errorf("查询手机号异常")
  262. }
  263. for i, m := range res.List() {
  264. if i == 0 {
  265. uid = common.ObjToString(m["baseinfo_id"])
  266. }
  267. if p := common.ObjToString(m["phone"]); p != "" {
  268. phoneArr = append(phoneArr, p)
  269. }
  270. }
  271. phonesStr = strings.Join(phoneArr, "','")
  272. //(1)最近3天(可配置)该电销人员与用户存在通话时长≥60秒(可配置);
  273. if num, err := g.DB("subject").GetCount(ctx, fmt.Sprintf(`SELECT *
  274. FROM Call_Accounting.voice_record
  275. WHERE CallTimeLength >= ?
  276. AND Ring > (SELECT DATE_SUB(NOW(), INTERVAL ? HOUR))
  277. AND Exten IN (
  278. SELECT seat_number
  279. FROM dwd_f_crm_personnel_management
  280. WHERE position_id = ?
  281. )
  282. AND (CallNo in ('%s') or CalledNo in ('%s'))`, phonesStr, phonesStr), g.Cfg().MustGet(ctx, "helpUserOrder.talkTimeLong", 60).Int64(), g.Cfg().MustGet(ctx, "helpUserOrder.talkHourLimit", 72).Int64(), posId); err == nil && num > 0 {
  283. return nil
  284. }
  285. //(2)最近3天(可配置)该电销人员与该用户存在已上传附件的跟进记录;
  286. if num, err := g.DB("subject").GetCount(ctx, `SELECT *
  287. FROM dwd_f_crm_clue_info a
  288. INNER JOIN dwd_f_crm_trail_content b ON a.id =b.clue_id
  289. INNER JOIN attachment c ON b.id =c.change_id
  290. WHERE a.uid =? AND b.createtime >DATE_SUB(NOW(), INTERVAL ? HOUR) AND type='跟进记录附件'`, uid, g.Cfg().MustGet(ctx, "helpUserOrder.trailAttach", 72).Int64()); err == nil && num > 0 {
  291. return nil
  292. }
  293. //(3)该电销人员与该用户正在通话中。
  294. if num, err := g.DB("subject").GetCount(ctx, `SELECT * FROM dwd_f_userbase_contacts
  295. WHERE baseinfo_id=? AND is_talking=1
  296. AND is_talking_seat_number IN(
  297. SELECT seat_number
  298. FROM dwd_f_crm_personnel_management
  299. WHERE position_id = ?)`, uid, posId); err == nil && num > 0 {
  300. return nil
  301. }
  302. return fmt.Errorf("不满足代用户下单条件,不支持下单")
  303. }