上一个章节,猿人君教会了你如何去设置广告牌,今天我们一起来学习,如何绑定前后台类目。
功能概览
在三级前台类目列表中,点击管理按钮,设置当前前台三级类目和后台类目的关系。通过勾选左侧后台类目的形式,将选中的三级类目内容放置到右侧的列表中,同时列表提供删除功能,点击保存按钮,完成前台类目和后台类目的关系绑定。
数据库设计
既然是绑定关系,那自然是需要关系表来持久这样的数据。至于为什么要建立这种关系,你可以查看之前的设计文章。
数据展示后端功能实现
在思考后端功能怎样实现时,我们可以先看看功能描述。点击管理后,来完成前后端类目关系设置的操作。你看,又是“设置”类的操作。对于这种操作,自然需要返回需要操作的数据,以及已经建立的关系数据了。
也就是说,我们的后端,需要至少两个数据接口——一个用于返回右侧的类目数据,一个返回已有的前后台类目关系。我们先在MallFnCategoryController中增加代码。
/** * 返回用于选择的后台类目 * @param queryMallFnBgCategoryRel * @return */ @RequestMapping("/findForSelect") public Result<List<MallCategoryVo>> findForSelect(@RequestBody QueryMallFnBgCategoryRel queryMallFnBgCategoryRel){ QueryMallCategory queryMallCategory = new QueryMallCategory(); Result<List<MallCategoryVo>> dataResult= mallCategoryService.getMallCategoryVoList(queryMallCategory,null); return dataResult; } /** * 返回前台类目后台类目关系列表 * @param queryMallFnBgCategoryRel * @return */ @RequestMapping("/findForSelectedTable") public Result<List<MallFnBgCategoryRel>> findForSelectedTable(@RequestBody QueryMallFnBgCategoryRel queryMallFnBgCategoryRel){ Result<List<MallFnBgCategoryRel>> result= mallFnBgCategoryRelService.getMallFnBgCategoryRelsByQueryWithCateName(queryMallFnBgCategoryRel); return result; }
考虑到部分朋友对如何获取树结构数据不太熟悉,这里把service层的代码给到你。
/** * 获取需要展示的类目 * @param queryMallCategory * @param exculdeIdlist * @return */ public Result<List<MallCategoryVo>> getMallCategoryVoList(QueryMallCategory queryMallCategory,List<Long> exculdeIdlist) { Result<List<MallCategoryVo>> result = new Result<List<MallCategoryVo>>(); try { List<MallCategory> dataList= mallCategoryDao.selectMallCategoryByQuery(queryMallCategory); //删除需要屏蔽的对象 if(!CollectionUtils.isEmpty(exculdeIdlist)){ dataList.removeIf(a -> { return exculdeIdlist.stream().anyMatch(b -> { if (b!= null && b.equals(a.getCategoryId())) { return true; } else { return false; } }); }); } List<MallCategoryVo> voList= new ArrayList<MallCategoryVo>(); result.addDefaultModel(voList); for(MallCategory category:dataList){ if(category.getLevel()==1){ MallCategoryVo vo = new MallCategoryVo(); vo.setCategoryId(category.getCategoryId()); vo.setCategoryName(category.getCategoryName()); vo.setLevel(category.getLevel()); voList.add(vo); setChildren(dataList,vo); } } } catch(Exception e) { result.setSuccess(false); } return result; } /** * 递归设置子节点 * @param dataList * @param mallCategoryVo */ private void setChildren(List<MallCategory> dataList,MallCategoryVo mallCategoryVo){ for(MallCategory category:dataList){ if(mallCategoryVo.getCategoryId().equals(category.getParentId())){ MallCategoryVo child = new MallCategoryVo(); child.setCategoryId(category.getCategoryId()); child.setCategoryName(category.getCategoryName()); child.setLevel(category.getLevel()); mallCategoryVo.getChildren().add(child); setChildren(dataList,child); } } }
数据展示前端功能实现
后端的数据有了,那么接下来就是前端数据展示的实现了。像这样的前端界面,我们其实在类目属性绑定的功能中也遇到过。这里帮你复习下。
同样的,我们使用el-tree组件来展示后台类目数据。
使用el-table组件,实现动态表单的功能。
前端数据初始化
页面已经有了,我们一起来看看数据初始化的问题。
我们需要调用后端接口,初始化类目和动态表单的数据,以完成数据内容的填充。
后台类目数据选择
由于当前的前台类目,可能出现已经绑定的后台类目,那么在实现时,需要过滤已经设置过的数据。
updateKeyChildren(data, key1, key2) { const checkedNodes = this.$refs.tree.getCheckedNodes() if (checkedNodes != null && checkedNodes.length > 0) { for (let i = 0; i < checkedNodes.length; i++) { this.atteibute = { id: undefined, fnCategoryId: this.fnCategoryId, categoryId: checkedNodes[i].categoryId, categoryName: checkedNodes[i].categoryName, fnCategoryName: this.fnCategoryName, status: 1, checked: true } const checkedNode = checkedNodes[i] if (checkedNode.categoryId !== null && checkedNode.level === 3) { let flag = true for (let j = 0; j < this.tableList.length; j++) { if (this.tableList[j].categoryId === checkedNode.categoryId) { console.log(checkedNode) flag = false } } if (flag) { if (checkedNode.checked) { this.atteibute.mainCategory = 1 } else { this.atteibute.mainCategory = 0 } this.tableList.push(this.atteibute) } } } } }
那有些内容,并不是想要的,需要删除怎么办啊?提供一个删除功能就好了。
handleDelete(index, row) { this.tableList.splice(index, 1) }
前端保存按钮功能实现
API的封装?你已经封装过很多次api了,这次你自己好好实现一把吧。
后端保存数据
增加一个后端数据接口,用于保存前后台类目的绑定关系就可以了。
/** * 批量新增前后台类目关系 * @param mallFnBgCategoryRelList * @return */ @RequestMapping("/addMallFnBgCategoryRelBatch") public Result<List<MallFnBgCategoryRel>> addMallCategoryPropertyValueBatch(@RequestBody List<MallFnBgCategoryRel> mallFnBgCategoryRelList){ try{ return mallFnBgCategoryRelService.addMallFnBgCategoryRelBatch(mallFnBgCategoryRelList); }catch(Exception e){ e.printStackTrace(); return new Result(false); } } @Override public Result<List<MallFnBgCategoryRel>> addMallFnBgCategoryRelBatch(List<MallFnBgCategoryRel> mallFnBgCategoryRelList) { Result<List<MallFnBgCategoryRel>> result = new Result<List<MallFnBgCategoryRel>>(); try { QueryMallFnBgCategoryRel query = new QueryMallFnBgCategoryRel(); query.setFnCategoryId(mallFnBgCategoryRelList.get(0).getFnCategoryId()); List<MallFnBgCategoryRel> dbList = mallFnBgCategoryRelDao.selectMallFnBgCategoryRelByQuery(query); //有即新增无则删除 for(MallFnBgCategoryRel newRel:mallFnBgCategoryRelList){ if(null==newRel.getId()){ mallFnBgCategoryRelDao.insertMallFnBgCategoryRelModified(newRel); continue; } for(MallFnBgCategoryRel dbRel:dbList){ if(newRel.getId().equals(dbRel.getId())){ mallFnBgCategoryRelDao.updateMallFnBgCategoryRelByIdModified(dbRel); continue; } } } //删除列表中没有的记录 for(MallFnBgCategoryRel dbRel: dbList){ boolean flag=true; for(MallFnBgCategoryRel newRel:mallFnBgCategoryRelList){ if(newRel.getId().equals(dbRel.getId())){ flag=false; } if(flag){ dbRel.setStatus(-1); mallFnBgCategoryRelDao.updateMallFnBgCategoryRelByIdModified(dbRel); } } } result.addDefaultModel(mallFnBgCategoryRelList); }catch(Exception e) { result.setSuccess(false); } return result; }
本文分享自微信公众号 - 猿人工厂(gh_deca5a88e287),作者:山旮旯的胖子
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2020-09-18
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句