yanderong
2026-07-17 08cb6046ab729d41570e9aa16da73bbced9542e5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
package com.stylefeng.guns.modular.system.controller.system;
 
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.base.tips.Tip;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.constant.dictmap.MenuDict;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.constant.state.MenuStatus;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.support.BeanKit;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.dao.TCompanyMapper;
import com.stylefeng.guns.modular.system.model.Menu;
import com.stylefeng.guns.modular.system.model.Relation;
import com.stylefeng.guns.modular.system.model.TCompany;
import com.stylefeng.guns.modular.system.service.IMenuService;
import com.stylefeng.guns.modular.system.service.IRelationService;
import com.stylefeng.guns.modular.system.warpper.MenuWarpper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
 
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
 
/**
 * 菜单控制器
 *
 * @author fengshuonan
 * @Date 2017年2月12日21:59:14
 */
@Controller
@RequestMapping("/menu")
public class MenuController extends BaseController {
 
    private static String PREFIX = "/system/menu/";
 
    // 快车相关菜单(isSpe=2时过滤)
    private static final List<String> SPE_MENUS = Arrays.asList(
        "快车订单", "快车改派管理", "快车车型设置"
    );
 
    // 出租车相关菜单(isTaxi=2时过滤)
    private static final List<String> TAXI_MENUS = Arrays.asList(
        "出租车订单", "出租车改派管理"
    );
 
    // 跨城相关菜单(isCross=2时过滤)
    private static final List<String> CROSS_MENUS = Arrays.asList(
        "跨城出行订单", "跨城改派管理", "跨城线路管理", "开通城市管理"
    );
 
    // 顺风车相关菜单(isHitchRide=2时过滤)
    private static final List<String> HITCH_RIDE_MENUS = Arrays.asList(
        "顺风车订单", "顺风车设置", "顺风车司机审核列表",
        "顺风车司机", "顺风车投诉", "顺风车评价"
    );
 
    @Autowired
    private IMenuService menuService;
    
    @Resource
    private TCompanyMapper companyMapper;
    
    @Resource
    private IRelationService rerelationService;
    
    
    
    /**
     * 跳转到菜单列表列表页面
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "menu.html";
    }
 
    /**
     * 跳转到菜单列表列表页面
     */
    @RequestMapping(value = "/menu_add")
    public String menuAdd() {
        return PREFIX + "menu_add.html";
    }
 
    /**
     * 跳转到菜单详情列表页面
     */
    @RequestMapping(value = "/menu_edit/{menuId}")
    public String menuEdit(@PathVariable Long menuId, Model model) {
        if (ToolUtil.isEmpty(menuId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        Menu menu = this.menuService.selectById(menuId);
 
        //获取父级菜单的id
        Menu temp = new Menu();
        temp.setCode(menu.getPcode());
        Menu pMenu = this.menuService.selectOne(new EntityWrapper<>(temp));
 
        //如果父级是顶级菜单
        if (pMenu == null) {
            menu.setPcode("0");
        } else {
            //设置父级菜单的code为父级菜单的id
            menu.setPcode(String.valueOf(pMenu.getId()));
        }
 
        Map<String, Object> menuMap = BeanKit.beanToMap(menu);
        menuMap.put("pcodeName", ConstantFactory.me().getMenuNameByCode(temp.getCode()));
        model.addAttribute("menu", menuMap);
        LogObjectHolder.me().set(menu);
        return PREFIX + "menu_edit.html";
    }
 
    /**
     * 修该菜单
     */
    @RequestMapping(value = "/edit")
    @BussinessLog(value = "修改菜单", key = "name", dict = MenuDict.class)
    @ResponseBody
    public Tip edit(@Valid Menu menu, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //设置父级菜单编号
        menuSetPcode(menu);
 
        this.menuService.updateById(menu);
 
 
        return SUCCESS_TIP;
    }
 
    /**
     * 获取菜单列表
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String menuName, @RequestParam(required = false) String level) {
        List<Map<String, Object>> menus = this.menuService.selectMenus(menuName, level);
        return super.warpObject(new MenuWarpper(menus));
    }
 
    /**
     * 新增菜单
     */
    @RequestMapping(value = "/add")
    @BussinessLog(value = "菜单新增", key = "name", dict = MenuDict.class)
    @ResponseBody
    public Tip add(@Valid Menu menu, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
 
        //判断是否存在该编号
        String existedMenuName = ConstantFactory.me().getMenuNameByCode(menu.getCode());
        if (ToolUtil.isNotEmpty(existedMenuName)) {
            throw new GunsException(BizExceptionEnum.EXISTED_THE_MENU);
        }
 
        //设置父级菜单编号
        menuSetPcode(menu);
 
        menu.setStatus(MenuStatus.ENABLE.getCode());
        this.menuService.insert(menu);
 
 
        return SUCCESS_TIP;
    }
 
    /**
     * 删除菜单
     */
    @RequestMapping(value = "/remove")
    @BussinessLog(value = "删除菜单", key = "menuId", dict = MenuDict.class)
    @ResponseBody
    public Tip remove(@RequestParam Long menuId) {
        if (ToolUtil.isEmpty(menuId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
 
 
        //缓存菜单的名称
        LogObjectHolder.me().set(ConstantFactory.me().getMenuName(menuId));
 
        this.menuService.delMenuContainSubMenus(menuId);
 
        return SUCCESS_TIP;
    }
 
    /**
     * 查看菜单
     */
    @RequestMapping(value = "/view/{menuId}")
    @ResponseBody
    public Tip view(@PathVariable Long menuId) {
        if (ToolUtil.isEmpty(menuId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        this.menuService.selectById(menuId);
        return SUCCESS_TIP;
    }
 
    /**
     * 获取菜单列表(首页用)
     */
    @RequestMapping(value = "/menuTreeList")
    @ResponseBody
    public List<ZTreeNode> menuTreeList() {
        ShiroUser user1 = ShiroKit.getUser();
        TCompany tCompany = companyMapper.selectById(user1.getObjectId());
        List<Long> ids = new ArrayList<>();
        if(1 != tCompany.getType()){
            List<Relation> relations = rerelationService.selectList(new EntityWrapper<Relation>().eq("roleid", tCompany.getType()));
            if(relations.size() == 0){
                ids.add(0L);
            }else{
                ids = relations.stream().map(Relation::getMenuid).collect(Collectors.toList());
            }
        }
        List<ZTreeNode> roleTreeList = this.menuService.menuTreeList(ids);
        // 分公司(type=2)和供应商(type=3)需要根据经营范围过滤菜单
        if (tCompany.getType() == 2 || tCompany.getType() == 3) {
            roleTreeList = filterMenusByBusinessScope(roleTreeList, tCompany);
        }
        return roleTreeList;
    }
 
    /**
     * 获取菜单列表(选择父级菜单用)
     */
    @RequestMapping(value = "/selectMenuTreeList")
    @ResponseBody
    public List<ZTreeNode> selectMenuTreeList() {
        ShiroUser user1 = ShiroKit.getUser();
        TCompany tCompany = companyMapper.selectById(user1.getObjectId());
        List<Long> ids = new ArrayList<>();
        if(1 != tCompany.getType()){
            List<Relation> relations = rerelationService.selectList(new EntityWrapper<Relation>().eq("roleid", tCompany.getType()));
            if(relations.size() == 0){
                ids.add(0L);
            }else{
                ids = relations.stream().map(Relation::getMenuid).collect(Collectors.toList());
            }
        }
        List<ZTreeNode> roleTreeList = this.menuService.menuTreeList(ids);
        // 分公司(type=2)和供应商(type=3)需要根据经营范围过滤菜单
        if (tCompany.getType() == 2 || tCompany.getType() == 3) {
            roleTreeList = filterMenusByBusinessScope(roleTreeList, tCompany);
        }
        roleTreeList.add(ZTreeNode.createParent());
        return roleTreeList;
    }
 
    /**
     * 获取角色列表
     */
    @RequestMapping(value = "/menuTreeListByRoleId/{roleId}")
    @ResponseBody
    public List<ZTreeNode> menuTreeListByRoleId(@PathVariable Integer roleId) {
        List<Long> menuIds = this.menuService.getMenuIdsByRoleId(roleId);
        ShiroUser user1 = ShiroKit.getUser();
        TCompany tCompany = companyMapper.selectById(user1.getObjectId());
        List<Long> ids = new ArrayList<>();
        if(1 != tCompany.getType()){
            List<Relation> relations = rerelationService.selectList(new EntityWrapper<Relation>().eq("roleid", tCompany.getType()));
            if(relations.size() == 0){
                ids.add(0L);
            }else{
                ids = relations.stream().map(Relation::getMenuid).collect(Collectors.toList());
            }
        }
        if (ToolUtil.isEmpty(menuIds)) {
            List<ZTreeNode> roleTreeList = this.menuService.menuTreeList(ids);
            // 分公司(type=2)和供应商(type=3)需要根据经营范围过滤菜单
            if (tCompany.getType() == 2 || tCompany.getType() == 3) {
                roleTreeList = filterMenusByBusinessScope(roleTreeList, tCompany);
            }
            return roleTreeList;
        } else {
            List<ZTreeNode> roleTreeListByUserId = this.menuService.menuTreeListByMenuIds(menuIds, ids);
            // 分公司(type=2)和供应商(type=3)需要根据经营范围过滤菜单
            if (tCompany.getType() == 2 || tCompany.getType() == 3) {
                roleTreeListByUserId = filterMenusByBusinessScope(roleTreeListByUserId, tCompany);
            }
            return roleTreeListByUserId;
        }
    }
 
    /**
     * 根据请求的父级菜单编号设置pcode和层级
     */
    private void menuSetPcode(@Valid Menu menu) {
        if (ToolUtil.isEmpty(menu.getPcode()) || menu.getPcode().equals("0")) {
            menu.setPcode("0");
            menu.setPcodes("[0],");
            menu.setLevels(1);
        } else {
            long code = Long.parseLong(menu.getPcode());
            Menu pMenu = menuService.selectById(code);
            Integer pLevels = pMenu.getLevels();
            menu.setPcode(pMenu.getCode());
 
            //如果编号和父编号一致会导致无限递归
            if (menu.getCode().equals(menu.getPcode())) {
                throw new GunsException(BizExceptionEnum.MENU_PCODE_COINCIDENCE);
            }
 
            menu.setLevels(pLevels + 1);
            menu.setPcodes(pMenu.getPcodes() + "[" + pMenu.getCode() + "],");
        }
    }
 
    /**
     * 根据企业经营范围过滤菜单
     * @param menuList 原始菜单列表
     * @param company 企业信息
     * @return 过滤后的菜单列表
     */
    private List<ZTreeNode> filterMenusByBusinessScope(List<ZTreeNode> menuList, TCompany company) {
        List<String> excludeMenuNames = new ArrayList<>();
 
        // isSpe=2 不经营快车
        if (company.getIsSpe() != null && company.getIsSpe() == 2) {
            excludeMenuNames.addAll(SPE_MENUS);
        }
        // isTaxi=2 不经营出租车
        if (company.getIsTaxi() != null && company.getIsTaxi() == 2) {
            excludeMenuNames.addAll(TAXI_MENUS);
        }
        // isCross=2 不经营跨城
        if (company.getIsCross() != null && company.getIsCross() == 2) {
            excludeMenuNames.addAll(CROSS_MENUS);
        }
        // isHitchRide=2 不经营顺风车
        if (company.getIsHitchRide() != null && company.getIsHitchRide() == 2) {
            excludeMenuNames.addAll(HITCH_RIDE_MENUS);
        }
 
        if (excludeMenuNames.isEmpty()) {
            return menuList;
        }
 
        return menuList.stream()
            .filter(node -> !excludeMenuNames.contains(node.getName()))
            .collect(Collectors.toList());
    }
 
}