1.数据库表设计
- 生成树结构的主要列是
id
列和parent_id
列,后者指向他的父级
2.来到前端代码生成器页面
- 导入你刚刚写出该格式的数据库表
3.点击编辑,来到字段
祖籍列表是为了好找到直接父类,不属于代码生成器方法,需要后台编写
4.改变生成结构为树表结构
5.提交然后生成代码并复制到对应目录当中
6.修改serviceImpl当中插入
和修改
方法
/**
* 新增原料
*
* @param tIngredient 原料
* @return 结果
*/
@Override
public int insertTIngredient(TIngredient tIngredient) {
TIngredient info = tIngredientMapper.selectTIngredientById(tIngredient.getParentId());
// 如果父节点不为正常状态,则不允许新增子节点
if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
throw new ServiceException("原料类型停用,不允许新增");
}
tIngredient.setAncestors(info.getAncestors() + "," + tIngredient.getParentId());
tIngredient.setCreateTime(DateUtils.getNowDate());
return tIngredientMapper.insertTIngredient(tIngredient);
}
/**
* 修改原料
*
* @param tIngredient 原料
* @return 结果
*/
@Override
public int updateTIngredient(TIngredient tIngredient) {
TIngredient newParentDept = tIngredientMapper.selectTIngredientById(tIngredient.getParentId());
TIngredient oldDept = tIngredientMapper.selectTIngredientById(tIngredient.getId());
if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) {
String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getId();
String oldAncestors = oldDept.getAncestors();
tIngredient.setAncestors(newAncestors);
updateDeptChildren(tIngredient.getId(), newAncestors, oldAncestors);
}
tIngredient.setUpdateTime(DateUtils.getNowDate());
int result = tIngredientMapper.updateTIngredient(tIngredient);
if (UserConstants.DEPT_NORMAL.equals(tIngredient.getStatus()) && StringUtils.isNotEmpty(tIngredient.getAncestors())
&& !StringUtils.equals("0", tIngredient.getAncestors())) {
// 如果该部门是启用状态,则启用该部门的所有上级部门
updateParentDeptStatusNormal(tIngredient);
}
return result;
}
- 用到了两个额外对数操作方法,联动子父级菜单的修改
/**
* 修改该部门的父级部门状态
*
* @param tIngredient 当前部门
*/
private void updateParentDeptStatusNormal(TIngredient tIngredient) {
String ancestors = tIngredient.getAncestors();
Long[] deptIds = Convert.toLongArray(ancestors);
tIngredientMapper.enableTIngredientByIds(deptIds);
}
/**
* 修改子元素关系
*
* @param deptId 被修改的部门ID
* @param newAncestors 新的父ID集合
* @param oldAncestors 旧的父ID集合
*/
public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
List<TIngredient> children = tIngredientMapper.selectChildrenTIngredientById(deptId);
for (TIngredient child : children) {
child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
}
if (children.size() > 0) {
tIngredientMapper.updateTIngredientChildren(children);
}
}
生成完毕,额外处理自己表中数据也是在新增或者修改当中写
来到想要使用的前端页面(其他页面使用)
1.导入依赖
- 第一个依赖是生成树的请求
- 第二个组件是vue.js的树形选择组件
- 第三个是树形组件的
css
样式
import { listIngredient } from "@/api/bases/ingredient";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
2.注册树形组件
components: {
Treeselect
},
3.要使用的核心方法
/** 查询原料下拉树结构 */
getTreeselect () {
listIngredient().then(response => {
this.ingredientOptions = [];
const data = { id: 0, ingredientName: '顶级节点', children: [] };
data.children = this.handleTree(response.data, "id", "parentId");
this.ingredientOptions.push(data);
});
},
/** 转换原料数据结构 */
normalizer (node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.ingredientName,
children: node.children
};
},
4调用方法,我是通过新增按钮
来实现的
/** 新增原料操作 */
handleAddIngredientVO () {
this.reset();
this.getTreeselect();
this.openAddIngredientVO = true;
this.titleAddIngredientVO = "添加产品原料";
},
5.调用方法的下拉框表单
<!-- 新增或者修改原料 -->
<el-dialog
:title="titleAddIngredientVO"
:visible.sync="openAddIngredientVO"
width="500px"
append-to-body
>
<el-form
ref="formVO"
:model="formVO"
:rules="rules"
label-width="80px"
>
<el-form-item
label="产品编码"
prop="breedId"
>
<el-input
v-model="formVO.breedId"
placeholder="请输入产品编码"
/>
</el-form-item>
<el-form-item
label="父级"
prop="materialId"
>
<treeselect
v-model="formVO.materialId"
:options="ingredientOptions"
:normalizer="normalizer"
:disable-branch-nodes="true"
placeholder="请选择原料"
/>
</el-form-item>
<el-form-item
label="kg/每米"
prop="remark"
>
<el-input
v-model="formVO.remark"
placeholder="请输入每米多少千克"
/>
</el-form-item>
</el-form>
<div
slot="footer"
class="dialog-footer"
>
<el-button
type="primary"
@click="submitForm"
>确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
**重点**
6.附treeselect组件常用属性
<treeselect
:multiple="true"
v-model="form.postIds"//多选id值可赋值可传给后台
:options="postOptions"//下拉树桩多选框的数据
:show-count="true"//展示下拉总数数据
:flat="true"//设置平面模式(选中的标签不联动子节点和父节点)
:limit="5"//展示多选的标签个数
:limitText="count => `及其它${count}项`"//多选的超出文字展示方式
:auto-deselect-descendants="true"//取消节点时,取消其接点的子节点(仅可在平面模式下使用)
:auto-select-descendants="true"//选择节点时,取消其接点的子节点(仅可在平面模式下使用)
placeholder="请选择区域"
:disable-branch-nodes="true"//只能选择末级节点
/>