workDesktop.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. package entity
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "sort"
  8. "strconv"
  9. "strings"
  10. MC "app.yhyue.com/moapp/jybase/common"
  11. "app.yhyue.com/moapp/jybase/encrypt"
  12. "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
  13. "github.com/zeromicro/go-zero/core/logx"
  14. )
  15. // WorkDesktopMenu 工作桌面菜单信息
  16. type WorkDesktopMenu struct {
  17. MenuTree []*JYMenu //菜单
  18. UserId string //用户id
  19. NewUserId int64 //base_userid
  20. EntId int64 //企业id
  21. EntUserId int64 //企业用户id
  22. AppId string //appid 剑鱼:10000
  23. IntranetBool bool //是否开启内网访问模式
  24. Platform string //平台来源
  25. WorkStatus int64 //菜单分组
  26. AccountId int64 //账户id
  27. EntAccountId int64 //企业账户id
  28. PositionType int64 //职位类型 0:个人 1:企业
  29. PositionId int64 //职位id
  30. MgoUserId string //原mongo userId -- p278
  31. EntNicheDis int64 //企业角色 默认0:销售 1:企业资讯分配 2:部门资讯分配 3:企业资讯分配+销售 4:部门资讯分配+销售
  32. EntUserRole string //1:情报处理岗 2:情报分配岗 3:信息浏览岗 4:销售管理岗,多个逗号拼接
  33. }
  34. // JYMenu 工作桌面菜单内容
  35. type JYMenu struct {
  36. Id int
  37. Name string //菜单名称
  38. Match string //滤镜过滤正则
  39. OrderId int //菜单排序id
  40. ParentId int //父级id
  41. PowerIds string //权限id
  42. CheckCode int //是否必须验证权限才显示菜单
  43. Url string //菜单跳转链接
  44. Icon string //菜单图标
  45. AdditionalInfo map[string]Additional //附加弹窗信息
  46. AppType string //菜单模式
  47. OpenType string //打开方式
  48. Status int //是否是可用服务
  49. PermissionCode string //功能代码
  50. CapitalCode string //留资代码
  51. CapitalInfo Additional //留资弹窗
  52. Children []*JYMenu //菜单s
  53. Authority int //权限逻辑备注 默认0:功能权限、资源权限、留资权限必须全部满足;1:功能权限或资源权限或留资权限满足其一就行;
  54. Level int //1:一级菜单;2:二级菜单;3:三级菜单;4:四级菜单
  55. Exclude string //不需要显示菜单权限集合
  56. }
  57. type Additional struct {
  58. Title string `json:"title"` //弹窗标题
  59. Content string `json:"content"` //弹窗提示信息
  60. ConfirmUrl string `json:"confirmUrl,optional"` //确认按钮跳转地址
  61. ConfirmText string `json:"confirmText,optional"` //确认按钮
  62. IsShowCancel bool `json:"isShowCancel,optional"` //是否显示取消按钮
  63. AppType string `json:"appType,optional,omitempty"` //跳转方式
  64. OpenType string `json:"openType,optional,omitempty"`
  65. }
  66. // GetMenuTreeData 获取有效菜单数据
  67. func (m *WorkDesktopMenu) GetMenuTreeData() error {
  68. //P278 身份切换
  69. positionType := ``
  70. switch m.PositionType { //职位类型 0:个人 1:企业
  71. case 0:
  72. positionType = `AND available <= 2`
  73. case 1:
  74. positionType = `AND available >= 2`
  75. //P364 企业角色
  76. if m.EntUserRole != "" {
  77. for _, entUserRole := range strings.Split(m.EntUserRole, ",") {
  78. positionType += fmt.Sprintf(` AND (FIND_IN_SET('0',entrole) OR FIND_IN_SET('%d',entrole))`, MC.Int64All(entUserRole)+1)
  79. }
  80. } else {
  81. positionType += fmt.Sprintf(` AND (FIND_IN_SET('0',entrole) OR FIND_IN_SET('%d',entrole))`, m.EntNicheDis)
  82. }
  83. }
  84. //tidb数据
  85. query := fmt.Sprintf(`SELECT * FROM `+ConfigJson.WorkTableOut+` WHERE appid=? AND status=%d %s ORDER BY id ASC`, m.WorkStatus, positionType)
  86. //是否开启内网访问数据权限---对应 api 配置文件
  87. if m.IntranetBool {
  88. query = fmt.Sprintf(`SELECT * FROM `+ConfigJson.WorkTableInside+` WHERE appid=? AND status>=0 %s ORDER BY id ASC`, positionType)
  89. }
  90. logx.Info("query:", query)
  91. menuData := BaseMysql.SelectBySql(query, m.AppId)
  92. if menuData == nil || len(*menuData) == 0 {
  93. return errors.New("查询数据异常")
  94. }
  95. for _, v := range *menuData {
  96. menu := &JYMenu{
  97. Id: MC.IntAll(v["id"]),
  98. Name: MC.ObjToString(v["name"]),
  99. Match: MC.ObjToString(v["match"]),
  100. OrderId: MC.IntAll(v["orderid"]),
  101. ParentId: MC.IntAll(v["parentid"]),
  102. PowerIds: MC.ObjToString(v["powerids"]),
  103. CheckCode: MC.IntAll(v["checkcode"]),
  104. Icon: MC.ObjToString(v["icon"]),
  105. AppType: MC.ObjToString(v["apptype"]),
  106. OpenType: MC.ObjToString(v["opentype"]),
  107. Status: MC.IntAll(v["status"]),
  108. PermissionCode: MC.ObjToString(v["permissioncode"]),
  109. CapitalCode: MC.ObjToString(v["capitalcode"]),
  110. Authority: MC.IntAll(v["authority"]),
  111. Exclude: MC.ObjToString(v["exclude"]),
  112. }
  113. var OpenType = map[string]string{}
  114. if err := json.Unmarshal([]byte(MC.ObjToString(v["opentype"])), &OpenType); err == nil {
  115. menu.OpenType = OpenType[m.Platform]
  116. }
  117. switch m.Platform {
  118. case "WX":
  119. menu.Url = MC.ObjToString(v["wxurl"])
  120. menu.PowerIds = MC.ObjToString(v["wxpids"])
  121. case "APP":
  122. menu.Url = MC.ObjToString(v["appurl"])
  123. menu.PowerIds = MC.ObjToString(v["apppids"])
  124. default:
  125. menu.Url = MC.ObjToString(v["pcurl"])
  126. }
  127. //菜单(移动端)是否需要显示:PC端菜单不需要在移动端显示;或移动端菜单不需要在PC端显示。
  128. if menu.Url == "-1" {
  129. continue
  130. }
  131. if additionalInfo := MC.ObjToString(v["additionalinfo"]); additionalInfo != "" {
  132. additional := map[string]Additional{}
  133. if json.Unmarshal([]byte(additionalInfo), &additional) == nil {
  134. menu.AdditionalInfo = map[string]Additional{
  135. m.Platform: additional[m.Platform],
  136. }
  137. }
  138. }
  139. if capitalInfo := MC.ObjToString(v["capitalinfo"]); capitalInfo != "" {
  140. additional := Additional{}
  141. if json.Unmarshal([]byte(capitalInfo), &additional) == nil {
  142. menu.CapitalInfo = additional
  143. }
  144. }
  145. if menu.Id > 0 {
  146. m.MenuTree = append(m.MenuTree, menu)
  147. }
  148. }
  149. return nil
  150. }
  151. // WorkMenuTree 菜单-格式化-tree
  152. func (m *WorkDesktopMenu) WorkMenuTree(parentId int) (jyMenu []*JYMenu) {
  153. jyMenu = make([]*JYMenu, 0)
  154. for _, mv := range m.MenuTree {
  155. if mv.ParentId == parentId {
  156. mv.Children = m.WorkMenuTree(mv.Id)
  157. sort.SliceStable(mv.Children, func(i, j int) bool {
  158. return mv.Children[i].OrderId < mv.Children[j].OrderId
  159. })
  160. jyMenu = append(jyMenu, mv)
  161. }
  162. }
  163. sort.SliceStable(jyMenu, func(i, j int) bool {
  164. return jyMenu[i].OrderId < jyMenu[j].OrderId
  165. })
  166. return
  167. }
  168. // WorkMenuFormat 菜单 格式化
  169. func (m *WorkDesktopMenu) WorkMenuFormat() ([]*pb.MenuList, error) {
  170. //logx.Info("树的长度:", len(m.MenuTree))
  171. menuList := make([]*pb.MenuList, 0)
  172. for _, mv := range m.MenuTree {
  173. //if mv.Id < 466 {
  174. // continue
  175. //}
  176. //0:默认展示;1:需验证权限,有权限展示;2:需验证权限,无权限也可展示(可用服务无权限不展示)
  177. pBool := m.VerifyPermissions(mv.PowerIds, mv.Exclude)
  178. //checkCode==1 验证权限结果 无权限不显示
  179. if !pBool.HasBool && mv.CheckCode == 1 {
  180. continue
  181. }
  182. //有权限 验证是否需要展示--->excludeBool
  183. if pBool.ExcludeBool {
  184. continue
  185. }
  186. //GetResources(m.AppId, m.NewUserId, m.EntId, m.EntUserId)
  187. oneLevel := &pb.MenuList{
  188. Name: mv.Name,
  189. Icon: mv.Icon,
  190. Url: mv.Url,
  191. Id: encrypt.SE.EncodeString(strconv.Itoa(mv.Id)), //功能id加密
  192. Usable: pBool.HasBool, //MC.If(mv.PowerIds != "", usable && mv.CheckCode == 1, true).(bool),
  193. AppType: mv.AppType,
  194. OpenType: mv.OpenType,
  195. Child: []*pb.SecondLevelMenu{},
  196. TipInfo: &pb.TipInfo{
  197. Title: mv.AdditionalInfo[m.Platform].Title,
  198. Content: mv.AdditionalInfo[m.Platform].Content,
  199. ConfirmUrl: mv.AdditionalInfo[m.Platform].ConfirmUrl,
  200. ConfirmText: mv.AdditionalInfo[m.Platform].ConfirmText,
  201. IsShowCancel: mv.AdditionalInfo[m.Platform].IsShowCancel,
  202. AppType: mv.AdditionalInfo[m.Platform].AppType,
  203. OpenType: mv.AdditionalInfo[m.Platform].OpenType,
  204. },
  205. Match: MC.If(mv.Match != "", strings.Split(mv.Match, ","), []string{}).([]string),
  206. }
  207. if len(mv.Children) > 0 {
  208. for _, sv := range mv.Children {
  209. //0:默认展示;1:需验证权限,有权限展示;2:需验证权限,无权限也可展示(可用服务无权限不展示)
  210. pBool := m.VerifyPermissions(sv.PowerIds, sv.Exclude)
  211. //checkCode==1 验证权限结果 无权限不显示
  212. if !pBool.HasBool && sv.CheckCode == 1 {
  213. continue
  214. }
  215. //有权限 验证是否需要展示--->excludeBool
  216. if pBool.ExcludeBool {
  217. continue
  218. }
  219. secondLevel := &pb.SecondLevelMenu{
  220. Name: sv.Name,
  221. Icon: sv.Icon,
  222. Url: sv.Url,
  223. Id: encrypt.SE.EncodeString(strconv.Itoa(sv.Id)), //功能id加密
  224. Usable: pBool.HasBool, //MC.If(sv.PowerIds != "", usable && sv.CheckCode == 1, true).(bool),
  225. Child: []*pb.ThreeLevelMenu{},
  226. AppType: sv.AppType,
  227. OpenType: sv.OpenType,
  228. TipInfo: &pb.TipInfo{
  229. Title: sv.AdditionalInfo[m.Platform].Title,
  230. Content: sv.AdditionalInfo[m.Platform].Content,
  231. ConfirmUrl: sv.AdditionalInfo[m.Platform].ConfirmUrl,
  232. ConfirmText: sv.AdditionalInfo[m.Platform].ConfirmText,
  233. IsShowCancel: sv.AdditionalInfo[m.Platform].IsShowCancel,
  234. AppType: sv.AdditionalInfo[m.Platform].AppType,
  235. OpenType: sv.AdditionalInfo[m.Platform].OpenType,
  236. },
  237. Match: MC.If(sv.Match != "", strings.Split(sv.Match, ","), []string{}).([]string),
  238. }
  239. if len(sv.Children) > 0 {
  240. for _, tv := range sv.Children {
  241. //附件下载包、采购单位画像记录、企业画像记录 如果是大会员 排除此三项菜单
  242. //灵活性降低
  243. if (tv.Name == "采购单位画像记录" && m.VerifyPermissions("5", "").HasBool) || (tv.Name == "企业画像记录" && m.VerifyPermissions("4,12,13,19,20,21,23", "").HasBool) {
  244. continue
  245. }
  246. //0:默认展示;1:需验证权限,有权限展示;2:需验证权限,无权限也可展示(可用服务无权限不展示)
  247. pBool := m.VerifyPermissions(tv.PowerIds, tv.Exclude)
  248. //checkCode==1 验证权限结果 无权限不显示
  249. if !pBool.HasBool && tv.CheckCode == 1 {
  250. continue
  251. }
  252. //有权限 验证是否需要展示--->excludeBool
  253. if pBool.ExcludeBool {
  254. continue
  255. }
  256. var (
  257. //数据库默认提示弹窗信息
  258. title, content, confirmUrl, confirmText, isShowCancel, appType, openType, feasibility = tv.AdditionalInfo[m.Platform].Title, tv.AdditionalInfo[m.Platform].Content, tv.AdditionalInfo[m.Platform].ConfirmUrl, tv.AdditionalInfo[m.Platform].ConfirmText, tv.AdditionalInfo[m.Platform].IsShowCancel, tv.AdditionalInfo[m.Platform].AppType, tv.AdditionalInfo[m.Platform].OpenType, pBool.HasBool
  259. )
  260. //三级菜单------
  261. if len(tv.Children) == 0 && (tv.CapitalCode != "" || tv.PermissionCode != "") {
  262. //用户是否需要留资
  263. //资源中台获取用户权限--没有权限:title等置空
  264. //ResourceLib.PowerHandle()
  265. title, content, confirmUrl, confirmText, appType, openType, isShowCancel, feasibility = CheckCapitalResources(tv, m, pBool.HasBool, m.VerifyPermissions(tv.PermissionCode, "").HasBool)
  266. }
  267. //弹框地址处理
  268. threeLevel := &pb.ThreeLevelMenu{
  269. Name: tv.Name,
  270. Icon: tv.Icon,
  271. Url: tv.Url,
  272. Id: encrypt.SE.EncodeString(strconv.Itoa(tv.Id)), //功能id加密
  273. Usable: feasibility, //MC.If(tv.PowerIds != "", usable && tv.CheckCode == 1, true).(bool),
  274. AppType: tv.AppType,
  275. OpenType: tv.OpenType,
  276. TipInfo: &pb.TipInfo{
  277. Title: title,
  278. Content: content,
  279. ConfirmUrl: confirmUrl,
  280. ConfirmText: confirmText,
  281. IsShowCancel: isShowCancel,
  282. AppType: appType,
  283. OpenType: openType,
  284. },
  285. Match: MC.If(tv.Match != "", strings.Split(tv.Match, ","), []string{}).([]string),
  286. }
  287. if len(tv.Children) > 0 {
  288. L:
  289. for _, fv := range tv.Children {
  290. if fv.Name == "" {
  291. continue
  292. }
  293. if fv.CapitalCode != "" || fv.PermissionCode != "" {
  294. //用户是否需要留资
  295. //资源中台获取用户权限--没有权限:title等置空
  296. //ResourceLib.PowerHandle()
  297. //判断资源中台权限
  298. title, content, confirmUrl, confirmText, appType, openType, isShowCancel, feasibility = CheckCapitalResources(fv, m, pBool.HasBool, m.VerifyPermissions(fv.PermissionCode, "").HasBool)
  299. }
  300. threeLevel.Url = MC.If(fv.Url != "", fv.Url, tv.Url).(string)
  301. threeLevel.Icon = MC.If(fv.Icon != "", fv.Icon, tv.Icon).(string)
  302. threeLevel.AppType = fv.AppType
  303. threeLevel.OpenType = fv.OpenType
  304. threeLevel.Usable = feasibility
  305. if title != "" {
  306. threeLevel.TipInfo = &pb.TipInfo{
  307. Title: title,
  308. Content: content,
  309. ConfirmUrl: confirmUrl,
  310. ConfirmText: confirmText,
  311. IsShowCancel: isShowCancel,
  312. AppType: appType,
  313. OpenType: openType,
  314. }
  315. }
  316. threeLevel.Match = MC.If(fv.Match != "", strings.Split(fv.Match, ","), []string{}).([]string)
  317. //四级菜单必须有顺序性,大会员》商机管理》超级订阅》免费用户
  318. name := MC.If(strings.Contains(fv.Name, "-"), strings.Split(fv.Name, "-")[0], "免费").(string)
  319. if len(UserRolePowers[name]) > 0 && m.VerifyPermissions(strings.Join(UserRolePowers[name], ","), "").HasBool && m.VerifyPermissions(fv.PowerIds, "").HasBool {
  320. break L
  321. }
  322. }
  323. }
  324. //无资源中台权限 菜单不显示
  325. if !feasibility && tv.CheckCode == 1 {
  326. continue
  327. }
  328. if threeLevel != nil {
  329. secondLevel.Child = append(secondLevel.Child, threeLevel)
  330. }
  331. }
  332. }
  333. //二级菜单 有三级子菜单;才会显示
  334. if len(secondLevel.Child) == 0 && sv.CheckCode == 1 {
  335. continue
  336. }
  337. oneLevel.Child = append(oneLevel.Child, secondLevel)
  338. }
  339. }
  340. //一级菜单 有二级子菜单;才会显示
  341. if len(oneLevel.Child) == 0 && mv.CheckCode == 1 {
  342. continue
  343. }
  344. menuList = append(menuList, oneLevel)
  345. }
  346. //清用户内存信息
  347. func(baseUserid int64, appId, userId string) {
  348. OverallLock.Lock()
  349. defer OverallLock.Unlock()
  350. userInfo := UserInfoMap[baseUserid]
  351. if userInfo != nil {
  352. userInfo.Lock.Lock()
  353. defer userInfo.Lock.Unlock()
  354. userInfo.Permissions = map[string]int{}
  355. userInfo.Capitals = map[string]int{}
  356. }
  357. }(m.NewUserId, m.AppId, m.UserId)
  358. //bytes, _ := json.MarshalIndent(menuList, "", " ")
  359. //fmt.Printf("%s\n", bytes)
  360. return menuList, nil
  361. }
  362. type PowersBool struct {
  363. HasBool bool
  364. ExcludeBool bool
  365. }
  366. // VerifyPermissions 是否有权限可用此服务
  367. func (m *WorkDesktopMenu) VerifyPermissions(powerIds string, excludeCodes string) (pb *PowersBool) {
  368. pb = &PowersBool{}
  369. if powerIds == "" {
  370. pb.HasBool = true
  371. }
  372. if powerIds != "" || excludeCodes != "" {
  373. userPower := m.AutoUserPowerInfo() //m.TimeOut, m.BigMemberOff,
  374. if len(strings.Split(powerIds, ",")) > 0 {
  375. for _, pv := range strings.Split(powerIds, ",") {
  376. if userPower[pv] > 0 {
  377. pb.HasBool = true
  378. break
  379. }
  380. }
  381. }
  382. if len(strings.Split(excludeCodes, ",")) > 0 {
  383. for _, pv := range strings.Split(excludeCodes, ",") {
  384. if userPower[pv] > 0 {
  385. pb.ExcludeBool = true
  386. break
  387. }
  388. }
  389. }
  390. }
  391. return
  392. }
  393. // WorkCommonly 常用功能
  394. var (
  395. WorkCommonly = "work_commonly"
  396. //WorkMenu = "work_menu"
  397. )
  398. // CommonlyUpdate 更新常用功能
  399. func CommonlyUpdate(in *pb.WorkDesktopComprehensiveReq) (B bool, M string) {
  400. //事务 1:查; 2: 存;3: 删;
  401. var (
  402. ids []string
  403. mk int
  404. )
  405. for _, mid := range strings.Split(in.MenuIds, ",") {
  406. if mid == "" {
  407. continue
  408. }
  409. //id 解密
  410. ids = append(ids, encrypt.SE.DecodeString(mid))
  411. mk++
  412. //常用功能数量限制
  413. if ConfigJson.CommonlySize > 0 && mk >= int(ConfigJson.CommonlySize) {
  414. break
  415. }
  416. }
  417. //更新此用户设置的常用功能
  418. if B = BaseMysql.ExecTx("常用功能批量更新", func(tx *sql.Tx) bool {
  419. //查询此用户常用功能是否已存在记录
  420. var (
  421. id = 0
  422. existingData *[]map[string]interface{}
  423. )
  424. //P278 身份切换 常用功能和职业id 绑定
  425. existingData = BaseMysql.SelectBySqlByTx(tx, `SELECT id FROM `+WorkCommonly+` WHERE base_userid = ? AND appid = ? AND field = ? AND userid = ? ORDER BY id DESC `, in.NewUserId, in.AppId, in.ActionMode, in.UserId)
  426. if existingData != nil && len(*existingData) > 0 {
  427. id = MC.IntAll((*existingData)[0]["id"])
  428. //} else {
  429. // //P278 之前版本查询逻辑
  430. // existingData = BaseMysql.SelectBySqlByTx(tx, `SELECT id FROM `+WorkCommonly+` WHERE base_userid = ? AND appid = ? AND field = ? ORDER BY id DESC `, in.NewUserId, in.AppId, in.ActionMode)
  431. // if existingData != nil && len(*existingData) > 0 {
  432. // id = MC.IntAll((*existingData)[0]["id"])
  433. // }
  434. }
  435. switch {
  436. case id > 0: //更新
  437. if BaseMysql.UpdateOrDeleteBySqlByTx(tx, `UPDATE `+WorkCommonly+` SET value = ?,userid = ? WHERE id = ?`, strings.Join(ids, ","), in.UserId, id) < 0 {
  438. logx.Info("常用功能-更新数据失败")
  439. return false
  440. }
  441. default: //插入
  442. if BaseMysql.InsertBySqlByTx(tx, `INSERT INTO `+WorkCommonly+` (appid,base_userid,platform,field,value,userid) VALUES (?,?,?,?,?,?)`, in.AppId, in.NewUserId, in.Platform, in.ActionMode, strings.Join(ids, ","), in.UserId) < 0 {
  443. logx.Info("常用功能-插入数据失败")
  444. return false
  445. }
  446. }
  447. return true
  448. }); !B {
  449. M = "常用功能更新数据失败"
  450. }
  451. return
  452. }
  453. // CommonlyFormat 常用功能 格式化
  454. func (m *WorkDesktopMenu) CommonlyFormat(childMenus map[int][]*JYMenu) ([]*pb.ThreeLevelMenu, []string, bool) {
  455. menuList := make([]*pb.ThreeLevelMenu, 0)
  456. subLevel := map[int]bool{}
  457. delBool := false //更新因超级订阅用户,又购买大会员得用户 导致附件下载包||采购单位画像记录||企业画像记录 不应该展示
  458. var saveIds []string
  459. for _, mv := range m.MenuTree {
  460. //三级菜单已处理,子级四级菜单不再处理
  461. //过滤子级 ++
  462. if subLevel[mv.ParentId] {
  463. continue
  464. }
  465. //三级下架菜单:mv.Status == 1
  466. if mv.Status == 1 {
  467. delBool = true
  468. continue
  469. }
  470. //附件下载包、采购单位画像记录、企业画像记录 如果是大会员 排除此三项菜单
  471. //灵活性降低
  472. if (mv.Name == "采购单位画像记录" && m.VerifyPermissions("5", "").HasBool) || (mv.Name == "企业画像记录" && m.VerifyPermissions("4,12,13,19,20,21,23", "").HasBool) {
  473. delBool = true
  474. continue
  475. }
  476. //0:默认展示;1:需验证权限,有权限展示;2:需验证权限,无权限也可展示(可用服务无权限不展示)
  477. pBool := m.VerifyPermissions(mv.PowerIds, mv.Exclude)
  478. if pBool.ExcludeBool {
  479. delBool = true
  480. continue
  481. }
  482. feasibility := pBool.HasBool
  483. //三级菜单------
  484. if len(childMenus[mv.Id]) == 0 && (mv.CapitalCode != "" || mv.PermissionCode != "") {
  485. _, _, _, _, _, _, _, feasibility = CheckCapitalResources(mv, m, pBool.HasBool, m.VerifyPermissions(mv.PermissionCode, "").HasBool)
  486. }
  487. saveIds = append(saveIds, encrypt.SE.EncodeString(strconv.Itoa(mv.Id)))
  488. subLevel[mv.Id] = true
  489. oneLevel := &pb.ThreeLevelMenu{
  490. Name: mv.Name,
  491. Icon: mv.Icon,
  492. Url: mv.Url,
  493. Id: encrypt.SE.EncodeString(strconv.Itoa(mv.Id)), //功能id加密
  494. Usable: feasibility, //MC.If(mv.PowerIds != "", usable && mv.CheckCode == 1, true).(bool),
  495. AppType: mv.AppType,
  496. OpenType: mv.OpenType,
  497. TipInfo: &pb.TipInfo{
  498. Title: mv.AdditionalInfo[m.Platform].Title,
  499. Content: mv.AdditionalInfo[m.Platform].Content,
  500. ConfirmUrl: mv.AdditionalInfo[m.Platform].ConfirmUrl,
  501. ConfirmText: mv.AdditionalInfo[m.Platform].ConfirmText,
  502. IsShowCancel: mv.AdditionalInfo[m.Platform].IsShowCancel,
  503. AppType: mv.AppType,
  504. OpenType: mv.OpenType,
  505. },
  506. Match: MC.If(mv.Match != "", strings.Split(mv.Match, ","), []string{}).([]string),
  507. }
  508. //处理子级
  509. if childMenus[mv.Id] != nil && len(childMenus[mv.Id]) > 0 {
  510. childMenu := childMenus[mv.Id]
  511. sort.Slice(childMenu, func(i, j int) bool {
  512. return childMenu[i].OrderId < childMenu[j].OrderId
  513. })
  514. L:
  515. for _, cv := range childMenu {
  516. //cv.Status < 0 四级菜单 生效不再处理;因为常用功能设置保存的都是三级菜单id,如果三级菜单功能下架,只处理三级菜单。
  517. if cv.Name == "" || cv.ParentId != mv.Id || cv.Status < 0 {
  518. continue
  519. }
  520. if cv.CapitalCode != "" || cv.PermissionCode != "" {
  521. _, _, _, _, _, _, _, feasibility = CheckCapitalResources(cv, m, pBool.HasBool, m.VerifyPermissions(cv.PermissionCode, "").HasBool)
  522. }
  523. oneLevel.Url = MC.If(cv.Url != "", cv.Url, mv.Url).(string)
  524. oneLevel.Icon = MC.If(cv.Icon != "", cv.Icon, mv.Icon).(string)
  525. oneLevel.AppType = cv.AppType
  526. oneLevel.OpenType = cv.OpenType
  527. oneLevel.Usable = feasibility
  528. if cv.AdditionalInfo[m.Platform].Title != "" {
  529. oneLevel.TipInfo = &pb.TipInfo{
  530. Title: cv.AdditionalInfo[m.Platform].Title,
  531. Content: cv.AdditionalInfo[m.Platform].Content,
  532. ConfirmUrl: cv.AdditionalInfo[m.Platform].ConfirmUrl,
  533. ConfirmText: cv.AdditionalInfo[m.Platform].ConfirmText,
  534. IsShowCancel: cv.AdditionalInfo[m.Platform].IsShowCancel,
  535. AppType: cv.AppType,
  536. OpenType: cv.OpenType,
  537. }
  538. }
  539. oneLevel.Match = MC.If(cv.Match != "", strings.Split(cv.Match, ","), []string{}).([]string)
  540. name := MC.If(strings.Contains(cv.Name, "-"), strings.Split(cv.Name, "-")[0], "免费").(string)
  541. if len(UserRolePowers[name]) > 0 && m.VerifyPermissions(strings.Join(UserRolePowers[name], ","), "").HasBool {
  542. break L
  543. }
  544. }
  545. }
  546. //跨平台,非本平台功能,给用户提示信息
  547. if oneLevel.Url == "-1" {
  548. oneLevel.TipInfo = &pb.TipInfo{
  549. Title: ConfigJson.DefaultPopup[m.Platform].Title,
  550. Content: ConfigJson.DefaultPopup[m.Platform].Content,
  551. ConfirmUrl: ConfigJson.DefaultPopup[m.Platform].ConfirmUrl,
  552. ConfirmText: ConfigJson.DefaultPopup[m.Platform].ConfirmText,
  553. IsShowCancel: ConfigJson.DefaultPopup[m.Platform].IsShowCancel,
  554. }
  555. if oneLevel.TipInfo.ConfirmUrl == "" {
  556. oneLevel.TipInfo.AppType = ""
  557. oneLevel.TipInfo.OpenType = ""
  558. }
  559. oneLevel.Url = ""
  560. oneLevel.Usable = false
  561. }
  562. //1、当前平台有权限,清空提示信息
  563. //2、提示信息内容为空,清空提示信息
  564. if oneLevel.Usable || oneLevel.TipInfo.Content == "" {
  565. oneLevel.TipInfo = &pb.TipInfo{}
  566. }
  567. menuList = append(menuList, oneLevel)
  568. }
  569. return menuList, saveIds, delBool
  570. }