Просмотр исходного кода

:heavy_plus_sign: 添加行政区划模块

smallchill 6 лет назад
Родитель
Сommit
4d1de005d4

+ 1 - 1
pom.xml

@@ -20,7 +20,7 @@
 
         <flowable.version>6.4.2</flowable.version>
 
-        <spring.boot.version>2.1.13.RELEASE</spring.boot.version>
+        <spring.boot.version>2.1.14.RELEASE</spring.boot.version>
         <spring.platform.version>Cairo-SR8</spring.platform.version>
 
         <!-- 推荐使用Harbor -->

+ 146 - 0
src/main/java/org/springblade/modules/system/controller/RegionController.java

@@ -0,0 +1,146 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.*;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.launch.constant.AppConstant;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.modules.system.entity.Region;
+import org.springblade.modules.system.service.IRegionService;
+import org.springblade.modules.system.vo.RegionVO;
+import org.springblade.modules.system.wrapper.RegionWrapper;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 行政区划表 控制器
+ *
+ * @author Chill
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping(AppConstant.APPLICATION_SYSTEM_NAME + "/region")
+@Api(value = "行政区划表", tags = "行政区划表接口")
+public class RegionController extends BladeController {
+
+	private final IRegionService regionService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入region")
+	public R<Region> detail(Region region) {
+		Region detail = regionService.getOne(Condition.getQueryWrapper(region));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页 行政区划表
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入region")
+	public R<IPage<Region>> list(Region region, Query query) {
+		IPage<Region> pages = regionService.page(Condition.getPage(query), Condition.getQueryWrapper(region));
+		return R.data(pages);
+	}
+
+	/**
+	 * 懒加载列表
+	 */
+	@GetMapping("/lazy-list")
+	@ApiImplicitParams({
+		@ApiImplicitParam(name = "code", value = "区划编号", paramType = "query", dataType = "string"),
+		@ApiImplicitParam(name = "name", value = "区划名称", paramType = "query", dataType = "string")
+	})
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "懒加载列表", notes = "传入menu")
+	public R<List<RegionVO>> lazyList(String parentCode, @ApiIgnore @RequestParam Map<String, Object> menu) {
+		List<RegionVO> list = regionService.lazyList(parentCode, menu);
+		return R.data(RegionWrapper.build().listNodeLazyVO(list));
+	}
+
+	/**
+	 * 懒加载列表
+	 */
+	@GetMapping("/lazy-tree")
+	@ApiImplicitParams({
+		@ApiImplicitParam(name = "code", value = "区划编号", paramType = "query", dataType = "string"),
+		@ApiImplicitParam(name = "name", value = "区划名称", paramType = "query", dataType = "string")
+	})
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "懒加载列表", notes = "传入menu")
+	public R<List<RegionVO>> lazyTree(String parentCode, @ApiIgnore @RequestParam Map<String, Object> menu) {
+		List<RegionVO> list = regionService.lazyTree(parentCode, menu);
+		return R.data(RegionWrapper.build().listNodeLazyVO(list));
+	}
+
+	/**
+	 * 新增 行政区划表
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "新增", notes = "传入region")
+	public R save(@Valid @RequestBody Region region) {
+		return R.status(regionService.save(region));
+	}
+
+	/**
+	 * 修改 行政区划表
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "修改", notes = "传入region")
+	public R update(@Valid @RequestBody Region region) {
+		return R.status(regionService.updateById(region));
+	}
+
+	/**
+	 * 新增或修改 行政区划表
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "新增或修改", notes = "传入region")
+	public R submit(@Valid @RequestBody Region region) {
+		return R.status(regionService.submit(region));
+	}
+
+
+	/**
+	 * 删除 行政区划表
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "删除", notes = "传入主键")
+	public R remove(@ApiParam(value = "主键", required = true) @RequestParam String id) {
+		return R.status(regionService.removeRegion(id));
+	}
+
+
+}

+ 128 - 0
src/main/java/org/springblade/modules/system/entity/Region.java

@@ -0,0 +1,128 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 行政区划表实体类
+ *
+ * @author Chill
+ */
+@Data
+@TableName("blade_region")
+@ApiModel(value = "Region对象", description = "行政区划表")
+public class Region implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 区划编号
+	 */
+	@TableId(value = "code", type = IdType.INPUT)
+	@ApiModelProperty(value = "区划编号")
+	private String code;
+	/**
+	 * 父区划编号
+	 */
+	@ApiModelProperty(value = "父区划编号")
+	private String parentCode;
+	/**
+	 * 祖区划编号
+	 */
+	@ApiModelProperty(value = "祖区划编号")
+	private String ancestors;
+	/**
+	 * 区划名称
+	 */
+	@ApiModelProperty(value = "区划名称")
+	private String name;
+	/**
+	 * 省级区划编号
+	 */
+	@ApiModelProperty(value = "省级区划编号")
+	private String provinceCode;
+	/**
+	 * 省级名称
+	 */
+	@ApiModelProperty(value = "省级名称")
+	private String provinceName;
+	/**
+	 * 市级区划编号
+	 */
+	@ApiModelProperty(value = "市级区划编号")
+	private String cityCode;
+	/**
+	 * 市级名称
+	 */
+	@ApiModelProperty(value = "市级名称")
+	private String cityName;
+	/**
+	 * 区级区划编号
+	 */
+	@ApiModelProperty(value = "区级区划编号")
+	private String districtCode;
+	/**
+	 * 区级名称
+	 */
+	@ApiModelProperty(value = "区级名称")
+	private String districtName;
+	/**
+	 * 镇级区划编号
+	 */
+	@ApiModelProperty(value = "镇级区划编号")
+	private String townCode;
+	/**
+	 * 镇级名称
+	 */
+	@ApiModelProperty(value = "镇级名称")
+	private String townName;
+	/**
+	 * 村级区划编号
+	 */
+	@ApiModelProperty(value = "村级区划编号")
+	private String villageCode;
+	/**
+	 * 村级名称
+	 */
+	@ApiModelProperty(value = "村级名称")
+	private String villageName;
+	/**
+	 * 层级
+	 */
+	@ApiModelProperty(value = "层级")
+	private Integer level;
+	/**
+	 * 排序
+	 */
+	@ApiModelProperty(value = "排序")
+	private Integer sort;
+	/**
+	 * 备注
+	 */
+	@ApiModelProperty(value = "备注")
+	private String remark;
+
+
+}

+ 49 - 0
src/main/java/org/springblade/modules/system/mapper/RegionMapper.java

@@ -0,0 +1,49 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.modules.system.entity.Region;
+import org.springblade.modules.system.vo.RegionVO;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 行政区划表 Mapper 接口
+ *
+ * @author Chill
+ */
+public interface RegionMapper extends BaseMapper<Region> {
+
+	/**
+	 * 懒加载列表
+	 * @param parentCode
+	 * @param param
+	 * @return
+	 */
+	List<RegionVO> lazyList(String parentCode, Map<String, Object> param);
+
+	/**
+	 * 懒加载列表
+	 * @param parentCode
+	 * @param param
+	 * @return
+	 */
+	List<RegionVO> lazyTree(String parentCode, Map<String, Object> param);
+
+}

+ 100 - 0
src/main/java/org/springblade/modules/system/mapper/RegionMapper.xml

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.system.mapper.RegionMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="regionResultMap" type="org.springblade.modules.system.entity.Region">
+        <id column="code" property="code"/>
+        <result column="parent_code" property="parentCode"/>
+        <result column="ancestors" property="ancestors"/>
+        <result column="name" property="name"/>
+        <result column="province_code" property="provinceCode"/>
+        <result column="province_name" property="provinceName"/>
+        <result column="city_code" property="cityCode"/>
+        <result column="city_name" property="cityName"/>
+        <result column="district_code" property="districtCode"/>
+        <result column="district_name" property="districtName"/>
+        <result column="town_code" property="townCode"/>
+        <result column="town_name" property="townName"/>
+        <result column="village_code" property="villageCode"/>
+        <result column="village_name" property="villageName"/>
+        <result column="level" property="level"/>
+        <result column="sort" property="sort"/>
+        <result column="remark" property="remark"/>
+    </resultMap>
+
+    <resultMap id="regionVOResultMap" type="org.springblade.modules.system.vo.RegionVO">
+        <id column="code" property="code"/>
+        <result column="parent_code" property="parentCode"/>
+        <result column="ancestors" property="ancestors"/>
+        <result column="name" property="name"/>
+        <result column="province_code" property="provinceCode"/>
+        <result column="province_name" property="provinceName"/>
+        <result column="city_code" property="cityCode"/>
+        <result column="city_name" property="cityName"/>
+        <result column="district_code" property="districtCode"/>
+        <result column="district_name" property="districtName"/>
+        <result column="town_code" property="townCode"/>
+        <result column="town_name" property="townName"/>
+        <result column="village_code" property="villageCode"/>
+        <result column="village_name" property="villageName"/>
+        <result column="level" property="level"/>
+        <result column="sort" property="sort"/>
+        <result column="remark" property="remark"/>
+        <result column="id" property="id"/>
+        <result column="parent_id" property="parentId"/>
+        <result column="has_children" property="hasChildren"/>
+    </resultMap>
+
+    <resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode">
+        <id column="id" property="id"/>
+        <result column="parent_id" property="parentId"/>
+        <result column="title" property="title"/>
+        <result column="value" property="value"/>
+        <result column="key" property="key"/>
+        <result column="has_children" property="hasChildren"/>
+    </resultMap>
+
+    <select id="lazyList" resultMap="regionVOResultMap">
+        SELECT
+            region.*,
+            ( SELECT CASE WHEN count( 1 ) > 0 THEN 1 ELSE 0 END FROM blade_region WHERE parent_code = region.code ) AS "has_children"
+        FROM
+            blade_region region
+        <where>
+            <if test="param1!=null">
+                and region.parent_code = #{param1}
+            </if>
+            <if test="param2.code!=null and param2.code!=''">
+                and region.code like concat(concat('%', #{param2.code}),'%')
+            </if>
+            <if test="param2.name!=null and param2.name!=''">
+                and region.name like concat(concat('%', #{param2.name}),'%')
+            </if>
+        </where>
+    </select>
+
+    <select id="lazyTree" resultMap="treeNodeResultMap">
+        SELECT
+            region.code AS "id",
+            region.parent_code AS "parent_id",
+            region.name AS "title",
+            region.code AS "value",
+            region.code AS "key",
+            ( SELECT CASE WHEN count( 1 ) > 0 THEN 1 ELSE 0 END FROM blade_region WHERE parent_code = region.code ) AS "has_children"
+        FROM
+            blade_region region
+        <where>
+            <if test="param1!=null">
+                and region.parent_code = #{param1}
+            </if>
+            <if test="param2.code!=null and param2.code!=''">
+                and region.code like concat(concat('%', #{param2.code}),'%')
+            </if>
+            <if test="param2.name!=null and param2.name!=''">
+                and region.name like concat(concat('%', #{param2.name}),'%')
+            </if>
+        </where>
+    </select>
+
+</mapper>

+ 67 - 0
src/main/java/org/springblade/modules/system/service/IRegionService.java

@@ -0,0 +1,67 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.modules.system.entity.Region;
+import org.springblade.modules.system.vo.RegionVO;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 行政区划表 服务类
+ *
+ * @author Chill
+ */
+public interface IRegionService extends IService<Region> {
+
+	/**
+	 * 提交
+	 *
+	 * @param region
+	 * @return
+	 */
+	boolean submit(Region region);
+
+	/**
+	 * 删除
+	 *
+	 * @param id
+	 * @return
+	 */
+	boolean removeRegion(String id);
+
+	/**
+	 * 懒加载列表
+	 *
+	 * @param parentCode
+	 * @param param
+	 * @return
+	 */
+	List<RegionVO> lazyList(String parentCode, Map<String, Object> param);
+
+	/**
+	 * 懒加载列表
+	 *
+	 * @param parentCode
+	 * @param param
+	 * @return
+	 */
+	List<RegionVO> lazyTree(String parentCode, Map<String, Object> param);
+
+}

+ 66 - 0
src/main/java/org/springblade/modules/system/service/impl/RegionServiceImpl.java

@@ -0,0 +1,66 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.modules.system.entity.Region;
+import org.springblade.modules.system.mapper.RegionMapper;
+import org.springblade.modules.system.service.IRegionService;
+import org.springblade.modules.system.vo.RegionVO;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 行政区划表 服务实现类
+ *
+ * @author Chill
+ */
+@Service
+public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements IRegionService {
+
+	@Override
+	public boolean submit(Region region) {
+		Integer cnt = baseMapper.selectCount(Wrappers.<Region>query().lambda().eq(Region::getCode, region.getCode()));
+		if (cnt > 0) {
+			return this.updateById(region);
+		}
+		return this.save(region);
+	}
+
+	@Override
+	public boolean removeRegion(String id) {
+		Integer cnt = baseMapper.selectCount(Wrappers.<Region>query().lambda().like(Region::getParentCode, id));
+		if (cnt > 0) {
+			throw new ServiceException("请先删除子节点!");
+		}
+		return removeById(id);
+	}
+
+	@Override
+	public List<RegionVO> lazyList(String parentCode, Map<String, Object> param) {
+		return baseMapper.lazyList(parentCode, param);
+	}
+
+	@Override
+	public List<RegionVO> lazyTree(String parentCode, Map<String, Object> param) {
+		return baseMapper.lazyTree(parentCode, param);
+	}
+}

+ 84 - 0
src/main/java/org/springblade/modules/system/vo/RegionVO.java

@@ -0,0 +1,84 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.vo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.tool.node.INode;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.system.entity.Region;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 行政区划表视图实体类
+ *
+ * @author Chill
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "RegionVO对象", description = "行政区划表")
+public class RegionVO extends Region implements INode<RegionVO> {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键ID
+	 */
+	@JsonSerialize(using = ToStringSerializer.class)
+	private Long id;
+
+	/**
+	 * 父节点ID
+	 */
+	@JsonSerialize(using = ToStringSerializer.class)
+	private Long parentId;
+
+	/**
+	 * 是否有子孙节点
+	 */
+	@JsonInclude(JsonInclude.Include.NON_EMPTY)
+	private Boolean hasChildren;
+
+	/**
+	 * 子孙节点
+	 */
+	@JsonInclude(JsonInclude.Include.NON_EMPTY)
+	private List<RegionVO> children;
+
+	@Override
+	public Long getId() {
+		return Func.toLong(this.getCode());
+	}
+
+	@Override
+	public Long getParentId() {
+		return Func.toLong(this.getParentCode());
+	}
+
+	@Override
+	public List<RegionVO> getChildren() {
+		if (this.children == null) {
+			this.children = new ArrayList<>();
+		}
+		return this.children;
+	}
+}

+ 48 - 0
src/main/java/org/springblade/modules/system/wrapper/RegionWrapper.java

@@ -0,0 +1,48 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.wrapper;
+
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.node.ForestNodeMerger;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.modules.system.entity.Region;
+import org.springblade.modules.system.vo.RegionVO;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 包装类,返回视图层所需的字段
+ *
+ * @author Chill
+ */
+public class RegionWrapper extends BaseEntityWrapper<Region, RegionVO> {
+
+	public static RegionWrapper build() {
+		return new RegionWrapper();
+	}
+
+	@Override
+	public RegionVO entityVO(Region region) {
+		return Objects.requireNonNull(BeanUtil.copy(region, RegionVO.class));
+	}
+
+	public List<RegionVO> listNodeLazyVO(List<RegionVO> list) {
+		return ForestNodeMerger.merge(list);
+	}
+
+}

+ 1 - 1
src/main/resources/templates/controller.java.vm

@@ -62,7 +62,7 @@ public class $!{table.controllerName} extends $!{superControllerClass} {
 public class $!{table.controllerName} {
 #end
 
-	private $!{table.serviceName} $!{table.entityPath}Service;
+	private final $!{table.serviceName} $!{table.entityPath}Service;
 
 #if($!{cfg.hasWrapper})
 	/**