微服务版后端初始化

This commit is contained in:
yaoyn
2025-02-08 17:51:37 +08:00
parent 54af6be188
commit da009a7cc4
1897 changed files with 429541 additions and 81 deletions

View File

@ -0,0 +1,15 @@
# 基础镜像
FROM nexus.gdyditc.com:8082/openjdk:11-arm64
# author
MAINTAINER xjrsoft
# 挂载目录
VOLUME /home/xjrsoft
# 创建目录
RUN mkdir -p /home/xjrsoft
# 指定路径
WORKDIR /home/xjrsoft
# 复制jar文件到路径
COPY ./target/xjrsoft-service-app.jar /home/xjrsoft/xjrsoft-service-app.jar
# 启动认证服务
ENTRYPOINT ["java","-jar","xjrsoft-service-app.jar","-Dfile.encoding=UTF-8"]

View File

@ -0,0 +1,69 @@
<?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">
<parent>
<artifactId>xjrsoft-service</artifactId>
<groupId>com.xjrsoft</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xjrsoft-service-app</artifactId>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.xjrsoft</groupId>
<artifactId>xjrsoft-service-app-api</artifactId>
<version>${xjrsoft.framework.version}</version>
</dependency>
<dependency>
<groupId>com.xjrsoft</groupId>
<artifactId>xjrsoft-service-generate-api</artifactId>
<version>${xjrsoft.framework.version}</version>
</dependency>
<dependency>
<groupId>com.xjrsoft</groupId>
<artifactId>xjrsoft-service-system-api</artifactId>
<version>${xjrsoft.framework.version}</version>
</dependency>
<dependency>
<groupId>com.xjrsoft</groupId>
<artifactId>xjrsoft-common-mybatis</artifactId>
<version>${xjrsoft.framework.version}</version>
</dependency>
<dependency>
<groupId>com.xjrsoft</groupId>
<artifactId>xjrsoft-service-organization-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</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>

View File

@ -0,0 +1,24 @@
package com.xjrsoft.app;
import com.xjrsoft.common.core.annotation.UniqueNameGenerator;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
/**
* @Author: tzx
* @Date: 2023/10/20 10:49
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.xjrsoft")
@MapperScan(value = "com.xjrsoft.**.mapper")
@ComponentScan(value = "com.xjrsoft", nameGenerator = UniqueNameGenerator.class)
public class AppApplication {
public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}
}

View File

@ -0,0 +1,56 @@
package com.xjrsoft.app.client;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.app.dto.SetAppRoleAuthDto;
import com.xjrsoft.app.entity.AppAuthorize;
import com.xjrsoft.app.service.IAppAuthorizeService;
import com.xjrsoft.app.vo.AppRoleAuthVo;
import com.xjrsoft.common.core.constant.GlobalConstant;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author hnyyzy
* @version 1.0
* @date 2024/1/24 15:30
*/
@Hidden
@RestController
@AllArgsConstructor
public class AppAuthorizeClient implements IAppAuthorizeClient{
private final IAppAuthorizeService authorizeService;
@Override
@GetMapping(GlobalConstant.CLIENT_API_PRE + GlobalConstant.MODULE_APP_NAME + "/removeAppAuthorieFeign")
public void removeAppAuthorieFeign(Long menuId) {
authorizeService.remove(Wrappers.<AppAuthorize>query().lambda().eq(AppAuthorize::getObjectId, menuId));
}
/**
* 设置角色权限
* @param
*/
@Override
@PostMapping(GlobalConstant.CLIENT_API_PRE + GlobalConstant.MODULE_APP_NAME + "/setAppRoleAuthFeign")
public Boolean setAppRoleAuthFeign(@RequestBody SetAppRoleAuthDto dto) {
return authorizeService.setRoleAppAuth(dto);
}
/**
* 获取角色权限
* @param roleId
* @return
*/
@Override
@GetMapping(GlobalConstant.CLIENT_API_PRE + GlobalConstant.MODULE_APP_NAME + "/getAppRoleAuthFeign")
public AppRoleAuthVo getAppRoleAuthFeign(Long roleId) {
return authorizeService.getRoleAppAuth(roleId);
}
}

View File

@ -0,0 +1,32 @@
package com.xjrsoft.app.client;
import com.xjrsoft.app.entity.AppFuncDesign;
import com.xjrsoft.app.service.IAppFuncDesignService;
import com.xjrsoft.common.core.constant.GlobalConstant;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: tzx
* @Date: 2023/10/10 18:52
*/
@Hidden
@RestController
@AllArgsConstructor
public class AppFuncDesignClient implements IAppFuncDesignClient {
private final IAppFuncDesignService funcDesignService;
/**
* 根据关联id 获取app功能设计
* @param id
* @return
*/
@Override
@GetMapping(GlobalConstant.CLIENT_API_PRE + GlobalConstant.MODULE_APP_NAME + "/getAppFuncDesignFeign")
public AppFuncDesign getAppFuncDesignFeign(Long id) {
return funcDesignService.getById(id);
}
}

View File

@ -0,0 +1,34 @@
package com.xjrsoft.app.controller;
import com.xjrsoft.app.service.IAppAuthorizeService;
import com.xjrsoft.common.core.constant.GlobalConstant;
import com.xjrsoft.common.core.domain.result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
@RestController
@RequestMapping(GlobalConstant.APP_MODEL +"/app-authorize")
@Tag(name = GlobalConstant.APP_MODEL +"/app-authorize", description = "app 权限模块")
@AllArgsConstructor
public class AppAuthorizeController {
private final IAppAuthorizeService authorizeService;
@GetMapping("/app-menu-permissions")
@Operation(summary="app用户菜单权限数据返回")
public R appMenuPermissions(@RequestParam(required = false) Long menuId){
return R.ok(authorizeService.getAppPermissions(menuId));
}
}

View File

@ -0,0 +1,130 @@
package com.xjrsoft.app.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.toolkit.MPJWrappers;
import com.xjrsoft.app.dto.*;
import com.xjrsoft.app.entity.AppFuncDesign;
import com.xjrsoft.app.entity.AppMenu;
import com.xjrsoft.app.service.IAppFuncDesignService;
import com.xjrsoft.app.service.IAppMenuService;
import com.xjrsoft.app.vo.AppFuncDesignPageVo;
import com.xjrsoft.app.vo.AppFuncDesignVo;
import com.xjrsoft.app.vo.AppMenuVo;
import com.xjrsoft.common.core.annotation.XjrLog;
import com.xjrsoft.common.core.constant.GlobalConstant;
import com.xjrsoft.common.core.domain.page.PageOutput;
import com.xjrsoft.common.core.domain.result.R;
import com.xjrsoft.common.core.uitls.VoToColumnUtil;
import com.xjrsoft.common.mybatis.utils.ConventPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* <p>
* 前端控制器
* </p>
*
* @author tzx
* @since 2023-07-26
*/
@RestController
@RequestMapping(GlobalConstant.APP_MODEL +"/func-design")
@Tag(name = GlobalConstant.APP_MODEL +"/func-design", description = "app端功能页面设计")
@AllArgsConstructor
public class AppFuncDesignController {
private IAppFuncDesignService funcDesignService;
private IAppMenuService appMenuService;
@GetMapping(value = "/page")
@Operation(summary = "app端功能页面设计分页")
public R page(AppFuncDesignPageDto dto) {
IPage<AppFuncDesignPageVo> page = funcDesignService.selectJoinListPage(ConventPage.getPage(dto), AppFuncDesignPageVo.class, MPJWrappers.<AppFuncDesign>lambdaJoin()
.like(StrUtil.isNotBlank(dto.getKeyword()), AppMenu::getName, dto.getKeyword())
.eq(ObjectUtil.isNotEmpty(dto.getEnabledMark()), AppFuncDesign::getEnabledMark, dto.getEnabledMark())
.eq(dto.getFormType() != null, AppFuncDesign::getFormType, dto.getFormType())
.select(AppFuncDesign::getId)
.select(AppFuncDesign.class, x -> VoToColumnUtil.fieldsToColumns(AppFuncDesignPageVo.class).contains(x.getProperty()))
.selectAs(AppMenu::getName, AppFuncDesignPageVo::getName)
.selectAs(AppMenu::getRemark, AppFuncDesignPageVo::getMenuRemark)
.leftJoin(AppMenu.class, AppMenu::getId, AppFuncDesign::getAppMenuId)
.orderByDesc(AppFuncDesign::getCreateDate)
);
PageOutput<AppFuncDesignPageVo> pageOutput = ConventPage.getPageOutput(page, AppFuncDesignPageVo.class);
return R.ok(pageOutput);
}
@PostMapping
@Operation(summary = "新增app端功能页面设计")
public R add(@Valid @RequestBody AddFuncDesignDto dto) {
return R.ok(funcDesignService.add(dto));
}
@PutMapping
@Operation(summary = "修改app端功能页面设计")
public R update(@Valid @RequestBody UpdateAppFuncDesignDto dto) {
return R.ok(funcDesignService.modify(dto));
}
@GetMapping(value = "/info")
@Operation(summary = "根据id查询数app端功能页面设计详细信息")
public R info(@RequestParam Long id) {
AppFuncDesign appFuncDesign = funcDesignService.getById(id);
if (appFuncDesign == null) {
return R.error("找不到此功能页面设计!");
}
AppFuncDesignVo appFuncDesignVo = BeanUtil.toBean(appFuncDesign, AppFuncDesignVo.class);
AppMenu appMenu = appMenuService.getById(appFuncDesign.getAppMenuId());
appFuncDesignVo.setMenuConfigs(BeanUtil.toBean(appMenu, AppMenuVo.class));
return R.ok(appFuncDesignVo);
}
@DeleteMapping
@Operation(summary = "删除")
@XjrLog(value = "删除app端展示页面设计")
@Transactional(rollbackFor = Exception.class)
public R delete(@Valid @RequestBody DeleteAppPageDesignDto dto) {
AppFuncDesign appFuncDesign = funcDesignService.getById(dto.getId());
appMenuService.removeById(appFuncDesign.getAppMenuId());
funcDesignService.removeById(dto.getId());
return R.ok(Boolean.TRUE);
}
@PutMapping("/update-enable-mark")
@Operation(summary = "修改启用状态")
@XjrLog(value = "修改启用状态")
public R updateEnableMark(@Valid @RequestBody UpdateEnableMarkDto dto) {
AppFuncDesign appFuncDesign = new AppFuncDesign();
appFuncDesign.setId(dto.getId());
appFuncDesign.setEnabledMark(dto.getEnabledMark());
funcDesignService.updateById(appFuncDesign);
AppFuncDesign one = funcDesignService.getOne(Wrappers.lambdaQuery(AppFuncDesign.class).eq(AppFuncDesign::getId, dto.getId()).select(AppFuncDesign::getAppMenuId));
AppMenu appMenu = new AppMenu();
appMenu.setId(one.getAppMenuId());
appMenu.setEnabledMark(dto.getEnabledMark());
appMenuService.updateById(appMenu);
return R.ok(true);
}
}

View File

@ -0,0 +1,218 @@
package com.xjrsoft.app.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.app.dto.AddAppMenuDto;
import com.xjrsoft.app.dto.AppMenuListDto;
import com.xjrsoft.app.dto.AppMenuPageDto;
import com.xjrsoft.app.dto.UpdateAppMenuDto;
import com.xjrsoft.app.entity.AppMenu;
import com.xjrsoft.app.entity.AppMenuButton;
import com.xjrsoft.app.entity.AppMenuColumn;
import com.xjrsoft.app.entity.AppMenuForm;
import com.xjrsoft.app.service.IAppMenuButtonService;
import com.xjrsoft.app.service.IAppMenuColumnService;
import com.xjrsoft.app.service.IAppMenuFormService;
import com.xjrsoft.app.service.IAppMenuService;
import com.xjrsoft.app.vo.AppMenuListVo;
import com.xjrsoft.app.vo.AppMenuPageVo;
import com.xjrsoft.app.vo.AppMenuSimpleTreeVo;
import com.xjrsoft.app.vo.AppMenuVo;
import com.xjrsoft.common.core.constant.GlobalConstant;
import com.xjrsoft.common.core.domain.page.PageOutput;
import com.xjrsoft.common.core.domain.result.R;
import com.xjrsoft.common.core.enums.EnabledMark;
import com.xjrsoft.common.core.uitls.TreeUtil;
import com.xjrsoft.common.core.uitls.VoToColumnUtil;
import com.xjrsoft.common.mybatis.utils.ConventPage;
import com.xjrsoft.system.client.IDictionaryDetailClient;
import com.xjrsoft.system.dto.MenuTreeDto;
import com.xjrsoft.system.entity.DictionaryDetail;
import com.xjrsoft.system.vo.MenuButtonListVo;
import com.xjrsoft.system.vo.MenuColumnListVo;
import com.xjrsoft.system.vo.MenuFormListVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* app 菜单前端控制器
* </p>
*
* @author tzx
* @since 2023-07-26
*/
@RestController
@RequestMapping(GlobalConstant.APP_MODEL +"/menu")
@Tag(name = GlobalConstant.APP_MODEL +"/menu", description = "app 菜单模块")
@AllArgsConstructor
public class AppMenuController {
private final IAppMenuService appMenuService;
private final IAppMenuButtonService appMenuButtonService;
private final IAppMenuColumnService appMenuColumnService;
private final IAppMenuFormService appMenuFormService;
private final IDictionaryDetailClient dictionaryDetailClient;
@GetMapping("/page")
@Operation(summary = "app菜单分页接口")
public R page(AppMenuPageDto dto){
LambdaQueryWrapper<AppMenu> queryWrapper = Wrappers.lambdaQuery(AppMenu.class)
.eq(StrUtil.isNotBlank(dto.getName()), AppMenu::getName, dto.getName())
.eq(StrUtil.isNotBlank(dto.getCode()), AppMenu::getCode, dto.getCode())
.eq(ObjectUtil.isNotNull(dto.getCategoryId()), AppMenu::getCategoryId, dto.getCategoryId())
.orderByAsc(AppMenu::getSortCode)
.select(AppMenu.class, x -> VoToColumnUtil.fieldsToColumns(AppMenuPageVo.class).contains(x.getProperty()));
IPage<AppMenu> page = appMenuService.page(ConventPage.getPage(dto), queryWrapper);
PageOutput<AppMenuPageVo> pageOutput = ConventPage.getPageOutput(page, AppMenuPageVo.class);
return R.ok(pageOutput);
}
@GetMapping("/list")
@Operation(summary = "app菜单 列表 不分页")
public R list(AppMenuListDto dto){
LambdaQueryWrapper<AppMenu> queryWrapper = Wrappers.lambdaQuery(AppMenu.class)
.eq(StrUtil.isNotBlank(dto.getName()), AppMenu::getName, dto.getName())
.eq(StrUtil.isNotBlank(dto.getCode()), AppMenu::getCode, dto.getCode())
.eq(ObjectUtil.isNotNull(dto.getCategoryId()), AppMenu::getCategoryId, dto.getCategoryId())
.eq(AppMenu::getEnabledMark, EnabledMark.ENABLED.getCode())
.orderByAsc(AppMenu::getSortCode)
.select(AppMenu.class, x -> VoToColumnUtil.fieldsToColumns(AppMenuPageVo.class).contains(x.getProperty()));
List<AppMenu> list = appMenuService.list(queryWrapper);
List<AppMenuListVo> appMenuListVos = BeanUtil.copyToList(list, AppMenuListVo.class);
return R.ok(appMenuListVos);
}
@PostMapping
@Operation(summary = "新增")
public R add(@Valid @RequestBody AddAppMenuDto dto){
AppMenu appMenu = BeanUtil.toBean(dto, AppMenu.class);
return R.ok(appMenuService.save(appMenu));
}
@PutMapping
@Operation(summary = "修改")
public R update(@Valid @RequestBody UpdateAppMenuDto dto){
AppMenu appMenu = BeanUtil.toBean(dto, AppMenu.class);
return R.ok(appMenuService.updateById(appMenu));
}
@DeleteMapping
@Operation(summary = "删除")
public R delete(@Valid @RequestBody List<Long> ids) {
appMenuService.removeBatchByIds(ids);
return R.ok(Boolean.TRUE);
}
@GetMapping("/simple-tree")
@Operation(summary = "获取所有app菜单树结构-以分类为父级")
public R menuAuthTree(@Valid MenuTreeDto dto) {
List<AppMenu> list = appMenuService.getAppAuthMenuList(dto);
List<DictionaryDetail> dictionaryDetailList = dictionaryDetailClient.getDicDetailListByItemIdFeign(1673142942973763585L);
List<AppMenuSimpleTreeVo> appMenuSimpleTreeVoList = new ArrayList<>();
if (dictionaryDetailList.size() > 0){
for (DictionaryDetail dictionaryDetail : dictionaryDetailList) {//以功能分类做为父级
AppMenuSimpleTreeVo appMenuSimpleTreeVo = new AppMenuSimpleTreeVo();
appMenuSimpleTreeVo.setId(dictionaryDetail.getId());
appMenuSimpleTreeVo.setCategoryId(dictionaryDetail.getId());
appMenuSimpleTreeVo.setName(dictionaryDetail.getName());
appMenuSimpleTreeVo.setCode(dictionaryDetail.getCode());
List<AppMenu> collect = list.stream().filter(x -> x.getCategoryId().equals(dictionaryDetail.getId())).collect(Collectors.toList());
List<AppMenuVo> appMenuVos = BeanUtil.copyToList(collect, AppMenuVo.class);
appMenuSimpleTreeVo.setChildren(appMenuVos);
appMenuSimpleTreeVoList.add(appMenuSimpleTreeVo);
}
}
return R.ok(appMenuSimpleTreeVoList);
}
@GetMapping("/app-simple-tree")
@Operation(summary = "获取所有app菜单树结构-以分类为父级")
public R appMenuAuthTree(@Valid MenuTreeDto dto) {
List<AppMenu> list = appMenuService.getAppAuthMenuList(dto);
List<DictionaryDetail> dictionaryDetailList = dictionaryDetailClient.getDicDetailListByItemIdFeign(1673142942973763585L);
List<AppMenuSimpleTreeVo> appMenuSimpleTreeVoList = new ArrayList<>();
if (dictionaryDetailList.size() > 0){
for (DictionaryDetail dictionaryDetail : dictionaryDetailList) {//以功能分类做为父级
AppMenuSimpleTreeVo appMenuSimpleTreeVo = new AppMenuSimpleTreeVo();
appMenuSimpleTreeVo.setId(dictionaryDetail.getId());
appMenuSimpleTreeVo.setCategoryId(dictionaryDetail.getId());
appMenuSimpleTreeVo.setName(dictionaryDetail.getName());
appMenuSimpleTreeVo.setCode(dictionaryDetail.getCode());
List<AppMenu> collect = list.stream().filter(x -> x.getCategoryId().equals(dictionaryDetail.getId())).collect(Collectors.toList());
List<AppMenuVo> appMenuVos = BeanUtil.copyToList(collect, AppMenuVo.class);
if (appMenuVos.size() > 0){
appMenuSimpleTreeVo.setChildren(appMenuVos);
appMenuSimpleTreeVoList.add(appMenuSimpleTreeVo);
}
}
}
return R.ok(appMenuSimpleTreeVoList);
}
@GetMapping("/button-list")
@Operation(summary = "app菜单按钮列表权限 不分页")
public R buttonList(@RequestParam(required = false) Long menuId){
if (menuId == null) {
return R.ok(new ArrayList<>(0));
}
List<AppMenuButton> list = appMenuButtonService.list(Wrappers.<AppMenuButton>lambdaQuery().eq(menuId != 0, AppMenuButton::getMenuId, menuId));
List<MenuButtonListVo> menuButtonListVos = BeanUtil.copyToList(list, MenuButtonListVo.class);
return R.ok(menuButtonListVos);
}
@GetMapping("/column-list")
@Operation(summary = "app菜单列表字段权限 不分页")
public R columnList(@RequestParam(required = false) Long menuId){
if (menuId == null) {
return R.ok(new ArrayList<>(0));
}
List<AppMenuColumn> list = appMenuColumnService.list(Wrappers.<AppMenuColumn>lambdaQuery().eq(menuId != 0, AppMenuColumn::getMenuId, menuId));
List<MenuColumnListVo> menuColumnListVos = BeanUtil.copyToList(list, MenuColumnListVo.class);
return R.ok(menuColumnListVos);
}
@GetMapping("/form-list")
@Operation(summary = "app菜单表单列表权限 不分页")
public R formList(@RequestParam(required = false) Long menuId){
if (menuId == null) {
return R.ok(new ArrayList<>(0));
}
List<AppMenuForm> list = appMenuFormService.list(Wrappers.<AppMenuForm>lambdaQuery().eq(menuId != 0, AppMenuForm::getMenuId, menuId));
List<MenuFormListVo> menuFormListVos = BeanUtil.copyToList(list, MenuFormListVo.class);
return R.ok(TreeUtil.build(menuFormListVos));
}
}

View File

@ -0,0 +1,125 @@
package com.xjrsoft.app.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xjrsoft.app.dto.*;
import com.xjrsoft.app.entity.AppPageDesign;
import com.xjrsoft.app.service.IAppMenuService;
import com.xjrsoft.app.service.IAppPageDesignService;
import com.xjrsoft.app.vo.AppPageDesignVo;
import com.xjrsoft.common.core.annotation.XjrLog;
import com.xjrsoft.common.core.constant.GlobalConstant;
import com.xjrsoft.common.core.domain.page.PageOutput;
import com.xjrsoft.common.core.domain.result.R;
import com.xjrsoft.common.core.uitls.VoToColumnUtil;
import com.xjrsoft.common.mybatis.utils.ConventPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* <p>
* xjr_data_display【数据展示表】 前端控制器
* </p>
*
* @author hnyyzy
* @since 2023-06-25
*/
@RestController
@RequestMapping(GlobalConstant.APP_MODEL +"/page-design")
@Tag(name = GlobalConstant.APP_MODEL +"/page-design", description = "app端展示页面设计")
@AllArgsConstructor
public class AppPageDesignController {
private IAppPageDesignService pageDesignService;
private IAppMenuService appMenuService;
@GetMapping(value = "/page")
@Operation(summary = "app端展示页面设计分页")
@XjrLog("app端展示页面设计分页")
public R page(AppPageDesignDto dto) {
LambdaQueryWrapper<AppPageDesign> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StrUtil.isNotBlank(dto.getKeyword()), AppPageDesign::getName, dto.getKeyword())
.like(StrUtil.isNotBlank(dto.getName()), AppPageDesign::getName, dto.getName())
.like(StrUtil.isNotBlank(dto.getCode()), AppPageDesign::getCode, dto.getCode())
.eq(ObjectUtil.isNotEmpty(dto.getEnabledMark()), AppPageDesign::getEnabledMark,dto.getEnabledMark())
.select(AppPageDesign.class, x -> VoToColumnUtil.fieldsToColumns(AppPageDesignVo.class).contains(x.getProperty()))
.orderByAsc(AppPageDesign::getSortCode);
IPage<AppPageDesign> page = pageDesignService.page(ConventPage.getPage(dto), queryWrapper);
PageOutput<AppPageDesignVo> pageOutput = ConventPage.getPageOutput(page, AppPageDesignVo.class);
return R.ok(pageOutput);
}
@PostMapping
@Operation(summary = "新增app端展示页面设计")
@XjrLog("新增app端展示页面设计")
public R add(@Valid @RequestBody AddAppPageDesignDto dto) {
return R.ok(pageDesignService.add(dto));
}
@PostMapping("/draft")
@Operation(summary = "app端展示页面设计保存草稿")
@XjrLog("app端展示页面设计保存草稿")
public R draft(@Valid @RequestBody AppPageDesignDraftDto dto) {
AppPageDesign bean = BeanUtil.toBean(dto, AppPageDesign.class);
return R.ok(pageDesignService.saveOrUpdate(bean));
}
@PutMapping
@Operation(summary = "修改app端展示页面设计")
@XjrLog("修改app端展示页面设计")
public R update(@Valid @RequestBody UpdateAppPageDesignDto dto) {
return R.ok(pageDesignService.modify(dto));
}
@GetMapping(value = "/info")
@Operation(summary = "根据id查询数app端展示页面设计详细信息")
@XjrLog("根据id查询数app端展示页面设计详细信息")
public R info(@RequestParam Long id) {
AppPageDesign appPageDesign = pageDesignService.getById(id);
if (appPageDesign == null) {
R.error("找不到此数据展示页!");
}
return R.ok(BeanUtil.toBean(appPageDesign, AppPageDesign.class));
}
@DeleteMapping
@Operation(summary = "删除")
@XjrLog(value = "删除app端展示页面设计")
@Transactional(rollbackFor = Exception.class)
public R delete(@Valid @RequestBody DeleteAppPageDesignDto dto) {
AppPageDesign pageDesign = pageDesignService.getById(dto.getId());
if (ObjectUtils.isNotEmpty(pageDesign.getAppMenuId())) {
appMenuService.removeById(pageDesign.getAppMenuId());
}
pageDesignService.removeById(dto.getId());
return R.ok(true);
}
@PutMapping("/update-enable-mark")
@Operation(summary = "修改启用状态")
@XjrLog(value = "修改启用状态")
public R updateEnableMark(@Valid @RequestBody UpdateEnableMarkDto dto) {
AppPageDesign appPageDesign = new AppPageDesign();
appPageDesign.setId(dto.getId());
appPageDesign.setEnabledMark(dto.getEnabledMark());
pageDesignService.updateById(appPageDesign);
return R.ok(true);
}
}

View File

@ -0,0 +1,42 @@
package com.xjrsoft.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xjrsoft.app.dto.SetAppRoleAuthDto;
import com.xjrsoft.app.entity.AppAuthorize;
import com.xjrsoft.app.vo.AppRoleAuthVo;
import com.xjrsoft.system.vo.MenuAuthVo;
/**
* <p>
* 服务类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
public interface IAppAuthorizeService extends IService<AppAuthorize> {
/**
*
* @param dto 按钮id
* @return 是否成功
*/
Boolean setRoleAppAuth(SetAppRoleAuthDto dto);
/**
* 获取角色权限
*
* @param id 角色id
* @return 角色权限
*/
AppRoleAuthVo getRoleAppAuth(Long id);
/**
* 根据登陆人获取app用户菜单权限数据
*
* @return
*/
MenuAuthVo getAppPermissions(Long menuId);
}

View File

@ -0,0 +1,22 @@
package com.xjrsoft.app.service;
import com.github.yulichang.base.MPJBaseService;
import com.xjrsoft.app.dto.AddFuncDesignDto;
import com.xjrsoft.app.dto.UpdateAppFuncDesignDto;
import com.xjrsoft.app.entity.AppFuncDesign;
/**
* <p>
* 服务类
* </p>
*
* @author tzx
* @since 2023-07-26
*/
public interface IAppFuncDesignService extends MPJBaseService<AppFuncDesign> {
Boolean add(AddFuncDesignDto dto);
Boolean modify(UpdateAppFuncDesignDto dto);
}

View File

@ -0,0 +1,16 @@
package com.xjrsoft.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xjrsoft.app.entity.AppMenuButton;
/**
* <p>
* app菜单按钮 服务类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
public interface IAppMenuButtonService extends IService<AppMenuButton> {
}

View File

@ -0,0 +1,16 @@
package com.xjrsoft.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xjrsoft.app.entity.AppMenuColumn;
/**
* <p>
* app菜单列表字段 服务类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
public interface IAppMenuColumnService extends IService<AppMenuColumn> {
}

View File

@ -0,0 +1,16 @@
package com.xjrsoft.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xjrsoft.app.entity.AppMenuForm;
/**
* <p>
* app菜单表单字段 服务类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
public interface IAppMenuFormService extends IService<AppMenuForm> {
}

View File

@ -0,0 +1,19 @@
package com.xjrsoft.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xjrsoft.app.entity.AppMenu;
import com.xjrsoft.system.dto.MenuTreeDto;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author tzx
* @since 2023-07-26
*/
public interface IAppMenuService extends IService<AppMenu> {
List<AppMenu> getAppAuthMenuList(MenuTreeDto dto);
}

View File

@ -0,0 +1,22 @@
package com.xjrsoft.app.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xjrsoft.app.dto.AddAppPageDesignDto;
import com.xjrsoft.app.dto.UpdateAppPageDesignDto;
import com.xjrsoft.app.entity.AppPageDesign;
/**
* <p>
* xjr_data_display【数据展示表】 服务类
* </p>
*
* @author hnyyzy
* @since 2023-06-25
*/
public interface IAppPageDesignService extends IService<AppPageDesign> {
Boolean add(AddAppPageDesignDto dto);
Boolean modify(UpdateAppPageDesignDto dto);
}

View File

@ -0,0 +1,277 @@
package com.xjrsoft.app.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.app.dto.SetAppRoleAuthDto;
import com.xjrsoft.app.entity.*;
import com.xjrsoft.app.mapper.*;
import com.xjrsoft.app.service.IAppAuthorizeService;
import com.xjrsoft.app.vo.AppRoleAuthVo;
import com.xjrsoft.common.core.constant.GlobalConstant;
import com.xjrsoft.common.core.domain.tree.ITreeNode;
import com.xjrsoft.common.core.enums.AuthorizeType;
import com.xjrsoft.common.core.enums.EnabledMark;
import com.xjrsoft.common.core.uitls.TreeUtil;
import com.xjrsoft.organization.client.IRoleClient;
import com.xjrsoft.organization.client.IUserRoleRelationClient;
import com.xjrsoft.organization.entity.Role;
import com.xjrsoft.organization.entity.UserRoleRelation;
import com.xjrsoft.system.vo.MenuAuthVo;
import com.xjrsoft.system.vo.MenuFormTreeVo;
import com.xjrsoft.tenant.util.SecureUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
@Service
@AllArgsConstructor
public class AppAuthorizeServiceImpl extends ServiceImpl<AppAuthorizeMapper, AppAuthorize> implements IAppAuthorizeService {
private final IUserRoleRelationClient userRoleRelationClient;
private final AppMenuMapper appMenuMapper;
private final AppMenuButtonMapper appMenuButtonMapper;
private final AppMenuColumnMapper appMenuColumnMapper;
private final AppMenuFormMapper appMenuFormMapper;
private final AppAuthorizeMapper appAuthorizeMapper;
private final IRoleClient roleClient;
@Override
public MenuAuthVo getAppPermissions(Long menuId) {
long userId = StpUtil.getLoginIdAsLong();
List<UserRoleRelation> relations = userRoleRelationClient.getUserRoleRelationListByUserIdFeign(userId);
List<Long> relationIds = relations.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
List<Role> roleList = roleClient.getRoleListByRelationIdsFeign(relationIds);
List<Long> roleIdList = roleList.stream().map(Role::getId).collect(Collectors.toList());
//如果包含超级管理员权限 默认返回当前菜单所有权限
List<AppMenuButton> buttonList = appMenuButtonMapper.selectList(Wrappers.<AppMenuButton>lambdaQuery().eq(AppMenuButton::getMenuId,menuId));
List<AppMenuColumn> columnList = appMenuColumnMapper.selectList(Wrappers.<AppMenuColumn>lambdaQuery().eq(AppMenuColumn::getMenuId,menuId));
List<AppMenuForm> formList = appMenuFormMapper.selectList(Wrappers.<AppMenuForm>lambdaQuery().eq(AppMenuForm::getMenuId,menuId));
if (!SecureUtil.isAdmin(roleIdList)) {
List<AppAuthorize> authorizeList = appAuthorizeMapper.selectList(Wrappers.lambdaQuery(AppAuthorize.class)
.in(roleIdList.size() > 0,AppAuthorize::getRoleId, roleIdList)
);
List<Long> buttonIds = authorizeList.stream().filter(x -> x.getAppAuthorizeType() == AuthorizeType.BUTTON.getCode()).map(AppAuthorize::getObjectId).collect(Collectors.toList());
if (buttonIds.size() > 0) {
buttonList = buttonList.stream().filter(x->buttonIds.contains(x.getId())).collect(Collectors.toList());
}else {
buttonList = new ArrayList<>(0);
}
List<Long> columnIds = authorizeList.stream().filter(x -> x.getAppAuthorizeType() == AuthorizeType.COLUMN.getCode()).map(AppAuthorize::getObjectId).collect(Collectors.toList());
if (columnIds.size() > 0) {
columnList = columnList.stream().filter(x->columnIds.contains(x.getId())).collect(Collectors.toList());
}else {
columnList = new ArrayList<>(0);
}
List<Long> formIds = authorizeList.stream().filter(x -> x.getAppAuthorizeType() == AuthorizeType.FORM.getCode()).map(AppAuthorize::getObjectId).collect(Collectors.toList());
if (formIds.size() > 0) {
LambdaQueryWrapper<AppMenuForm> queryWrapper = Wrappers.lambdaQuery(AppMenuForm.class);
queryWrapper.in(AppMenuForm::getId, formIds);
formList = formList.stream().filter(x->formIds.contains(x.getId())).collect(Collectors.toList());
}
else {
formList = new ArrayList<>(0);
}
}
List<MenuFormTreeVo> formTreeVoList = TreeUtil.build(BeanUtil.copyToList(formList, MenuFormTreeVo.class));
MenuAuthVo vo = new MenuAuthVo();
vo.setMenuId(menuId);
vo.setButtonAuthCode(buttonList.stream().map(AppMenuButton::getCode).collect(Collectors.toSet()));
vo.setColumnAuthCode(columnList.stream().map(AppMenuColumn::getCode).collect(Collectors.toSet()));
// 处理表单字段,可能存在子表的情况
Set<Object> formAuthCodeList = new LinkedHashSet<>(formTreeVoList.size());
for (MenuFormTreeVo treeVo : formTreeVoList) {
List<MenuFormTreeVo> children = treeVo.getChildren();
if (CollectionUtils.isNotEmpty(children)) {
Set<String> subCodeList = new LinkedHashSet<>(children.size());
for (MenuFormTreeVo child : children) {
subCodeList.add(child.getCode());
}
Map<String, Set<String>> subTableCodeMap = new HashMap<>(1);
subTableCodeMap.put(treeVo.getCode(), subCodeList);
formAuthCodeList.add(subTableCodeMap);
} else {
formAuthCodeList.add(treeVo.getCode());
}
}
vo.setFormAuthCode(formAuthCodeList);
return vo;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean setRoleAppAuth(SetAppRoleAuthDto dto) {
//添加菜单权限
Long id = dto.getId();
List<AppAuthorize> savedAuthList = new ArrayList<>();
//菜单
buildAppAuthorize(id, dto.getMenuIds(), AuthorizeType.MENU.getCode(), savedAuthList);
//按钮
buildAppAuthorize(id, dto.getButtonIds(), AuthorizeType.BUTTON.getCode(), savedAuthList);
//列表字段
buildAppAuthorize(id, dto.getColumnIds(), AuthorizeType.COLUMN.getCode(), savedAuthList);
//表单字段
buildAppAuthorize(id, dto.getFormIds(), AuthorizeType.FORM.getCode(), savedAuthList);
//删除当前角色所有权限
this.remove(Wrappers.<AppAuthorize>query().lambda().eq(AppAuthorize::getRoleId, id).in(AppAuthorize::getAppAuthorizeType, 0, 1, 2, 3));
//先保存角色权限
this.saveBatch(savedAuthList);
//再更新角色权限的缓存
logoutByRoleId(id);
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public AppRoleAuthVo getRoleAppAuth(Long id) {
//如果是超级管理员 默认返回所有权限
List<AppMenu> menus = appMenuMapper.selectList(Wrappers.lambdaQuery(AppMenu.class)
.eq(AppMenu::getEnabledMark, EnabledMark.ENABLED.getCode()));
if (Objects.equals(id, GlobalConstant.SUPER_ADMIN_ROLE_ID)) {
List<AppMenuButton> buttons = appMenuButtonMapper.selectList(Wrappers.lambdaQuery(AppMenuButton.class).select(AppMenuButton::getId));
AppRoleAuthVo adminVo = new AppRoleAuthVo();
adminVo.setMenuIds(menus.stream().map(AppMenu::getId).collect(Collectors.toList()));
adminVo.setButtonIds(buttons.stream().map(AppMenuButton::getId).collect(Collectors.toList()));
return adminVo;
}
//获取角色所有权限
List<AppAuthorize> authorizeList = appAuthorizeMapper.selectList(Wrappers.lambdaQuery(AppAuthorize.class).eq(AppAuthorize::getRoleId, id));
//将角色权限分为 菜单、按钮、列表字段和表单字段权限
List<Long> menuIdList = new ArrayList<>();
List<Long> btnIdList = new ArrayList<>();
List<Long> colIdList = new ArrayList<>();
List<Long> formIdList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(authorizeList)) {
for (AppAuthorize authorize : authorizeList) {
Integer authorizeType = authorize.getAppAuthorizeType();
Long authorizeId = authorize.getObjectId();
if (authorizeType == AuthorizeType.MENU.getCode()) {
menuIdList.add(authorizeId);
} else if (authorizeType == AuthorizeType.BUTTON.getCode()) {
btnIdList.add(authorizeId);
} else if (authorizeType == AuthorizeType.COLUMN.getCode()) {
colIdList.add(authorizeId);
} else if (authorizeType == AuthorizeType.FORM.getCode()) {
formIdList.add(authorizeId);
}
}
}
AppRoleAuthVo roleAuthVo = new AppRoleAuthVo();
if (CollectionUtils.isNotEmpty(menuIdList)) {
List<Long> authMenuIdsList = menus.stream().filter(menu -> menuIdList.contains(menu.getId())).map(AppMenu::getId).collect(Collectors.toList());
roleAuthVo.setMenuIds(authMenuIdsList);
}
if (CollectionUtils.isNotEmpty(btnIdList)) {
// 过滤按钮id
List<AppMenuButton> menuButtonList = appMenuButtonMapper.selectList(Wrappers.<AppMenuButton>query().lambda()
.select(AppMenuButton::getId).in(AppMenuButton::getId, btnIdList));
roleAuthVo.setButtonIds(menuButtonList.stream().map(AppMenuButton::getId).collect(Collectors.toList()));
}
if (CollectionUtils.isNotEmpty(colIdList)) {
// 过滤列表字段id
List<AppMenuColumn> menuColumnList = appMenuColumnMapper.selectList(Wrappers.<AppMenuColumn>query().lambda()
.select(AppMenuColumn::getId).in(AppMenuColumn::getId, colIdList));
roleAuthVo.setColumnIds(menuColumnList.stream().map(AppMenuColumn::getId).collect(Collectors.toList()));
}
if (CollectionUtils.isNotEmpty(formIdList)) {
// 过滤掉按钮id
List<AppMenuForm> menuList = appMenuFormMapper.selectList(Wrappers.<AppMenuForm>query().lambda()
.select(AppMenuForm::getParentId, AppMenuForm::getId));
List<AppMenuForm> authMenuFormList = new ArrayList<>();
Set<Long> parentIdSet = new LinkedHashSet<>();
for (AppMenuForm menuForm : menuList) {
if (formIdList.contains(menuForm.getId())) {
authMenuFormList.add(menuForm);
}
parentIdSet.add(menuForm.getParentId());
}
List<MenuFormTreeVo> menuFormTreeVos = BeanUtil.copyToList(authMenuFormList, MenuFormTreeVo.class);
List<MenuFormTreeVo> menuFormTreeList = TreeUtil.build(menuFormTreeVos);
buildLastChildIds(menuFormTreeList, roleAuthVo.getFormIds(), parentIdSet);
}
return roleAuthVo;
}
private <T extends ITreeNode<T, Long>> void buildLastChildIds(List<T> treeList, List<Long> idList, Set<Long> parentIdList) {
if (CollectionUtils.isEmpty(treeList)) {
return;
}
for (ITreeNode<T, Long> treeVo : treeList) {
List<T> children = treeVo.getChildren();
if (CollectionUtils.isNotEmpty(children)) {
buildLastChildIds(children, idList, parentIdList);
} else if (!parentIdList.contains(treeVo.getId())){
idList.add(treeVo.getId());
}
}
}
/**
* 构建授权数据
*
* @param roleId 角色id
* @param itemIdList 菜单id
* @param itemType 菜单类型0-菜单1-按钮2-列表字段3-表单字段
* @param authorizeList 构建的保存对象集合
*/
private void buildAppAuthorize(Long roleId, List<Long> itemIdList, Integer itemType, List<AppAuthorize> authorizeList) {
if (CollectionUtils.isNotEmpty(itemIdList)) {
for (Long itemId : itemIdList) {
AppAuthorize authorize = new AppAuthorize();
authorize.setAppAuthorizeType(itemType);
authorize.setObjectId(itemId);
authorize.setRoleId(roleId);
authorizeList.add(authorize);
}
}
}
/**
* 根据roleId 登出所有用户 用于:角色权限变化,所有拥有此权限的用户 必须全部重新登录
*
* @param id
*/
private void logoutByRoleId(Long id) {
List<UserRoleRelation> relations = userRoleRelationClient.getUserRoleRelationListByRoleIdFeigh(id);
List<Long> currentRoleUser = relations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList());
currentRoleUser.forEach(StpUtil::logout);
}
}

View File

@ -0,0 +1,531 @@
package com.xjrsoft.app.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.meta.MetaUtil;
import cn.hutool.db.meta.Table;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.app.dto.AddAppMenuDto;
import com.xjrsoft.app.dto.AddFuncDesignDto;
import com.xjrsoft.app.dto.UpdateAppFuncDesignDto;
import com.xjrsoft.app.entity.*;
import com.xjrsoft.app.mapper.AppFuncDesignMapper;
import com.xjrsoft.app.mapper.AppMenuMapper;
import com.xjrsoft.app.service.*;
import com.xjrsoft.common.core.config.GeneratePathConfig;
import com.xjrsoft.common.core.constant.GlobalConstant;
import com.xjrsoft.common.core.domain.generator.ComponentConfig;
import com.xjrsoft.common.core.enums.FormTemplateType;
import com.xjrsoft.common.core.enums.YesOrNoEnum;
import com.xjrsoft.common.core.exception.MyException;
import com.xjrsoft.common.generate.model.*;
import com.xjrsoft.common.mybatis.utils.DatasourceUtil;
import com.xjrsoft.generate.client.IGenerateClient;
import com.xjrsoft.generate.constant.ComponentTypeConstant;
import com.xjrsoft.generate.dto.GeneratorAppDto;
import com.xjrsoft.generate.utils.GeneratorUtil;
import com.xjrsoft.generate.utils.SqlUtil;
import com.xjrsoft.system.client.IDatabaselinkClient;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author tzx
* @since 2023-07-26
*/
@Service
@AllArgsConstructor
public class AppFuncDesignServiceImpl extends MPJBaseServiceImpl<AppFuncDesignMapper, AppFuncDesign> implements IAppFuncDesignService {
private static final Boolean isOutputDirLowerName=false;
private final AppMenuMapper appMenuMapper;
private final IGenerateClient generateClient;
private final GeneratePathConfig generatePathConfig;
private final IDatabaselinkClient databaselinkClient;
private final IAppMenuButtonService appMenuButtonService;
private final IAppMenuColumnService appMenuColumnService;
private final IAppMenuFormService appMenuFormService;
private final IAppAuthorizeService appAuthorizeService;
@Override
@SneakyThrows
@Transactional(rollbackFor = Exception.class)
public Boolean add(AddFuncDesignDto dto) {
AppFuncDesign appFuncDesign = BeanUtil.toBean(dto, AppFuncDesign.class);
//如果是自定义表单 不需要生成代码 以及 page.json
if (dto.getFormType() == FormTemplateType.CUSTOM.getCode() && dto.getIsGeneratorCode() != YesOrNoEnum.YES.getCode()) {
GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
long snowflakeNextId = IdUtil.getSnowflakeNextId();
appMenu.setUrl(appMenu.getUrl() + StringPool.QUESTION_MARK + "id=" + snowflakeNextId);
appMenuMapper.insert(appMenu);
insertAppMenuConfig(generatorConfig,appMenu,false);
appFuncDesign.setId(snowflakeNextId);
appFuncDesign.setAppMenuId(appMenu.getId());
save(appFuncDesign);
} else {
GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
if(dto.getFormType() == FormTemplateType.CUSTOM.getCode()){
generatorEndCode(generatorConfig);
}
AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
appMenu.setUrl("/pages/" + dto.getCodes().getOutputValue() + StringPool.SLASH + (isOutputDirLowerName?dto.getCodes().getClassName().toLowerCase():dto.getCodes().getClassName()) + StringPool.SLASH + "list");
appMenuMapper.insert(appMenu);
insertAppMenuConfig(generatorConfig,appMenu,true);
appFuncDesign.setAppMenuId(appMenu.getId());
save(appFuncDesign);
//保存成功之后 生成代码
modifyPageJsonFile(dto.getCodes(), dto.getMenuConfigs());
generateClient.generateAppCodesFeign(dto.getCodes());
}
return Boolean.TRUE;
}
/**
* 插入app端默认菜单数据
* @param generatorConfig
* @param appMenu
* @param isUnderlineToCamel 是否需要转驼峰,自定义表单不需要生成代码不转驼峰,其它都转
* @return
*/
private Boolean insertAppMenuConfig(GeneratorConfig generatorConfig,AppMenu appMenu,boolean isUnderlineToCamel){
List<ButtonConfig> buttonConfigs = generatorConfig.getListConfig().getButtonConfigs();
List<AppMenuButton> oldBtnList = appMenuButtonService.list(Wrappers.lambdaQuery(AppMenuButton.class)
.select(AppMenuButton::getId, AppMenuButton::getCode).eq(AppMenuButton::getMenuId, appMenu.getId()));
Map<String, Long> btnCodeIdMap = oldBtnList.stream().collect(Collectors.toMap(m ->
StringUtils.defaultIfBlank(StringUtils.substringAfterLast(m.getCode(), StringPool.COLON), m.getCode()), AppMenuButton::getId));
List<AppMenuButton> btnList = new ArrayList<>();
buttonConfigs.forEach(buttonConfig -> {
String code = StringPool.EMPTY;
if (BooleanUtils.isTrue(buttonConfig.getIsUse())) {
code = buttonConfig.getCode();
AppMenuButton menuButton = new AppMenuButton();
menuButton.setId(btnCodeIdMap.get(StringUtils.defaultIfBlank(StringUtils.substringAfterLast(code, StringPool.COLON), code)));
menuButton.setMenuId(appMenu.getId());
menuButton.setName(buttonConfig.getName());
menuButton.setCode(code);
menuButton.setIcon(buttonConfig.getIcon());
btnList.add(menuButton);
}
});
List<ColumnConfig> columnConfigs = generatorConfig.getListConfig().getColumnConfigs();
List<AppMenuColumn> oldColList = appMenuColumnService.list(Wrappers.lambdaQuery(AppMenuColumn.class)
.select(AppMenuColumn::getId, AppMenuColumn::getCode).eq(AppMenuColumn::getMenuId, appMenu.getId()));
Map<String, Long> colCodeIdMap = oldColList.stream().collect(Collectors.toMap(AppMenuColumn::getCode, AppMenuColumn::getId));
List<AppMenuColumn> colList = new ArrayList<>();
for (ColumnConfig columnConfig : columnConfigs) {
AppMenuColumn menuColumn = new AppMenuColumn();
menuColumn.setMenuId(appMenu.getId());
menuColumn.setName(columnConfig.getLabel());
String code = columnConfig.getColumnName();
if (isUnderlineToCamel){//转驼峰
code = com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(columnConfig.getColumnName());
menuColumn.setId(colCodeIdMap.get(com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(columnConfig.getColumnName())));
}else {
menuColumn.setId(colCodeIdMap.get(columnConfig.getColumnName()));
}
menuColumn.setCode(code);
colList.add(menuColumn);
}
List<ComponentConfig> componentConfigList = GeneratorUtil.getFormComponentListWithoutLayout(generatorConfig.getFormJson().getList());
List<AppMenuForm> oldFormList = appMenuFormService.list(Wrappers.lambdaQuery(AppMenuForm.class)
.select(AppMenuForm::getId, AppMenuForm::getCode).eq(AppMenuForm::getMenuId, appMenu.getId()));
Map<String, Long> formCodeIdMap = oldFormList.stream().collect(Collectors.toMap(m -> m.getParentId() + StringPool.AMPERSAND + m.getCode(), AppMenuForm::getId));
List<AppMenuForm> formList = new ArrayList<>();
for (ComponentConfig componentConfig : componentConfigList) {
String type = componentConfig.getType();
if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.SUB_FORM) || StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.ONE_FOR_ONE_FORM)) {
Long oldId = formCodeIdMap.get(StringPool.ZERO + StringPool.AMPERSAND + StrUtil.toCamelCase(componentConfig.getBindTable()));
long id = oldId == null ? IdUtil.getSnowflakeNextId() : oldId;
IdWorker.getId();
AppMenuForm menuForm = new AppMenuForm();
menuForm.setId(id);
menuForm.setMenuId(appMenu.getId());
if (isUnderlineToCamel){
menuForm.setCode(StrUtil.toCamelCase(componentConfig.getBindTable()));
}else {
menuForm.setCode(componentConfig.getBindTable());
}
menuForm.setName(componentConfig.getLabel());
formList.add(menuForm);
for (ComponentConfig subConfig : componentConfig.getChildren()) {
AppMenuForm form = buildAppMenuForm(id, appMenu.getId(), subConfig,isUnderlineToCamel);
form.setId(formCodeIdMap.get(id + StringPool.AMPERSAND + form.getCode()));
formList.add(form);
}
} else {
AppMenuForm form = buildAppMenuForm(0L, appMenu.getId(), componentConfig,isUnderlineToCamel);
form.setId(formCodeIdMap.get(StringPool.ZERO + StringPool.AMPERSAND + form.getCode()));
formList.add(form);
}
}
List<Long> oldAppAuthIds = new ArrayList<>();
oldAppAuthIds.add(appMenu.getId());
List<AppMenuButton> appMenuButtonList = appMenuButtonService.list(Wrappers.lambdaQuery(AppMenuButton.class).select(AppMenuButton::getId).eq(AppMenuButton::getMenuId, appMenu.getId()));
if (appMenuButtonList.size() > 0){
List<Long> oldButtonIds = appMenuButtonList.stream().map(AppMenuButton::getId).collect(Collectors.toList());
//删除之前的按钮信息
appMenuButtonService.removeByIds(oldButtonIds);
oldAppAuthIds.addAll(oldButtonIds);
}
List<AppMenuColumn> appMenuColumnList = appMenuColumnService.list(Wrappers.lambdaQuery(AppMenuColumn.class).select(AppMenuColumn::getId).eq(AppMenuColumn::getMenuId, appMenu.getId()));
if (appMenuColumnList.size() > 0){
List<Long> oldColumnIds = appMenuColumnList.stream().map(AppMenuColumn::getId).collect(Collectors.toList());
appMenuColumnService.removeByIds(oldColumnIds);
oldAppAuthIds.addAll(oldColumnIds);
}
List<AppMenuForm> appMenuFormList = appMenuFormService.list(Wrappers.lambdaQuery(AppMenuForm.class).select(AppMenuForm::getId).eq(AppMenuForm::getMenuId, appMenu.getId()));
if (appMenuFormList.size() > 0){
List<Long> oldFormIds = appMenuFormList.stream().map(AppMenuForm::getId).collect(Collectors.toList());
appMenuFormService.removeByIds(oldFormIds);
oldAppAuthIds.addAll(oldFormIds);
}
//删除之前的授权信息
if (oldAppAuthIds.size() > 0){
appAuthorizeService.remove(Wrappers.lambdaQuery(AppAuthorize.class).in(AppAuthorize::getObjectId,oldAppAuthIds));
}
appMenuButtonService.saveBatch(btnList);
appMenuColumnService.saveBatch(colList);
appMenuFormService.saveBatch(formList);
return true;
}
private AppMenuForm buildAppMenuForm(Long parentId, Long menuId, ComponentConfig componentConfig,boolean isUnderlineToCamel) {
String field = null;
String type = componentConfig.getType();
if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.DATE_RANGE)
|| StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.TIME_RANGE)) {
if (isUnderlineToCamel){
field = com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(componentConfig.getBindStartTime()) + StringPool.COMMA + com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(componentConfig.getBindEndTime());
}else {
field = componentConfig.getBindStartTime() + StringPool.COMMA + componentConfig.getBindEndTime();
}
} else {
if (isUnderlineToCamel){
field = StrUtil.isEmpty(componentConfig.getBindField()) ? componentConfig.getKey() : com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(componentConfig.getBindField());
}else {
field = StrUtil.isEmpty(componentConfig.getBindField()) ? componentConfig.getKey() : componentConfig.getBindField();
}
}
Boolean isRequired = MapUtils.getBoolean(componentConfig.getOptions(), "required", Boolean.FALSE);
AppMenuForm subMenuForm = new AppMenuForm();
subMenuForm.setParentId(parentId);
subMenuForm.setMenuId(menuId);
subMenuForm.setCode(field);
subMenuForm.setName(componentConfig.getLabel());
subMenuForm.setIsRequired(isRequired ? YesOrNoEnum.YES.getCode() : YesOrNoEnum.NO.getCode());
return subMenuForm;
}
@Override
@SneakyThrows
@Transactional(rollbackFor = Exception.class)
public Boolean modify(UpdateAppFuncDesignDto dto) {
AppFuncDesign appFuncDesign = BeanUtil.toBean(dto, AppFuncDesign.class);
//如果是自定义表单 不需要生成代码 以及 page.json
if (dto.getFormType() == FormTemplateType.CUSTOM.getCode() && dto.getIsGeneratorCode() != YesOrNoEnum.YES.getCode()) {
GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
appMenu.setId(dto.getAppMenuId());
appMenu.setUrl(appMenu.getUrl() + StringPool.QUESTION_MARK + "id=" + appFuncDesign.getId());
appMenuMapper.updateById(appMenu);
insertAppMenuConfig(generatorConfig,appMenu,false);
appFuncDesign.setAppMenuId(appMenu.getId());
updateById(appFuncDesign);
} else {
GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
if(dto.getFormType() == FormTemplateType.CUSTOM.getCode()){
generatorEndCode(generatorConfig);
}
AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);
appMenu.setId(dto.getAppMenuId());
appMenu.setUrl("/pages/" + dto.getCodes().getOutputValue() + StringPool.SLASH + (isOutputDirLowerName?dto.getCodes().getClassName().toLowerCase():dto.getCodes().getClassName()) + StringPool.SLASH + "list");
appMenuMapper.updateById(appMenu);
insertAppMenuConfig(generatorConfig,appMenu,true);
updateById(appFuncDesign);
//保存成功之后 生成代码
modifyPageJsonFile(dto.getCodes(), dto.getMenuConfigs());
generateClient.generateAppCodesFeign(dto.getCodes());
}
return Boolean.TRUE;
}
private void modifyPageJsonFile(GeneratorAppDto dto, AddAppMenuDto menuDto) {
File tempFile = FileUtil.file(generatePathConfig.getAppPath() + StringPool.SLASH + "pages.json");
JSON jsonContent = JSONUtil.readJSON(tempFile, StandardCharsets.UTF_8);
Boolean isPageCreated=false;
if (jsonContent.getByPath("pages").toString().contains( "pages/" + dto.getOutputValue() + StringPool.SLASH + (isOutputDirLowerName?dto.getClassName().toLowerCase():dto.getClassName()) + StringPool.SLASH + "list")) {
isPageCreated=true;
}
Boolean isEasycomCreated=false;
if (jsonContent.getByPath("easycom").toString().contains( "^sys-" + dto.getOutputValue() + "-(.*)")) {
isEasycomCreated=true;
}
//如果已经包含了此地址 就不再生成
if(isPageCreated&&isEasycomCreated){
return;
}
if(!isPageCreated) {
Map<String, Object> listJsonMap = new HashMap<>();
listJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + (isOutputDirLowerName ? dto.getClassName().toLowerCase() : dto.getClassName()) + StringPool.SLASH + "list");
Map<String, Object> listStyleMap = new HashMap<>();
listStyleMap.put("navigationBarTitleText", menuDto.getName());
listJsonMap.put("style", listStyleMap);
// Map<String, Object> formJsonMap = new HashMap<>();
// formJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "form");
// Map<String, Object> formStyleMap = new HashMap<>();
// formStyleMap.put("navigationBarTitleText", "新增");
// formJsonMap.put("style", formStyleMap);
Map<String, Object> containerJsonMap = new HashMap<>();
containerJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "container");
Map<String, Object> containerStyleMap = new HashMap<>();
containerStyleMap.put("navigationBarTitleText", "新增");
containerJsonMap.put("style", containerStyleMap);
JSONArray pages = JSONUtil.parseArray(jsonContent.getByPath("pages").toString());
pages.add(listJsonMap);
// pages.add(formJsonMap);
pages.add(containerJsonMap);
jsonContent.putByPath("pages", pages);
}
if(!isEasycomCreated){
JSONObject easycom = JSONUtil.parseObj(jsonContent.getByPath("easycom").toString());
JSONObject custom = easycom.getJSONObject("custom");
custom.putIfAbsent("^sys-" + dto.getOutputValue() + "-(.*)","@/pages/" + dto.getOutputValue() + "/$1/form.vue");
jsonContent.putByPath("easycom", easycom);
}
FileUtil.writeString(jsonContent.toJSONString(4), tempFile, StandardCharsets.UTF_8);
// \components\system-form\index.vue 文件修改
String indexFilePath = generatePathConfig.getAppPath() + StringPool.SLASH +
"components" + StringPool.SLASH + "system-form" + StringPool.SLASH + "index.vue";
String indexFileContent = FileUtil.readUtf8String(indexFilePath);
String newIndexFileContent = StringUtils.replace(indexFileContent, "<!--html-->", dto.getTagString());
FileUtil.writeUtf8String(newIndexFileContent, indexFilePath);
}
/**
* 根据json 生成后端代码
* @param generatorConfig
*/
@SneakyThrows
private void generatorEndCode(GeneratorConfig generatorConfig){
Optional<TableConfig> tableConfigOptional = generatorConfig.getTableConfigs().stream().filter(TableConfig::getIsMain).findFirst();
//主表
TableConfig mainTable;
if (tableConfigOptional.isPresent()) {
mainTable = tableConfigOptional.get();
} else {
throw new MyException("请选择主表");
}
OutputConfig outputConfig = generatorConfig.getOutputConfig();
String databaseId = generatorConfig.getDatabaseId();
if (BooleanUtils.isTrue(outputConfig.getIsDataAuth())) {
// 添加权限字段 rule_user_id
DataSource dataSource = DatasourceUtil.getDataSource(databaseId);
String[] columnNames = MetaUtil.getColumnNames(dataSource, mainTable.getTableName());
if (!ArrayUtils.contains(columnNames, GlobalConstant.AUTH_USER_ID)) {
DbType dbType = databaselinkClient.getDatabaselinkDbTypeFeign(databaseId);
Db.use(dataSource).executeBatch(SqlUtil.buildAddDataAuthFieldSqls(dbType, mainTable.getTableName()));
}
}
//修改 getTableInfos 也记得修改 FromTemplateServiceImpl 的同名方法
List<Table> tableInfos = getTableInfos(generatorConfig);
createCodeFile(generatorConfig, mainTable, tableInfos);
}
/**
* 获取表结构信息
*
* @param generatorConfig
* @return
*/
private List<Table> getTableInfos(GeneratorConfig generatorConfig) {
List<Table> tableInfos = new ArrayList<>();
for (TableConfig tableConfig : generatorConfig.getTableConfigs()) {
//判断是否为默认数据源
if (StrUtil.equalsIgnoreCase(generatorConfig.getDatabaseId(), GlobalConstant.DEFAULT_DATASOURCE_KEY)) {
tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDatasourceMaster(), tableConfig.getTableName()));
} else {
tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDataSource(generatorConfig.getDatabaseId()), tableConfig.getTableName()));
}
}
return tableInfos;
}
/**
* 根据配置生成文件
*
* @param generatorConfig
* @param mainTable
* @param tableInfos
* @throws FileNotFoundException
*/
private void createCodeFile(GeneratorConfig generatorConfig, TableConfig mainTable, List<Table> tableInfos) throws FileNotFoundException {
String className = generatorConfig.getOutputConfig().getClassName();
// 输出区域 在 微服务中 的 代表 选择服务模块
String dirValue = generatorConfig.getOutputConfig().getOutputValue();
//---------------------------------------生成entity开始----------------------------------------------------
{
Map<String, String> entityCodeMap = GeneratorUtil.getEntityCode(generatorConfig, tableInfos);
for (Map.Entry<String, String> entry : entityCodeMap.entrySet()) {
GeneratorUtil.writeFile(GeneratorUtil.getEntityOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
}
}
//---------------------------------------生成entity结束----------------------------------------------------
//********************************************生成dto开始************************************************
{
Map<String, String> dtoMap = new HashMap<>(3);
dtoMap.putAll(GeneratorUtil.getAddDtoCode(generatorConfig, tableInfos));
dtoMap.putAll(GeneratorUtil.getUpdateDtoCode(generatorConfig, tableInfos));
dtoMap.putAll(GeneratorUtil.getPageDtoCode(generatorConfig, tableInfos, mainTable));
for (Map.Entry<String, String> entry : dtoMap.entrySet()) {
GeneratorUtil.writeFile(GeneratorUtil.getDtoOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
}
}
//********************************************生成dto结束************************************************
//###############################################生成Vo开始###############################################
{
Map<String, String> voMap = new HashMap<>(2);
voMap.putAll(GeneratorUtil.getPageVoCode(generatorConfig, tableInfos, mainTable));
voMap.putAll(GeneratorUtil.getInfoVoCode(generatorConfig, tableInfos, mainTable));
for (Map.Entry<String, String> entry : voMap.entrySet()) {
GeneratorUtil.writeFile(GeneratorUtil.getVoOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
}
}
//###############################################生成Vo结束###############################################
//---------------------------------------生成三层代码开始----------------------------------------------------
{
Map<String, String> mapperCode = GeneratorUtil.getMapperCode(generatorConfig, tableInfos);
for (Map.Entry<String, String> entry : mapperCode.entrySet()) {
GeneratorUtil.writeFile(GeneratorUtil.getMapperOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
}
}
{
Map<String, String> serviceCode = GeneratorUtil.getServiceCode(generatorConfig, mainTable, tableInfos.size() > 1);
for (Map.Entry<String, String> entry : serviceCode.entrySet()) {
GeneratorUtil.writeFile(GeneratorUtil.getServiceOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
}
}
{
Map<String, String> serviceImplCode = GeneratorUtil.getServiceImplCode(generatorConfig, mainTable, tableInfos.size() > 1);
for (Map.Entry<String, String> entry : serviceImplCode.entrySet()) {
GeneratorUtil.writeFile(GeneratorUtil.getServiceImplOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
}
}
{
Map<String, String> controllerCode = GeneratorUtil.getControllerCode(generatorConfig, tableInfos, mainTable);
for (Map.Entry<String, String> entry : controllerCode.entrySet()) {
GeneratorUtil.writeFile(GeneratorUtil.getControllerOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
}
}
//---------------------------------------生成三层代码结束----------------------------------------------------
}
}

View File

@ -0,0 +1,21 @@
package com.xjrsoft.app.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.app.entity.AppMenuButton;
import com.xjrsoft.app.mapper.AppMenuButtonMapper;
import com.xjrsoft.app.service.IAppMenuButtonService;
import org.springframework.stereotype.Service;
/**
* <p>
* app菜单按钮 服务实现类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
@Service
public class AppMenuButtonServiceImpl extends ServiceImpl<AppMenuButtonMapper, AppMenuButton> implements IAppMenuButtonService {
}

View File

@ -0,0 +1,20 @@
package com.xjrsoft.app.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.app.entity.AppMenuColumn;
import com.xjrsoft.app.mapper.AppMenuColumnMapper;
import com.xjrsoft.app.service.IAppMenuColumnService;
import org.springframework.stereotype.Service;
/**
* <p>
* app菜单列表字段 服务实现类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
@Service
public class AppMenuColumnServiceImpl extends ServiceImpl<AppMenuColumnMapper, AppMenuColumn> implements IAppMenuColumnService {
}

View File

@ -0,0 +1,20 @@
package com.xjrsoft.app.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.app.entity.AppMenuForm;
import com.xjrsoft.app.mapper.AppMenuFormMapper;
import com.xjrsoft.app.service.IAppMenuFormService;
import org.springframework.stereotype.Service;
/**
* <p>
* app菜单表单字段 服务实现类
* </p>
*
* @author hnyyzy
* @since 2023-12-25
*/
@Service
public class AppMenuFormServiceImpl extends ServiceImpl<AppMenuFormMapper, AppMenuForm> implements IAppMenuFormService {
}

View File

@ -0,0 +1,69 @@
package com.xjrsoft.app.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.app.entity.AppAuthorize;
import com.xjrsoft.app.entity.AppMenu;
import com.xjrsoft.app.mapper.AppAuthorizeMapper;
import com.xjrsoft.app.mapper.AppMenuMapper;
import com.xjrsoft.app.service.IAppMenuService;
import com.xjrsoft.common.core.enums.AuthorizeType;
import com.xjrsoft.common.core.enums.EnabledMark;
import com.xjrsoft.organization.client.IUserRoleRelationClient;
import com.xjrsoft.organization.entity.UserRoleRelation;
import com.xjrsoft.system.dto.MenuTreeDto;
import com.xjrsoft.tenant.util.SecureUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author tzx
* @since 2023-07-26
*/
@Service
@AllArgsConstructor
public class AppMenuServiceImpl extends ServiceImpl<AppMenuMapper, AppMenu> implements IAppMenuService {
private final IUserRoleRelationClient userRoleRelationClient;
private final AppAuthorizeMapper appAuthorizeMapper;
@Override
public List<AppMenu> getAppAuthMenuList(MenuTreeDto dto) {
List<UserRoleRelation> relations = userRoleRelationClient.getUserRoleRelationListByUserIdFeign(StpUtil.getLoginIdAsLong());
if (CollectionUtils.isEmpty(relations)) {
return new ArrayList<>();
}
List<Long> roleIds = relations.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
List<Long> authMenuIdList = null;
// 非超级管理员权限过滤
if (!SecureUtil.isAdmin(roleIds)) {
List<AppAuthorize> authorizeList = appAuthorizeMapper.selectList(Wrappers.<AppAuthorize>lambdaQuery()
.eq(AppAuthorize::getAppAuthorizeType, AuthorizeType.MENU.getCode())
.in(AppAuthorize::getRoleId, roleIds));
if (CollectionUtils.isEmpty(authorizeList)) {
return new ArrayList<>();
}
authMenuIdList = authorizeList.stream().map(AppAuthorize::getObjectId).collect(Collectors.toList());
}
return this.list(Wrappers.<AppMenu>lambdaQuery()
.like(StrUtil.isNotBlank(dto.getCode()), AppMenu::getCode, dto.getCode())
.like(StrUtil.isNotBlank(dto.getName()), AppMenu::getName, dto.getName())
.in(CollectionUtils.isNotEmpty(authMenuIdList), AppMenu::getId, authMenuIdList)
.eq(AppMenu::getEnabledMark, EnabledMark.ENABLED.getCode())
.orderByAsc(AppMenu::getSortCode)
);
}
}

View File

@ -0,0 +1,225 @@
package com.xjrsoft.app.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.app.dto.AddAppPageDesignDto;
import com.xjrsoft.app.dto.UpdateAppPageDesignDto;
import com.xjrsoft.app.entity.AppMenu;
import com.xjrsoft.app.entity.AppPageDesign;
import com.xjrsoft.app.mapper.AppMenuMapper;
import com.xjrsoft.app.mapper.AppPageDesignMapper;
import com.xjrsoft.app.service.IAppPageDesignService;
import com.xjrsoft.common.core.config.GeneratePathConfig;
import com.xjrsoft.common.core.constant.GlobalConstant;
import com.xjrsoft.common.core.enums.YesOrNoEnum;
import com.xjrsoft.common.core.exception.MyException;
import com.xjrsoft.common.redis.service.RedisUtil;
import com.xjrsoft.generate.utils.GeneratorUtil;
import com.xjrsoft.system.entity.DictionaryDetail;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* <p>
* xjr_data_display【数据展示表】 服务实现类
* </p>
*
* @author hnyyzy
* @since 2023-06-25
*/
@Service
@AllArgsConstructor
public class AppPageDesignServiceImpl extends ServiceImpl<AppPageDesignMapper, AppPageDesign> implements IAppPageDesignService {
private final AppMenuMapper appMenuMapper;
private final GeneratePathConfig generatePathConfig;
private final RedisUtil redisUtil;
@Override
@Transactional(rollbackFor = Exception.class)
@SneakyThrows
public Boolean add(AddAppPageDesignDto dto) {
long count = count(Wrappers.<AppPageDesign>query().lambda().eq(AppPageDesign::getName, dto.getName()));
if (count > 0) {
throw new MyException("此数据展示页已经存在!");
}
AppPageDesign appPageDesign = BeanUtil.toBean(dto, AppPageDesign.class);
List<DictionaryDetail> detailList = redisUtil.get(GlobalConstant.DIC_DETAIL_CACHE_KEY, new TypeReference<List<DictionaryDetail>>() {
});
if (dto.getIsMenu() == YesOrNoEnum.YES.getCode()) {
Optional<DictionaryDetail> first = detailList.stream().filter(x -> x.getId().equals(dto.getCategoryId())).findFirst();
if (!first.isPresent()) {
throw new MyException("找不到当前功能类别信息!");
}
AppMenu appMenu = new AppMenu();
appMenu.setCode(dto.getCode());
appMenu.setName(dto.getName());
appMenu.setIcon(dto.getIcon());
appMenu.setCategoryId(dto.getCategoryId());
appMenu.setRemark(dto.getRemark());
appMenu.setUrl(StringPool.SLASH+"pages"+StringPool.SLASH +first.get().getValue().toLowerCase() + StringPool.SLASH + dto.getCode().toLowerCase());
appMenuMapper.insert(appMenu);
appPageDesign.setAppMenuId(appMenu.getId());
save(appPageDesign);
//保存成功之后 生成代码
GeneratorUtil.writeFile(getPageOutputDir(first.get().getValue()), dto.getCode().toLowerCase() + StringPool.DOT + "vue", dto.getPageCode());
File tempFile = FileUtil.file(generatePathConfig.getAppPath() + StringPool.SLASH + "pages.json");
JSON jsonContent = JSONUtil.readJSON(tempFile, StandardCharsets.UTF_8);
Map<String, Object> pageJsonMap = new HashMap<>();
pageJsonMap.put("path", "pages/" + first.get().getValue().toLowerCase() + StringPool.SLASH + dto.getCode().toLowerCase());
Map<String, Object> styleMap = new HashMap<>();
styleMap.put("navigationBarTitleText", dto.getName());
pageJsonMap.put("style", styleMap);
JSONArray pages = JSONUtil.parseArray(jsonContent.getByPath("pages").toString());
pages.add(pageJsonMap);
jsonContent.putByPath("pages", pages);
FileUtil.writeString(jsonContent.toJSONString(4), tempFile, StandardCharsets.UTF_8);
} else {
save(appPageDesign);
return Boolean.TRUE;
}
return Boolean.TRUE;
}
@Override
@Transactional(rollbackFor = Exception.class)
@SneakyThrows
public Boolean modify(UpdateAppPageDesignDto dto) {
AppPageDesign appPageDesign = BeanUtil.toBean(dto, AppPageDesign.class);
if (dto.getIsMenu() == YesOrNoEnum.YES.getCode()) {
List<DictionaryDetail> detailList = redisUtil.get(GlobalConstant.DIC_DETAIL_CACHE_KEY, new TypeReference<List<DictionaryDetail>>() {
});
Optional<DictionaryDetail> first = detailList.stream().filter(x -> x.getId().equals(dto.getCategoryId())).findFirst();
if (!first.isPresent()) {
throw new MyException("找不到当前功能类别信息!");
}
GeneratorUtil.writeFile(getPageOutputDir(first.get().getValue().toLowerCase()), dto.getCode().toLowerCase() + StringPool.DOT + "vue", dto.getPageCode());
AppMenu appMenu = new AppMenu();
appMenu.setCode(dto.getCode());
appMenu.setName(dto.getName());
appMenu.setIcon(dto.getIcon());
appMenu.setCategoryId(dto.getCategoryId());
appMenu.setUrl(StringPool.SLASH+"pages"+StringPool.SLASH +first.get().getValue().toLowerCase() + StringPool.SLASH + dto.getCode().toLowerCase());
appMenu.setRemark(dto.getRemark());
//如果发布菜单 menuid 不为空 则需要修改
if (ObjectUtil.isNotNull(dto.getAppMenuId())) {
appMenu.setId(dto.getAppMenuId());
appMenuMapper.updateById(appMenu);
} else {
appMenuMapper.insert(appMenu);
}
// //保存成功之后 生成代码
// GeneratorUtil.writeFile(getPageOutputDir(first.get().getValue()), dto.getCode().toLowerCase() + StringPool.DOT + "vue", dto.getPageCode());
File tempFile = FileUtil.file(generatePathConfig.getAppPath() + StringPool.SLASH + "pages.json");
JSON jsonContent = JSONUtil.readJSON(tempFile, StandardCharsets.UTF_8);
//判断page.json里面是否有对应的路径没有就进行生成
String path = "pages/" + first.get().getValue().toLowerCase() + StringPool.SLASH + dto.getCode().toLowerCase();
if (((JSONObject) jsonContent).get("pages").toString().contains(path)){
JSONArray pages = JSONUtil.parseArray(jsonContent.getByPath("pages").toString());
for (Object page : pages) {
if (page.toString().contains(path) && !page.toString().contains(dto.getName())){//找到这个path路径的值再判断页面名称是否改变改变则先移除再新增
pages.remove(page);
Map<String, Object> pageJsonMap = new HashMap<>();
pageJsonMap.put("path", path);
Map<String, Object> styleMap = new HashMap<>();
styleMap.put("navigationBarTitleText", dto.getName());
pageJsonMap.put("style", styleMap);
pages.add(pageJsonMap);
jsonContent.putByPath("pages", pages);
FileUtil.writeString(jsonContent.toJSONString(4), tempFile, StandardCharsets.UTF_8);
}
}
}else {
Map<String, Object> pageJsonMap = new HashMap<>();
pageJsonMap.put("path", path);
Map<String, Object> styleMap = new HashMap<>();
styleMap.put("navigationBarTitleText", dto.getName());
pageJsonMap.put("style", styleMap);
JSONArray pages = JSONUtil.parseArray(jsonContent.getByPath("pages").toString());
pages.add(pageJsonMap);
jsonContent.putByPath("pages", pages);
FileUtil.writeString(jsonContent.toJSONString(4), tempFile, StandardCharsets.UTF_8);
}
appPageDesign.setAppMenuId(appMenu.getId());
} else {
//如果不发布菜单 并且 appmenuId又在 需要删除菜单
if (ObjectUtil.isNotNull(dto.getAppMenuId())) {
appMenuMapper.deleteById(dto.getAppMenuId());
}
}
updateById(appPageDesign);
return Boolean.TRUE;
}
/**
* 获取实体类生成目录
*
* @param outputArea
* @return
*/
private String getPageOutputDir(String outputArea) {
return generatePathConfig.getAppPath() + StringPool.SLASH + "pages" + StringPool.SLASH + outputArea.toLowerCase();
}
}

View File

@ -0,0 +1,3 @@
spring:
profiles:
active: public

View File

@ -0,0 +1,76 @@
server:
port: 3004
spring:
application:
name: app-service
main:
allow-bean-definition-overriding: true
autoconfigure:
#自动化配置 例外处理
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
primary: master
datasource:
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://new-energy-mysqlt.itc.gdyd.com:3307/fcd2-msat-init?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
username: learun4dev
password: ABcd1234@
cloud:
nacos: #nacos监控
discovery:
server-addr: 10.0.252.1:8848
namespace: ITC
group: DNE
username: nacos
password: ABcd1234@
config:
server-addr: 10.0.252.1:8848 # nacos 配置中心地址
namespace: ITC
group: DNE
username: nacos
password: ABcd1234@
file-extension: yml # 指定格式 xjrsoft-demo-service-dev.yml
extension-configs:
- data-id: global-config.yml #导入全局配置
refresh: true
group: DNE
- data-id: mybatis-plus-config.yml #导入mybatisplus 配置
refresh: true
group: DNE
- data-id: sa-token-client-config.yml #导入sa-token配置
refresh: true
group: DNE
- data-id: redis-config.yml #导入redis配置
refresh: true
group: DNE
- data-id: seata-config.yml #导入seata配置
refresh: true
group: DNE
sentinel:
transport:
dashboard: localhost:8080 #sentinel dashboard 地址
port: 8719 #默认端口, 如果 被占用,会一直+1 直到未被占用为止
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
show-extensions: true
api-docs:
path: /app/v3/api-docs
group-configs:
- group: 'default'
paths-to-match: '/app/**'
packages-to-scan: com.xjrsoft.app
default-flat-param-object: false