user.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. package entity
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "sync"
  8. "time"
  9. MC "app.yhyue.com/moapp/jybase/common"
  10. "app.yhyue.com/moapp/jybase/redis"
  11. )
  12. const (
  13. IsNewFreeTimeCell = 1637830020
  14. BigMemberUserPowerTable = "bigmember_service_user"
  15. RedisCode = "newother"
  16. RedisMenuKey = "jy_workdesktopmenu_%s_%s_%s"
  17. UserPowerRedisKey = "jy_userpowerredis_%s_%d_%s"
  18. UserEntIdKey = "jy_userentid_%s_%d_%s"
  19. UserRegisterTime = "jy_userregistertime_%s"
  20. )
  21. type UserInfo struct {
  22. Capitals map[string]int
  23. Permissions map[string]int
  24. Lock *sync.Mutex
  25. }
  26. var (
  27. CapitalRetention = "capital_retention"
  28. //UserCapitals = map[string]map[string]int{}
  29. //UserPermissions = map[string]map[string]int{}
  30. //UserLock = map[string]*sync.Mutex{}
  31. OverallLock = &sync.Mutex{}
  32. UserInfoMap = map[string]*UserInfo{}
  33. UserRolePowers = map[string][]string{}
  34. )
  35. /*
  36. *待调整 调整为存redis
  37. *测试用例放的地方不对 待调整
  38. */
  39. //用户权限 初始化
  40. func (m *WorkDesktopMenu) AutoUserPowerInfo() map[string]int {
  41. /*
  42. * 商机管理--》新版商机管理vs老版商机管理
  43. * 大会员--》bigmember_service
  44. * 超级订阅--》新版超级订阅vs老版超级订阅
  45. * 免费用户--》新免费用户
  46. */
  47. var UserPowerMap = map[string]int{}
  48. //redis newother 查询是否存在用户功能信息
  49. userPowerRedisKey := fmt.Sprintf(UserPowerRedisKey, m.AppId, time.Now().Day(), m.UserId)
  50. bytes, err := redis.GetBytes(RedisCode, userPowerRedisKey)
  51. if err == nil && len(*bytes) > 0 {
  52. if err = json.Unmarshal(*bytes, &UserPowerMap); err == nil {
  53. return UserPowerMap
  54. }
  55. }
  56. //查询用户信息
  57. data, ok := Mgo.FindById("user", m.UserId, `{"s_phone":1,"s_m_phone":1,i_member_status":1,“i_member_endtime”:1,"s_member_mainid":1,"i_member_sub_status":1,"i_vip_status":1,"l_vip_endtime":1,"o_vipjy":1,"o_jy":1,"l_registedate":1}`)
  58. if ok && *data != nil && len(*data) > 0 {
  59. var (
  60. isFree = true
  61. //第一版领域化权限判断 ;第二版:超级订阅||大会员 到期时间超过90天
  62. //商机管理服务 前提是超级订阅、大会员、医械通
  63. domainBool = false
  64. registerTime int64 = 0
  65. )
  66. phone, _ := MC.If((*data)["s_phone"] != nil, (*data)["s_phone"], (*data)["s_m_phone"]).(string)
  67. if phone != "" {
  68. //同一个手机号 多个商机管理角色 其中一个是企业管理员或者部门管理员 查的时候按角色权重排序
  69. entNicheInfos := Mysql.SelectBySql(`SELECT i.isNew,r.role_id,u.ent_id FROM (entniche_user u LEFT JOIN entniche_user_role r ON r.user_id = u.id) LEFT JOIN entniche_info i ON u.ent_id=i.id WHERE u.phone = ? and u.power=1 and i.status=1 ORDER BY r.role_id,i.isNew DESC`, phone)
  70. //商机管理用户信息判断
  71. if entNicheInfos != nil && len(*entNicheInfos) > 0 {
  72. isFree = false
  73. for _, entNicheInfo := range *entNicheInfos {
  74. //判断是否是当前企业
  75. ent_id := MC.Int64All(entNicheInfo["ent_id"])
  76. if m.EntId > 0 && ent_id != m.EntId {
  77. continue
  78. }
  79. //entNicheInfo := (*entNicheInfos)[0]
  80. switch MC.IntAll(entNicheInfo["isNew"]) {
  81. case 1: //新版商机管理
  82. UserPowerMap["110"] = 1
  83. switch MC.IntAll(entNicheInfo["role_id"]) {
  84. case 1: //部门管理员
  85. UserPowerMap["111"] = 1
  86. case 2: //企业管理员
  87. UserPowerMap["112"] = 1
  88. }
  89. case 0: //老版商机管理
  90. UserPowerMap["100"] = 1
  91. switch MC.IntAll(entNicheInfo["role_id"]) {
  92. case 1: //部门管理员
  93. UserPowerMap["101"] = 1
  94. case 2: //企业管理员
  95. UserPowerMap["102"] = 1
  96. }
  97. }
  98. }
  99. }
  100. //大会员
  101. if memberStatus := MC.IntAll((*data)["i_member_status"]); memberStatus > 0 || ConfigJson.BigMemberOff {
  102. mainUserId := m.UserId
  103. if memberStatus > 0 {
  104. registerTime = MC.Int64All((*data)["i_member_endtime"])
  105. domainBool = true
  106. isFree = false
  107. UserPowerMap["0"] = memberStatus
  108. //是否是子账号 而且 子账号被启用
  109. if (*data)["s_member_mainid"] != nil && MC.ObjToString((*data)["s_member_mainid"]) != "" && MC.IntAllDef((*data)["i_member_sub_status"], 0) > 0 {
  110. mainUserId = MC.ObjToString((*data)["s_member_mainid"])
  111. }
  112. }
  113. //大会员用户购买的服务
  114. serviceList := Mysql.Find(BigMemberUserPowerTable, map[string]interface{}{"s_userid": mainUserId, "i_status": 0}, "DISTINCT(s_serviceid),i_frequency", "", -1, -1)
  115. if serviceList != nil && len(*serviceList) != 0 {
  116. for _, sv := range *serviceList {
  117. UserPowerMap[MC.ObjToString(sv["s_serviceid"])] = MC.If(MC.IntAll(sv["i_frequency"]) > 0, MC.IntAll(sv["i_frequency"]), memberStatus).(int)
  118. }
  119. }
  120. }
  121. //VIP用户
  122. if vipStatus := MC.IntAll((*data)["i_vip_status"]); vipStatus > 0 {
  123. if registerTime < MC.Int64All((*data)["l_vip_endtime"]) {
  124. registerTime = MC.Int64All((*data)["l_vip_endtime"])
  125. }
  126. domainBool = true
  127. isFree = false
  128. UserPowerMap["200"] = vipStatus
  129. if vipSet := MC.ObjToMap((*data)["o_vipjy"]); vipSet != nil {
  130. if buySet := MC.ObjToMap((*vipSet)["o_buyset"]); buySet != nil {
  131. //vip 升级用户
  132. if MC.IntAll((*buySet)["upgrade"]) > 0 {
  133. UserPowerMap["201"] = vipStatus
  134. }
  135. }
  136. }
  137. }
  138. //免费用户
  139. if isFree {
  140. UserPowerMap["300"] = 1
  141. freeSet := MC.ObjToMap((*data)["o_jy"])
  142. if MC.IntAll((*freeSet)["i_newfree"]) > 0 || IsNewFreeTimeCell < MC.IntAll((*data)["l_registedate"]) {
  143. //新免费用户
  144. UserPowerMap["301"] = 1
  145. }
  146. }
  147. //广东移动DICT
  148. if Mysql.CountBySql(`select count(*) from privatedata where phone = ?`, phone) > 0 {
  149. UserPowerMap["400"] = 1
  150. }
  151. //资源中台获取权限
  152. powerList := GetResources(m.AppId, m.NewUserId, m.EntId, m.EntUserId)
  153. if len(powerList) > 0 {
  154. for _, plv := range powerList {
  155. UserPowerMap[plv] = 1
  156. }
  157. }
  158. //领域化产品权限
  159. //第一版:必须是大会员或者超级订阅用户 且留资 留资表:capital_retention;source = 'medical_domain',未留资提示留资信息
  160. //第二版:调资源中台rpc获取用户是否有使用领域化产品的权限 无权限则去购买
  161. //需求调整:
  162. //1:是否是大会员或者超级订阅用户 否:提示购买到超级订阅购买页; 是>-2
  163. //2:判断用户是否留资 否:提示用去留资;是:>-3
  164. //3:资源中台获取用户权限码判断是否有权限 否:提示用户去联系客服
  165. if domainBool {
  166. userRegisterTimeKey := fmt.Sprintf(UserRegisterTime, m.UserId)
  167. redis.Put(RedisCode, userRegisterTimeKey, strconv.Itoa(int(registerTime)), int(registerTime))
  168. UserPowerMap["500"] = 1
  169. }
  170. }
  171. if UserPowerMap != nil {
  172. bytes, err := json.Marshal(UserPowerMap)
  173. if err == nil && len(bytes) > 0 {
  174. redis.PutBytes(RedisCode, userPowerRedisKey, &bytes, ConfigJson.InternalTime)
  175. if m.EntId > 0 {
  176. //商机管理用户entId 缓存
  177. userEntIdKey := fmt.Sprintf(UserEntIdKey, m.AppId, time.Now().Day(), m.UserId)
  178. redis.Put(RedisCode, userEntIdKey, m.EntId, ConfigJson.InternalTime)
  179. }
  180. }
  181. }
  182. }
  183. return UserPowerMap
  184. }
  185. //clear One
  186. func ClearUserPowerFunc(userId, appId string) {
  187. userPowerRedisKey := fmt.Sprintf(UserPowerRedisKey, appId, time.Now().Day(), userId)
  188. redis.Del(RedisCode, userPowerRedisKey)
  189. for _, v := range []string{"PC", "APP", "WX"} {
  190. RedisMenuKey := fmt.Sprintf(RedisMenuKey, appId, v, userId)
  191. redis.Del(RedisCode, RedisMenuKey)
  192. }
  193. }
  194. //用户角色权限初始化
  195. func UserRolePowerInit(strs []string) {
  196. if len(strs) > 0 {
  197. jyUserRoleData := BaseMysql.SelectBySql(`SELECT id,name FROM jyfunction WHERE status = 1`)
  198. if jyUserRoleData != nil && len(*jyUserRoleData) > 0 {
  199. for _, jv := range *jyUserRoleData {
  200. for _, v := range strs {
  201. if strings.Contains(MC.ObjToString(jv["name"]), v) {
  202. UserRolePowers[v] = append(UserRolePowers[v], strconv.Itoa(MC.IntAll(jv["id"])))
  203. }
  204. }
  205. }
  206. }
  207. }
  208. }
  209. /*
  210. 1、不符合可以留资申请开通权限的用户
  211. 1、免费用户
  212. 2、超级订阅用户、大会员用户到期时间是否超过3个月
  213. (1、2:弹窗-医械通上线啦)
  214. 2、符合可以留资申请开通的用户
  215. 1、未留资
  216. (1:弹窗-完善基本信息)
  217. 2、已留资未开通
  218. 3、已留资且开通
  219. (2、3:弹窗-恭喜留资成功)
  220. */
  221. /*
  222. 1、判断是否满足超级订阅用户或大会员用户 且到期时间超过90天(配置);
  223. 1.1、否:权限=0;提示上线啦
  224. 1.2、是:是否留资
  225. 1.2.1、否:权限=0;提示留资
  226. 1.2.2、是:是否开通权限
  227. 1.2.2.1、否:权限=0;提示恭喜留资成功,客服联系
  228. 1.2.2.2、是:权限=1
  229. */
  230. /*存在超级订阅 或 大会员到期 而医械通未到期的情况*/
  231. // CheckCapitalResources 是否需要留资 且权限验证--弹窗处理
  232. //b 一级权限(超级订阅、大会员等)
  233. //p 二级权限(请求资源中台:医械通等)
  234. func CheckCapitalResources(menu *JYMenu, wd *WorkDesktopMenu, b, p bool) (title, content, confirmUrl, confirmText, appType, openType string, isShowCancel, usable bool) {
  235. OverallLock.Lock()
  236. userInfo := UserInfoMap[wd.NewUserId]
  237. if userInfo == nil {
  238. userInfo = &UserInfo{}
  239. userInfo.Lock = &sync.Mutex{}
  240. userInfo.Capitals = map[string]int{}
  241. userInfo.Permissions = map[string]int{}
  242. UserInfoMap[wd.NewUserId] = userInfo
  243. }
  244. OverallLock.Unlock()
  245. userInfo.Lock.Lock()
  246. defer userInfo.Lock.Unlock()
  247. var (
  248. capitalBool = true //是否留资
  249. permissionBool = true //是否有功能权限
  250. customPopup = true //自定义弹窗
  251. defaultPopup = false //默认弹窗
  252. )
  253. //无权限(医械通-:1:免费用户;2:超级订阅、大会员到期时间不在规定范围内)
  254. if b {
  255. //大会员超级订阅用户 才有权限去验证是否有医疗权限
  256. //用户是否需要留资
  257. if menu.CapitalCode != "" {
  258. capitalBool = false
  259. for _, cv := range strings.Split(menu.CapitalCode, ",") {
  260. if userInfo.Capitals[cv] == 0 {
  261. if c := BaseMysql.CountBySql(`SELECT COUNT(id) FROM `+CapitalRetention+` WHERE source = ? AND user_id = ? AND appid = ?`, cv, wd.NewUserId, wd.AppId); c > 0 {
  262. userInfo.Capitals[cv] = 1
  263. } else {
  264. userInfo.Capitals[cv] = -1
  265. }
  266. }
  267. if userInfo.Capitals[cv] < 0 {
  268. customPopup = false
  269. //留资弹窗信息
  270. title = menu.CapitalInfo.Title
  271. content = menu.CapitalInfo.Content
  272. confirmUrl = menu.CapitalInfo.ConfirmUrl
  273. confirmText = menu.CapitalInfo.ConfirmText
  274. isShowCancel = menu.CapitalInfo.IsShowCancel
  275. appType = menu.CapitalInfo.AppType
  276. openType = menu.CapitalInfo.OpenType
  277. } else {
  278. capitalBool = true
  279. break
  280. }
  281. }
  282. }
  283. //资源中台--- 无权限弹窗信息为默认信息(先留资)
  284. if menu.PermissionCode != "" {
  285. permissionBool = false
  286. if (menu.CapitalCode != "" && capitalBool) || menu.CapitalCode == "" {
  287. if p {
  288. title = ""
  289. permissionBool = true
  290. customPopup = false
  291. }
  292. //for _, pv := range strings.Split(menu.PermissionCode, ",") {
  293. // if userInfo.Permissions[pv] == 0 {
  294. // userInfo.Permissions[pv] = -1
  295. // powerList := GetResources(wd.AppId, wd.NewUserId, wd.EntId, wd.EntUserId)
  296. // if len(powerList) > 0 {
  297. // for _, plv := range powerList {
  298. // userInfo.Permissions[plv] = 1
  299. // }
  300. // }
  301. // }
  302. // if userInfo.Permissions[pv] >= 0 {
  303. // title = ""
  304. // permissionBool = true
  305. // customPopup = false
  306. // break
  307. // }
  308. //}
  309. }
  310. }
  311. //有用户权限 查看功能权限
  312. //医械通---用户没有功能权限 也没有留资 查看
  313. if !permissionBool {
  314. switch menu.PowerIds {
  315. case "500":
  316. userRegisterTime, _ := strconv.ParseInt(redis.GetStr(RedisCode, fmt.Sprintf(UserRegisterTime, wd.UserId)), 10, 64)
  317. //超级订阅 大会员到期时间 是否 大于 90天
  318. if userRegisterTime-time.Now().Unix() < ConfigJson.MedicalFieldTimespan {
  319. //即使是超级订阅或大会员 也没有权限
  320. defaultPopup = true
  321. }
  322. }
  323. }
  324. //
  325. usable = capitalBool && permissionBool
  326. }
  327. //无权限--免费用户||不符合条件的付费用户
  328. if !b || defaultPopup {
  329. //配置弹窗信息
  330. if ConfigJson.DefaultPopup[menu.PowerIds].Title != "" {
  331. customPopup = false
  332. title = ConfigJson.DefaultPopup[menu.PowerIds].Title
  333. content = ConfigJson.DefaultPopup[menu.PowerIds].Content
  334. confirmUrl = ConfigJson.DefaultPopup[menu.PowerIds].ConfirmUrl
  335. confirmText = ConfigJson.DefaultPopup[menu.PowerIds].ConfirmText
  336. isShowCancel = ConfigJson.DefaultPopup[menu.PowerIds].IsShowCancel
  337. appType = ConfigJson.DefaultPopup[menu.PowerIds].AppType
  338. openType = ConfigJson.DefaultPopup[menu.PowerIds].OpenType
  339. }
  340. }
  341. //无权限(有权限未留资|留资了未开通权限) --》 没有配置弹窗信息 --》自定义弹窗
  342. if customPopup {
  343. title = menu.AdditionalInfo.Title
  344. content = menu.AdditionalInfo.Content
  345. confirmUrl = menu.AdditionalInfo.ConfirmUrl
  346. confirmText = menu.AdditionalInfo.ConfirmText
  347. isShowCancel = menu.AdditionalInfo.IsShowCancel
  348. appType = menu.AdditionalInfo.AppType
  349. openType = menu.AdditionalInfo.OpenType
  350. }
  351. return
  352. }