功能:在保险、规则、交易、积分和短信模块中实现初始功能和基础组件。

This commit is contained in:
abcv7
2026-03-03 04:04:22 +08:00
parent e050eb3317
commit e156d625bf
1999 changed files with 146080 additions and 63 deletions
+21
View File
@@ -0,0 +1,21 @@
FROM openjdk:11-jdk
LABEL maintainer="研究院研发组 <research@itcast.cn>"
# 时区修改为东八区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /dict-web
ARG PACKAGE_PATH=./target/dict-web.jar
ADD ${PACKAGE_PATH:-./} dict-web.jar
EXPOSE 8080
ENV JAVA_OPTS="\
-server \
-Xms256m \
-Xmx512m \
-XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=512m\
-Dspring.profiles.active=test"
ENTRYPOINT ["sh","-c","java -Djava.security.egd=file:/dev/./urandom -jar $JAVA_OPTS dict-web.jar"]
+97
View File
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.itheima.sfbx</groupId>
<artifactId>sfbx-dict</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>
<!--数字字典web模块-->
<artifactId>dict-web</artifactId>
<name>dict-web</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-web</artifactId>
</dependency>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-seata</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-mybatis-plus</artifactId>
</dependency>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-task-executor</artifactId>
</dependency>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-knife4j-web</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.yaml</include>
<include>**/*.txt</include>
</includes>
</resource>
</resources>
<finalName>dict-web</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,14 @@
package com.itheima.sfbx.dict;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 后台管理中的 系统管理-数字字典
*/
@SpringBootApplication(scanBasePackages = {"com.itheima.sfbx"})
public class DictWebStart {
public static void main(String[] args) {
SpringApplication.run(DictWebStart.class, args);
}
}
@@ -0,0 +1,50 @@
package com.itheima.sfbx.dict.feign;
import com.itheima.sfbx.dict.service.IDataDictService;
import com.itheima.sfbx.framework.commons.dto.dict.DataDictVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @ClassName DataDictController.java
* @Description 数字字典controller
*/
@Slf4j
@RestController
@RequestMapping("data-dict-feign")
@Api(tags = "数字字典feign")
public class DataDictFeignController {
@Autowired
IDataDictService dataDictService;
/**
* @Description 父项键查询
* @return List<DataDictVO>
*/
@PostMapping("parent-key/{parentKey}")
@ApiOperation(value = "父项键查询",notes = "父项键查询")
@ApiImplicitParam(paramType = "path",name = "parentKey",value = "字典parentKey",example = "URGE_TYPE",dataType = "String")
List<DataDictVO> findDataDictVOByParentKey(@PathVariable("parentKey") String parentKey) {
return dataDictService.findDataDictVOByParentKey(parentKey);
}
/**
* @Description 子项键查询
* @return DataDictVO
*/
@PostMapping("data-key/{dataKey}")
@ApiOperation(value = "子项键查询",notes = "子项键查询")
@ApiImplicitParam(paramType = "path",name = "dataKey",value = "字典dataKey",example = "URGE_TYPE",dataType = "String")
DataDictVO findDataDictVOByDataKey(@PathVariable("dataKey")String dataKey){
return dataDictService.findDataDictVOByDataKey(dataKey);
}
}
@@ -0,0 +1,35 @@
package com.itheima.sfbx.dict.feign;
import com.itheima.sfbx.dict.service.IPlacesService;
import com.itheima.sfbx.framework.commons.dto.dict.PlacesVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @ClassName PlacesFeignController.java
* @Description 地区controller
*/
@RestController
@RequestMapping("places-fgign")
@Api(tags = "地区fegin")
public class PlacesFeignController {
@Autowired
IPlacesService placesService;
/**
* @Description 保存字典数据
* @return
*/
@PostMapping("{parentId}")
@ApiOperation(value = "地区下拉框",notes = "地区下拉框")
@ApiImplicitParam(name = "parentId",value = "父层id",required = true,dataType = "Long")
public List<PlacesVO> findPlacesVOListByParentId(@PathVariable("parentId") Long parentId) {
return placesService.findPlacesVOListByParentId(parentId);
}
}
@@ -0,0 +1,61 @@
package com.itheima.sfbx.dict.init;
import com.itheima.sfbx.dict.service.IDataDictService;
import com.itheima.sfbx.framework.commons.utils.EmptyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
/**
* @ClassName InitDataDict.java
* @Description 热加载数字字典
*/
@Component
public class InitDataDict {
@Autowired
IDataDictService dataDictService;
@Async
@PostConstruct
public void initDataDict(){
Timer timer = new Timer();
timer.schedule(new InitTask(timer),10*1000);
}
class InitTask extends TimerTask{
private Timer timer;
private InitTask(Timer timer) {
this.timer= timer;
}
@Override
public void run() {
//所有ParentKey的set集合
Set<String> parentKeyAll = dataDictService.findParentKeyAll();
if (EmptyUtil.isNullOrEmpty(parentKeyAll)){
return;
}
//初始化父亲目录下所有有效状态的数据
parentKeyAll.forEach(n->{
dataDictService.findDataDictVOByParentKey(n);
});
//所有dataKey的set集合
Set<String> dataKeyAll = dataDictService.findDataKeyAll();
if (EmptyUtil.isNullOrEmpty(parentKeyAll)){
return;
}
//初始化datakey对应有效状态的数据
dataKeyAll.forEach(n->{
dataDictService.findDataDictVOByDataKey(n);
});
}
}
}
@@ -0,0 +1,61 @@
package com.itheima.sfbx.dict.init;
import com.itheima.sfbx.dict.service.IPlacesService;
import com.itheima.sfbx.framework.commons.constant.basic.SuperConstant;
import com.itheima.sfbx.framework.commons.dto.dict.PlacesVO;
import com.itheima.sfbx.framework.commons.utils.EmptyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
* @ClassName InitPlaces.java
* @Description 热加载区域
*/
@Component
public class InitPlaces {
@Autowired
IPlacesService placesService;
@Async
@PostConstruct
public void initPlaces(){
Timer timer = new Timer();
timer.schedule(new InitTask(timer),10*1000);
}
class InitTask extends TimerTask {
private Timer timer;
private InitTask(Timer timer) {
this.timer= timer;
}
@Override
public void run() {
//初始化省列表
List<PlacesVO> provinces = placesService.findPlacesVOListByParentId(SuperConstant.CHINA_CODE);
if (EmptyUtil.isNullOrEmpty(provinces)){
return;
}
//初始化市列表
provinces.forEach(n->{
List<PlacesVO> citys = placesService.findPlacesVOListByParentId(n.getId());
if (EmptyUtil.isNullOrEmpty(citys)){
return;
}
//初始化区列表
citys.forEach(k->{
placesService.findPlacesVOListByParentId(k.getId());
});
});
}
}
}
@@ -0,0 +1,13 @@
package com.itheima.sfbx.dict.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.sfbx.dict.pojo.DataDict;
import org.apache.ibatis.annotations.Mapper;
/**
* @Description:数据字典表Mapper接口
*/
@Mapper
public interface DataDictMapper extends BaseMapper<DataDict> {
}
@@ -0,0 +1,13 @@
package com.itheima.sfbx.dict.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.sfbx.dict.pojo.Places;
import org.apache.ibatis.annotations.Mapper;
/**
* @Description:地方表Mapper接口
*/
@Mapper
public interface PlacesMapper extends BaseMapper<Places> {
}
@@ -0,0 +1,46 @@
package com.itheima.sfbx.dict.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.itheima.sfbx.framework.mybatisplus.basic.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* @Description:数据字典表
*/
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("tab_data_dict")
@ApiModel(value="DataDict对象", description="数据字典表")
public class DataDict extends BasePojo {
private static final long serialVersionUID = 1L;
@Builder
public DataDict(Long id, String dataState, String parentKey, String dataKey, String dataValue, String discription) {
super(id, dataState);
this.parentKey = parentKey;
this.dataKey = dataKey;
this.dataValue = dataValue;
this.discription = discription;
}
@ApiModelProperty(value = "父key")
private String parentKey;
@ApiModelProperty(value = "数据字典KEY")
private String dataKey;
@ApiModelProperty(value = "")
private String dataValue;
@ApiModelProperty(value = "描述")
private String discription;
}
@@ -0,0 +1,38 @@
package com.itheima.sfbx.dict.pojo;
import com.baomidou.mybatisplus.annotation.TableName;
import com.itheima.sfbx.framework.mybatisplus.basic.BasePojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* @Description:地方表
*/
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("tab_places")
@ApiModel(value="Places对象", description="地方表")
public class Places extends BasePojo {
private static final long serialVersionUID = 1L;
@Builder
public Places(Long id, String dataState, Long parentId, String cityName) {
super(id, dataState);
this.parentId = parentId;
this.cityName = cityName;
}
@ApiModelProperty(value = "父ID")
private Long parentId;
@ApiModelProperty(value = "名称")
private String cityName;
}
@@ -0,0 +1,67 @@
package com.itheima.sfbx.dict.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.sfbx.dict.pojo.DataDict;
import com.itheima.sfbx.framework.commons.dto.dict.DataDictVO;
import java.util.List;
import java.util.Set;
/**
* @Description:数据字典表 服务类
*/
public interface IDataDictService extends IService<DataDict> {
/***
* @description 数据字典列表数据
*
* @param dataDictVO 查询条件
* @param pageNum 页码
* @param pageSize 每页条数
* @return: Page<DataDictVO>
*/
Page<DataDictVO> findDataDictVOPage(DataDictVO dataDictVO, int pageNum, int pageSize);
/**
* @Description 检测key是否已经存在
* @return
*/
Boolean checkByDataKey(String dataKey);
/**
* @Description 保存字典数据
* @return
*/
DataDictVO saveDataDict(DataDictVO dataDictVO) ;
/**
* @Description 修改字典数据
* @return
*/
DataDictVO updateDataDict(DataDictVO dataDictVO);
/**
* @Description 根据dataKey获取value
* @return DataDictVO
*/
DataDictVO findDataDictVOByDataKey(String dataKey);
/**
* @Description 获得所有不重复的ParentKey的set集合
* @return Set<String>
*/
Set<String> findParentKeyAll();
/**
* @Description 获取父key下的数据
* @return List<DataDictVO>
*/
List<DataDictVO> findDataDictVOByParentKey(String parentKey);
/**
* @Description 获得所有不重复的DataKey的set集合
* @return Set<String>
*/
Set<String> findDataKeyAll();
}
@@ -0,0 +1,23 @@
package com.itheima.sfbx.dict.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.sfbx.dict.pojo.Places;
import com.itheima.sfbx.framework.commons.constant.dict.PlacesCacheConstant;
import com.itheima.sfbx.framework.commons.dto.dict.PlacesVO;
import org.springframework.cache.annotation.Cacheable;
import java.util.List;
/**
* @Description:地方表 服务类
*/
public interface IPlacesService extends IService<Places> {
/***
* @description 查询下级
* @param parentId
* @return: List<Places>
*/
List<PlacesVO> findPlacesVOListByParentId(Long parentId);
}
@@ -0,0 +1,191 @@
package com.itheima.sfbx.dict.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.sfbx.dict.mapper.DataDictMapper;
import com.itheima.sfbx.dict.pojo.DataDict;
import com.itheima.sfbx.dict.service.IDataDictService;
import com.itheima.sfbx.framework.commons.constant.basic.SuperConstant;
import com.itheima.sfbx.framework.commons.constant.dict.DataDictCacheConstant;
import com.itheima.sfbx.framework.commons.dto.dict.DataDictVO;
import com.itheima.sfbx.framework.commons.enums.dict.DataDictEnum;
import com.itheima.sfbx.framework.commons.exception.ProjectException;
import com.itheima.sfbx.framework.commons.utils.BeanConv;
import com.itheima.sfbx.framework.commons.utils.EmptyUtil;
import com.itheima.sfbx.framework.commons.utils.ExceptionsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @Description:数据字典表 服务实现类
*/
@Slf4j
@Service
public class DataDictServiceImpl extends ServiceImpl<DataDictMapper, DataDict> implements IDataDictService {
/***
* @description 构建多条件查询条件
* @param dataDictVO 查询条件
* @return 查询条件
*/
private QueryWrapper queryWrapper(DataDictVO dataDictVO){
QueryWrapper<DataDict> queryWrapper = new QueryWrapper<>();
//多条件查询
if (!EmptyUtil.isNullOrEmpty(dataDictVO.getDiscription())){
queryWrapper.lambda().like(DataDict::getDiscription,dataDictVO.getDiscription());
}
if (!EmptyUtil.isNullOrEmpty(dataDictVO.getParentKey())){
queryWrapper.lambda().like(DataDict::getParentKey,dataDictVO.getParentKey());
}
if (!EmptyUtil.isNullOrEmpty(dataDictVO.getDataKey())){
queryWrapper.lambda().like(DataDict::getDataKey,dataDictVO.getDataKey());
}
if (!EmptyUtil.isNullOrEmpty(dataDictVO.getDataValue())){
queryWrapper.lambda().like(DataDict::getDataValue,dataDictVO.getDataValue());
}
if (!EmptyUtil.isNullOrEmpty(dataDictVO.getDataState())){
queryWrapper.lambda().eq(DataDict::getDataState,dataDictVO.getDataState());
}
queryWrapper.lambda().orderByDesc(DataDict::getCreateTime).orderByAsc(DataDict::getDataKey);
return queryWrapper;
}
@Override
@Cacheable(value = DataDictCacheConstant.PAGE,key ="#pageNum+'-'+#pageSize+'-'+#dataDictVO.hashCode()")
public Page<DataDictVO> findDataDictVOPage(DataDictVO dataDictVO, int pageNum, int pageSize) {
try {
Page<DataDict> page = new Page<>(pageNum, pageSize);
QueryWrapper<DataDict> queryWrapper = this.queryWrapper(dataDictVO);
return BeanConv.toPage(page(page, queryWrapper),DataDictVO.class);
}catch (Exception e){
log.error("查询数据字典列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.PAGE_FAIL);
}
}
@Override
public Boolean checkByDataKey(String dataKey) {
try {
QueryWrapper<DataDict> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(DataDict::getDataKey,dataKey);
return !EmptyUtil.isNullOrEmpty(getOne(queryWrapper));
}catch (Exception e){
log.error("检查数字字典重复性异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.CHECK_FALL);
}
}
@Override
@Caching(
evict={@CacheEvict(value = DataDictCacheConstant.PAGE,allEntries = true),
@CacheEvict(value = DataDictCacheConstant.PARENT_KEY,key = "#dataDictVO.parentKey")},
put={@CachePut(value = DataDictCacheConstant.DATA_KEY,key = "#dataDictVO.dataKey")})
@Transactional
public DataDictVO saveDataDict(DataDictVO dataDictVO) {
try {
DataDict dataDict =BeanConv.toBean(dataDictVO,DataDict.class);
boolean flag = save(dataDict);
if (flag){
return BeanConv.toBean(dataDict,DataDictVO.class);
}else {
log.error("数据字典保存异常!");
throw new ProjectException(DataDictEnum.SAVE_FAIL);
}
}catch (Exception e){
log.error("数据字典保存异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.SAVE_FAIL);
}
}
@Override
@Caching(
evict={@CacheEvict(value = DataDictCacheConstant.PAGE,allEntries = true),
@CacheEvict(value = DataDictCacheConstant.PARENT_KEY,key = "#dataDictVO.parentKey"),
@CacheEvict(value = DataDictCacheConstant.DATA_KEY,key = "#dataDictVO.dataKey")})
@Transactional
public DataDictVO updateDataDict(DataDictVO dataDictVO) {
try {
DataDict dataDict = BeanConv.toBean(dataDictVO, DataDict.class);
DataDict dataDictTemp = getById(dataDictVO.getId());
dataDict.setCreateBy(dataDictTemp.getCreateBy());
dataDict.setCreateTime(dataDictTemp.getCreateTime());
boolean flag = updateById(dataDict);
if (flag){
return BeanConv.toBean(dataDict, DataDictVO.class);
}else {
log.error("修改数据字典列表异常!");
throw new ProjectException(DataDictEnum.UPDATE_FAIL);
}
}catch (Exception e){
log.error("修改数据字典列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.UPDATE_FAIL);
}
}
@Override
public Set<String> findParentKeyAll() {
try {
QueryWrapper<DataDict> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(DataDict::getDataState, SuperConstant.DATA_STATE_0);
List<DataDict> list = list(queryWrapper);
return EmptyUtil.isNullOrEmpty(list)?null:list.stream().map(DataDict::getParentKey).collect(Collectors.toSet());
}catch (Exception e){
log.error("查询数据字典列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.FIND_PARENTKEY_ALL);
}
}
@Override
@Cacheable(value = DataDictCacheConstant.PARENT_KEY,key = "#parentKey")
public List<DataDictVO> findDataDictVOByParentKey(String parentKey) {
try {
QueryWrapper<DataDict> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(DataDict::getParentKey,parentKey)
.eq(DataDict::getDataState, SuperConstant.DATA_STATE_0);
return BeanConv.toBeanList(list(queryWrapper),DataDictVO.class);
}catch (Exception e){
log.error("查询数据字典列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.FIND_DATADICTVO_PARENTKEY);
}
}
@Override
public Set<String> findDataKeyAll() {
try {
QueryWrapper<DataDict> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(DataDict::getDataState, SuperConstant.DATA_STATE_0);
List<DataDict> list = list(queryWrapper);
return EmptyUtil.isNullOrEmpty(list)?null:list.stream().map(DataDict::getDataKey).collect(Collectors.toSet());
}catch (Exception e){
log.error("查询数据字典列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.FIND_DATAKEY_ALL);
}
}
@Override
@Cacheable(value = DataDictCacheConstant.DATA_KEY,key = "#dataKey")
public DataDictVO findDataDictVOByDataKey(String dataKey) {
try {
QueryWrapper<DataDict> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(DataDict::getDataKey,dataKey)
.eq(DataDict::getDataState, SuperConstant.DATA_STATE_0);
return BeanConv.toBean(getOne(queryWrapper),DataDictVO.class);
}catch (Exception e){
log.error("查询数据字典列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(DataDictEnum.FIND_DATADICTVO_DATAKEY);
}
}
}
@@ -0,0 +1,40 @@
package com.itheima.sfbx.dict.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.sfbx.dict.mapper.PlacesMapper;
import com.itheima.sfbx.dict.pojo.Places;
import com.itheima.sfbx.dict.service.IPlacesService;
import com.itheima.sfbx.framework.commons.constant.dict.PlacesCacheConstant;
import com.itheima.sfbx.framework.commons.dto.dict.PlacesVO;
import com.itheima.sfbx.framework.commons.enums.dict.PlacesEnum;
import com.itheima.sfbx.framework.commons.exception.ProjectException;
import com.itheima.sfbx.framework.commons.utils.BeanConv;
import com.itheima.sfbx.framework.commons.utils.ExceptionsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description:地方表 服务实现类
*/
@Slf4j
@Service
public class PlacesServiceImpl extends ServiceImpl<PlacesMapper, Places> implements IPlacesService {
@Override
@Cacheable(value = PlacesCacheConstant.LIST,key = "#parentId")
public List<PlacesVO> findPlacesVOListByParentId(Long parentId) {
try {
QueryWrapper<Places> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(Places::getParentId,parentId);
return BeanConv.toBeanList(list(queryWrapper),PlacesVO.class);
}catch (Exception e){
log.error("查询parentId下列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
throw new ProjectException(PlacesEnum.LIST_FAIL);
}
}
}
@@ -0,0 +1,115 @@
package com.itheima.sfbx.dict.web;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.itheima.sfbx.dict.service.IDataDictService;
import com.itheima.sfbx.framework.commons.basic.ResponseResult;
import com.itheima.sfbx.framework.commons.dto.dict.DataDictVO;
import com.itheima.sfbx.framework.commons.utils.ResponseResultBuild;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @ClassName DataDictController.java
* @Description 数字字典controller
*/
@Slf4j
@RestController
@RequestMapping("data-dict")
@Api(tags = "数字字典")
public class DataDictController {
@Autowired
IDataDictService dataDictService;
/***
* @description 数据字典分页
* @param dataDictVO 查询条件
* @param pageNum 页码
* @param pageSize 每页条数
* @return: Page<DataDictVO>
*/
@PostMapping("page/{pageNum}/{pageSize}")
@ApiOperation(value = "数据字典分页",notes = "数据字典分页")
@ApiImplicitParams({
@ApiImplicitParam(name = "dataDictVO",value = "字典查询对象",required = false,dataType = "DataDictVO"),
@ApiImplicitParam(paramType = "path",name = "pageNum",value = "页码",example = "1",dataType = "Integer"),
@ApiImplicitParam(paramType = "path",name = "pageSize",value = "每页条数",example = "10",dataType = "Integer")
})
@ApiOperationSupport(includeParameters ={"dataDictVO.parentKey","","dataDictVO.dataKey",
"dataDictVO.dataValue","dataDictVO.discription"} )
ResponseResult<Page<DataDictVO>> findDataDictVOPage(
@RequestBody DataDictVO dataDictVO,
@PathVariable("pageNum") int pageNum,
@PathVariable("pageSize") int pageSize) {
Page<DataDictVO> dataDictVOPage = dataDictService.findDataDictVOPage(dataDictVO, pageNum, pageSize);
return ResponseResultBuild.successBuild(dataDictVOPage);
}
/**
* @Description 保存字典数据
* @return
*/
@PostMapping
@ApiOperation(value = "数字字典添加",notes = "数字字典添加")
@ApiImplicitParam(name = "dataDictVO",value = "字典信息",required = true,dataType = "DataDictVO")
@ApiOperationSupport(ignoreParameters ={"dataDictVO.id", "dataDictVO.updateTime",
"dataDictVO.createBy","dataDictVO.updateBy", "dataDictVO.creator"} )
public ResponseResult<DataDictVO> saveDataDict(@RequestBody DataDictVO dataDictVO) {
DataDictVO dataDictVOResult = dataDictService.saveDataDict(dataDictVO);
return ResponseResultBuild.successBuild(dataDictVOResult);
}
/**
* @Description 修改字典数据
* @return
*/
@PatchMapping
@ApiOperation(value = "数字字典编辑",notes = "数字字典编辑")
@ApiImplicitParam(name = "dataDictVO",value = "字典信息",required = true,dataType = "DataDictVO")
@ApiOperationSupport(ignoreParameters ={"dataDictVO.updateTime", "dataDictVO.createBy",
"dataDictVO.updateBy", "dataDictVO.creator"})
public ResponseResult<DataDictVO> updateDataDict(@RequestBody DataDictVO dataDictVO) {
DataDictVO dataDictVOResult = dataDictService.updateDataDict(dataDictVO);
return ResponseResultBuild.successBuild(dataDictVOResult);
}
@PostMapping("data-state")
@ApiOperation(value = "数字字典状态编辑",notes = "数字字典状态编辑")
@ApiImplicitParam(name = "dataDictVO",value = "字典信息",required = true,dataType = "DataDictVO")
@ApiOperationSupport(ignoreParameters ={"dataDictVO.id", "dataDictVO.dataState"})
ResponseResult<DataDictVO> updateDataDictEnableFlag(@RequestBody DataDictVO dataDictVO) {
DataDictVO dataDictVOResult = dataDictService.updateDataDict(dataDictVO);
return ResponseResultBuild.successBuild(dataDictVOResult);
}
/**
* @Description 父项键查询
* @return List<DataDictVO>
*/
@PostMapping("parent-key/{parentKey}")
@ApiOperation(value = "父项键查询",notes = "父项键查询")
@ApiImplicitParam(paramType = "path",name = "parentKey",value = "字典parentKey",example = "URGE_TYPE",dataType = "String")
ResponseResult<List<DataDictVO>> findDataDictVOByParentKey(@PathVariable("parentKey") String parentKey) {
return ResponseResultBuild.successBuild(dataDictService.findDataDictVOByParentKey(parentKey));
}
/**
* @Description 子项键查询
* @return DataDictVO
*/
@PostMapping("data-key/{dataKey}")
@ApiOperation(value = "子项键查询",notes = "子项键查询")
@ApiImplicitParam(paramType = "path",name = "dataKey",value = "字典dataKey",example = "URGE_TYPE",dataType = "String")
ResponseResult<DataDictVO> findDataDictVOByDataKey(@PathVariable("dataKey")String dataKey){
return ResponseResultBuild.successBuild(dataDictService.findDataDictVOByDataKey(dataKey));
}
}
@@ -0,0 +1,41 @@
package com.itheima.sfbx.dict.web;
import com.itheima.sfbx.dict.service.IPlacesService;
import com.itheima.sfbx.framework.commons.basic.ResponseResult;
import com.itheima.sfbx.framework.commons.dto.dict.PlacesVO;
import com.itheima.sfbx.framework.commons.utils.ResponseResultBuild;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @ClassName PlacesFeignController.java
* @Description 地区controller
*/
@RestController
@RequestMapping("places")
@Api(tags = "地区")
public class PlacesController {
@Autowired
IPlacesService placesService;
/**
* @Description 保存字典数据
* @return
*/
@PostMapping("{parentId}")
@ApiOperation(value = "地区下拉框",notes = "地区下拉框")
@ApiImplicitParam(name = "parentId",value = "父层id",required = true,dataType = "Long")
public ResponseResult<List<PlacesVO>> findPlacesVOListByParentId(@PathVariable("parentId") Long parentId) {
List<PlacesVO> placesVOList = placesService.findPlacesVOListByParentId(parentId);
return ResponseResultBuild.successBuild(placesVOList);
}
}
@@ -0,0 +1,10 @@
_ __ __
(_) /__________ ______/ /_
/ / __/ ___/ __ `/ ___/ __/
/ / /_/ /__/ /_/ (__ ) /_
/_/\__/\___/\__,_/____/\__/
:: Spring Boot :: (v-2.7.10)
:: Spring Cloud :: (v-2021.0.6)
:: Spring Cloud Alibaba :: (v-2021.0.1.0)
:: sfbx Cloud :: (v-2.0-SNAPSHOT)
:: 献给可爱的传智人 ::
@@ -0,0 +1,53 @@
#服务配置
server:
#端口
port: 7071
#服务编码
tomcat:
uri-encoding: UTF-8
spring:
# profiles:
# active: test
config:
activate:
on-profile:
- test
main:
allow-circular-references: true
allow-bean-definition-overriding: true
mvc:
pathmatch:
matching-strategy: ant_path_matcher
#应用配置
application:
#应用名称
name: dict-web
cloud:
nacos:
discovery:
server-addr: ${NACOS_ADDRESS:nacos-service.yjy-public-sfbx-java.svc.cluster.local:20015} # nacos注册中心
group: SEATA_GROUP
service: ${spring.application.name}
username: ${NACOS_USERNAME:nacos}
password: ${NACOS_PASSWORD:PKsf*bxQ4;yP3a+}
config:
server-addr: ${NACOS_ADDRESS:nacos-service.yjy-public-sfbx-java.svc.cluster.local:20015} # nacos配置中心地址
group: SEATA_GROUP
file-extension: yml
shared-configs: # 共享配置
- data-id: shared-spring-seata.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
- data-id: shared-spring-task.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
- data-id: shared-redisson.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
- data-id: shared-mybatis-plus.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
username: ${NACOS_USERNAME:nacos}
password: ${NACOS_PASSWORD:PKsf*bxQ4;yP3a+}
logging:
config: classpath:logback.xml
@@ -0,0 +1,45 @@
#服务配置
server:
#端口
port: 7071
#服务编码
tomcat:
uri-encoding: UTF-8
spring:
profiles:
active: dev
main:
allow-circular-references: true
allow-bean-definition-overriding: true
mvc:
pathmatch:
matching-strategy: ant_path_matcher
#应用配置
application:
#应用名称
name: dict-web
cloud:
nacos:
discovery:
server-addr: 192.168.12.129:8848 # nacos注册中心
group: SEATA_GROUP
service: ${spring.application.name}
config:
server-addr: 192.168.12.129:8848 # nacos配置中心地址
group: SEATA_GROUP
file-extension: yml
shared-configs: # 共享配置
- data-id: shared-spring-seata.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
- data-id: shared-spring-task.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
- data-id: shared-redisson.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
- data-id: shared-mybatis-plus.yml #配置文件名-DataId
group: SEATA_GROUP
refresh: false
logging:
config: classpath:logback.xml
@@ -0,0 +1,33 @@
#\u6570\u636E\u5E93\u5730\u5740
url=jdbc:mysql://192.168.12.129:3306/restkeeper-dict?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&tinyInt1isBit=false
#\u6570\u636E\u5E93\u8D26\u53F7
userName=root
#\u6570\u636E\u5E93\u5BC6\u7801
password=pass
#\u6B64\u5904\u4E3A\u672C\u9879\u76EEsrc\u6240\u5728\u8DEF\u5F84\uFF08\u4EE3\u7801\u751F\u6210\u5668\u8F93\u51FA\u8DEF\u5F84\uFF09
serviceProjectPath=D:/easy-cloud/easy-dict/dict-web
#\u8BBE\u7F6E\u4F5C\u8005
author=Admin
#\u81EA\u5B9A\u4E49\u5305\u8DEF\u5F84
parent=com.itheima
#\u88C5\u4EE3\u7801\u7684\u6587\u4EF6\u5939\u540D
moduleName=project
#\u8BBE\u7F6E\u8868\u524D\u7F00\uFF0C\u4E0D\u8BBE\u7F6E\u5219\u9ED8\u8BA4\u65E0\u524D\u7F00
tablePrefix =tab_
#\u6570\u636E\u5E93\u8868\u540D(\u6B64\u5904\u5207\u4E0D\u53EF\u4E3A\u7A7A\uFF0C\u5982\u679C\u4E3A\u7A7A\uFF0C\u5219\u9ED8\u8BA4\u8BFB\u53D6\u6570\u636E\u5E93\u7684\u6240\u6709\u8868\u540D)
tableName=tab_data_dict,tab_places
#pojo\u7684\u8D85\u7C7B
SuperEntityClass = com.itheima.sfbx.framework.commons.basic.BasicPojo
#pojo\u7684\u8D85\u7C7B\u516C\u7528\u5B57\u6BB5
superEntityColumns = id,created_time,updated_time,sharding_id,enable_flag
#\u751F\u6210\u7684\u5C42\u7EA7
entity=true
entity.ftl.path=/templates/entity.java
mapper=true
mapper.ftl.path=/templates/mapper.java
service=false
service.ftl.path=/templates/service.java
serviceImp=false
serviceImp.ftl.path=/templates/serviceImpl.java
controller=false
controller.ftl.path=/templates/controller.java
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="/data/logs/dict-web" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/dict-web-01.log.%d{yyyy-MM-dd}.log
</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
<!--日志文件最大的大小 -->
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder"
level="TRACE" />
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor"
level="DEBUG" />
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
<!--myibatis log configure -->
<logger name="com.apache.ibatis" level="TRACE" />
<logger name="java.sql.Connection" level="DEBUG" />
<logger name="java.sql.Statement" level="DEBUG" />
<logger name="java.sql.PreparedStatement" level="DEBUG" />
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
<!--日志异步到数据库 -->
</configuration>
@@ -0,0 +1,34 @@
package ${package.Controller};
import org.springframework.web.bind.annotation.RequestMapping;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
/**
* @Description${table.comment!} 前端控制器
*/
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>
}
</#if>
@@ -0,0 +1,156 @@
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.EqualsAndHashCode;
</#if>
/**
* @Description${table.comment!}
*/
<#if entityLombokModel>
@Data
@NoArgsConstructor
<#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
<#else>
@EqualsAndHashCode(callSuper = false)
</#if>
</#if>
<#if table.convert>
@TableName("${table.name}")
</#if>
<#if swagger2>
@ApiModel(value="${entity}对象", description="${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#else>
public class ${entity} implements Serializable {
</#if>
<#if entitySerialVersionUID>
private static final long serialVersionUID = 1L;
</#if>
@Builder
public ${entity}(Long id,<#list table.fields as field>${field.propertyType} ${field.propertyName}<#if field_has_next>,</#if></#list>){
super(id);
<#list table.fields as field>
this.${field.propertyName}=${field.propertyName};
</#list>
}
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.keyFlag>
<#assign keyPropertyName="${field.propertyName}"/>
</#if>
<#if field.comment!?length gt 0>
<#if swagger2>
@ApiModelProperty(value = "${field.comment}")
<#else>
/**
* ${field.comment}
*/
</#if>
</#if>
<#if field.keyFlag>
<#-- 主键 -->
<#if field.keyIdentityFlag>
@TableId(value = "${field.name}", type = IdType.AUTO)
<#elseif idType??>
@TableId(value = "${field.name}", type = IdType.${idType})
<#elseif field.convert>
@TableId("${field.name}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- ----- 存在字段填充设置 ----->
<#if field.convert>
@TableField(value = "${field.name}", fill = FieldFill.${field.fill})
<#else>
@TableField(fill = FieldFill.${field.fill})
</#if>
<#elseif field.convert>
@TableField("${field.name}")
</#if>
<#-- 乐观锁注解 -->
<#if (versionFieldName!"") == field.name>
@Version
</#if>
<#-- 逻辑删除注解 -->
<#if (logicDeleteFieldName!"") == field.name>
@TableLogic
</#if>
private ${field.propertyType} ${field.propertyName};
</#list>
<#------------ END 字段循环遍历 ---------->
<#if !entityLombokModel>
<#list table.fields as field>
<#if field.propertyType == "boolean">
<#assign getprefix="is"/>
<#else>
<#assign getprefix="get"/>
</#if>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
<#if entityBuilderModel>
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
<#else>
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
</#if>
this.${field.propertyName} = ${field.propertyName};
<#if entityBuilderModel>
return this;
</#if>
}
</#list>
</#if>
<#if entityColumnConstant>
<#list table.fields as field>
public static final String ${field.name?upper_case} = "${field.name}";
</#list>
</#if>
<#if activeRecord>
@Override
protected Serializable pkVal() {
<#if keyPropertyName??>
return this.${keyPropertyName};
<#else>
return null;
</#if>
}
</#if>
<#if !entityLombokModel>
@Override
public String toString() {
return "${entity}{" +
<#list table.fields as field>
<#if field_index==0>
"${field.propertyName}=" + ${field.propertyName} +
<#else>
", ${field.propertyName}=" + ${field.propertyName} +
</#if>
</#list>
"}";
}
</#if>
}
@@ -0,0 +1,15 @@
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* @Description${table.comment!}Mapper接口
*/
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}
</#if>
@@ -0,0 +1,39 @@
<?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="${package.Mapper}.${table.mapperName}">
<#if enableCache>
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
</#if>
<#if baseResultMap>
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
<#list table.fields as field>
<#if field.keyFlag><#--生成主键排在第一位-->
<id column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
<#list table.commonFields as field><#--生成公共字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#list>
<#list table.fields as field>
<#if !field.keyFlag><#--生成普通字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
</resultMap>
</#if>
<#if baseColumnList>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<#list table.commonFields as field>
${field.name},
</#list>
${table.fieldNames}
</sql>
</#if>
</mapper>
@@ -0,0 +1,15 @@
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* @Description${table.comment!} 服务类
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
}
</#if>
@@ -0,0 +1,21 @@
package ${package.ServiceImpl};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
/**
* @Description${table.comment!} 服务实现类
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
}
</#if>