workDesktop.go 26 KB

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