Commit bf558e67 authored by linpeiqin's avatar linpeiqin

初始化

parents
Pipeline #119 failed with stages
target/
!.mvn/wrapper/maven-wrapper.jar
/.mvn/*
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
\ No newline at end of file
### 服务接口文档
---
- Knife4j
- 服务启动后,Knife4j的文档入口地址 [http://localhost:8082/doc.html#/plus](http://localhost:8082/doc.html#/plus)
- Postman
- 无需启动服务,即可将当前工程的接口导出成Postman格式。在工程的common/common-tools/模块下,找到ExportApiApp文件,并执行main函数。
### 服务启动环境依赖
---
执行docker-compose up -d 命令启动下面依赖的服务。
执行docker-compose down 命令停止下面服务。
- Redis
- 版本:4
- 端口: 6379
- 推荐客户端工具 [AnotherRedisDesktopManager](https://github.com/qishibo/AnotherRedisDesktopManager)
- Minio
- 版本:8.4.5
- 控制台URL:需要配置Nginx,将请求导入到我们缺省设置的19000端口,之后可通过浏览器操作minio。
- 缺省用户名密码:admin/admin123456
<?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>
<groupId>com.yice</groupId>
<artifactId>lmp</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>application-webadmin</artifactId>
<version>1.0.0</version>
<name>application-webadmin</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-captcha</artifactId>
<version>${ajcaptcha.version}</version>
</dependency>
<!-- 业务组件依赖 -->
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-ext</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-redis</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-log</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-minio</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-sequence</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-datafilter</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-swagger</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.yice</groupId>
<artifactId>common-dict</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.yice.webadmin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 应用服务启动类。
*
* @author linking
* @date 2023-04-13
*/
@EnableAsync
@SpringBootApplication
@ComponentScan("com.yice")
public class WebAdminApplication {
public static void main(String[] args) {
SpringApplication.run(WebAdminApplication.class, args);
}
}
package com.yice.webadmin.app.controller;
import com.yice.common.log.annotation.OperationLog;
import com.yice.common.log.model.constant.SysOperationLogType;
import com.github.pagehelper.page.PageMethod;
import com.yice.webadmin.app.vo.*;
import com.yice.webadmin.app.dto.*;
import com.yice.webadmin.app.model.*;
import com.yice.webadmin.app.service.*;
import com.yice.common.core.object.*;
import com.yice.common.core.util.*;
import com.yice.common.core.constant.*;
import com.yice.common.core.annotation.MyRequestBody;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 提示词模板操作控制器类。
*
* @author linking
* @date 2023-04-13
*/
@Api(tags = "提示词模板管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/app/promptTemplate")
public class PromptTemplateController {
@Autowired
private PromptTemplateService promptTemplateService;
/**
* 新增提示词模板数据。
*
* @param promptTemplateDto 新增对象。
* @return 应答结果对象,包含新增对象主键Id。
*/
@ApiOperationSupport(ignoreParameters = {"promptTemplateDto.templateId", "promptTemplateDto.searchString"})
@OperationLog(type = SysOperationLogType.ADD)
@PostMapping("/add")
public ResponseResult<Long> add(@MyRequestBody PromptTemplateDto promptTemplateDto) {
String errorMessage = MyCommonUtil.getModelValidationError(promptTemplateDto, false);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
PromptTemplate promptTemplate = MyModelUtil.copyTo(promptTemplateDto, PromptTemplate.class);
// 验证关联Id的数据合法性
CallResult callResult = promptTemplateService.verifyRelatedData(promptTemplate, null);
if (!callResult.isSuccess()) {
return ResponseResult.errorFrom(callResult);
}
promptTemplate = promptTemplateService.saveNew(promptTemplate);
return ResponseResult.success(promptTemplate.getTemplateId());
}
/**
* 更新提示词模板数据。
*
* @param promptTemplateDto 更新对象。
* @return 应答结果对象。
*/
@ApiOperationSupport(ignoreParameters = {"promptTemplateDto.searchString"})
@OperationLog(type = SysOperationLogType.UPDATE)
@PostMapping("/update")
public ResponseResult<Void> update(@MyRequestBody PromptTemplateDto promptTemplateDto) {
String errorMessage = MyCommonUtil.getModelValidationError(promptTemplateDto, true);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
PromptTemplate promptTemplate = MyModelUtil.copyTo(promptTemplateDto, PromptTemplate.class);
PromptTemplate originalPromptTemplate = promptTemplateService.getById(promptTemplate.getTemplateId());
if (originalPromptTemplate == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
// 验证关联Id的数据合法性
CallResult callResult = promptTemplateService.verifyRelatedData(promptTemplate, originalPromptTemplate);
if (!callResult.isSuccess()) {
return ResponseResult.errorFrom(callResult);
}
if (!promptTemplateService.update(promptTemplate, originalPromptTemplate)) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
/**
* 删除提示词模板数据。
*
* @param templateId 删除对象主键Id。
* @return 应答结果对象。
*/
@OperationLog(type = SysOperationLogType.DELETE)
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long templateId) {
if (MyCommonUtil.existBlankArgument(templateId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
return this.doDelete(templateId);
}
/**
* 列出符合过滤条件的提示词模板列表。
*
* @param promptTemplateDtoFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<MyPageData<PromptTemplateVo>> list(
@MyRequestBody PromptTemplateDto promptTemplateDtoFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
PromptTemplate promptTemplateFilter = MyModelUtil.copyTo(promptTemplateDtoFilter, PromptTemplate.class);
String orderBy = MyOrderParam.buildOrderBy(orderParam, PromptTemplate.class);
List<PromptTemplate> promptTemplateList =
promptTemplateService.getPromptTemplateListWithRelation(promptTemplateFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(promptTemplateList, PromptTemplate.INSTANCE));
}
/**
* 查看指定提示词模板对象详情。
*
* @param templateId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<PromptTemplateVo> view(@RequestParam Long templateId) {
PromptTemplate promptTemplate = promptTemplateService.getByIdWithRelation(templateId, MyRelationParam.full());
if (promptTemplate == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
PromptTemplateVo promptTemplateVo = PromptTemplate.INSTANCE.fromModel(promptTemplate);
return ResponseResult.success(promptTemplateVo);
}
private ResponseResult<Void> doDelete(Long templateId) {
String errorMessage;
// 验证关联Id的数据合法性
PromptTemplate originalPromptTemplate = promptTemplateService.getById(templateId);
if (originalPromptTemplate == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!promptTemplateService.remove(templateId)) {
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
}
package com.yice.webadmin.app.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.app.model.PromptTemplate;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 提示词模板数据操作访问接口。
*
* @author linking
* @date 2023-04-13
*/
public interface PromptTemplateMapper extends BaseDaoMapper<PromptTemplate> {
/**
* 批量插入对象列表。
*
* @param promptTemplateList 新增对象列表。
*/
void insertList(List<PromptTemplate> promptTemplateList);
/**
* 获取过滤后的对象列表。
*
* @param promptTemplateFilter 主表过滤对象。
* @param orderBy 排序字符串,order by从句的参数。
* @return 对象列表。
*/
List<PromptTemplate> getPromptTemplateList(
@Param("promptTemplateFilter") PromptTemplate promptTemplateFilter, @Param("orderBy") String orderBy);
}
<?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="com.yice.webadmin.app.dao.PromptTemplateMapper">
<resultMap id="BaseResultMap" type="com.yice.webadmin.app.model.PromptTemplate">
<id column="template_id" jdbcType="BIGINT" property="templateId"/>
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
<result column="deleted_flag" jdbcType="TINYINT" property="deletedFlag"/>
<result column="template_name" jdbcType="VARCHAR" property="templateName"/>
<result column="template_label" jdbcType="VARCHAR" property="templateLabel"/>
<result column="page_view" jdbcType="BIGINT" property="pageView"/>
<result column="template_content" jdbcType="VARCHAR" property="templateContent"/>
<result column="template_source" jdbcType="TINYINT" property="templateSource"/>
<result column="scenario_type" jdbcType="TINYINT" property="scenarioType"/>
<result column="parameter_format" jdbcType="VARCHAR" property="parameterFormat"/>
<result column="interface_address" jdbcType="VARCHAR" property="interfaceAddress"/>
<result column="template_framework" jdbcType="TINYINT" property="templateFramework"/>
<result column="variable" jdbcType="VARCHAR" property="variable"/>
</resultMap>
<insert id="insertList">
INSERT INTO lmp_prompt_template
(template_id,
create_user_id,
create_time,
update_user_id,
update_time,
deleted_flag,
template_name,
template_label,
page_view,
template_content,
template_source,
scenario_type,
parameter_format,
interface_address,
template_framework,
variable)
VALUES
<foreach collection="list" index="index" item="item" separator="," >
(#{item.templateId},
#{item.createUserId},
#{item.createTime},
#{item.updateUserId},
#{item.updateTime},
#{item.deletedFlag},
#{item.templateName},
#{item.templateLabel},
#{item.pageView},
#{item.templateContent},
#{item.templateSource},
#{item.scenarioType},
#{item.parameterFormat},
#{item.interfaceAddress},
#{item.templateFramework},
#{item.variable})
</foreach>
</insert>
<!-- 如果有逻辑删除字段过滤,请写到这里 -->
<sql id="filterRef">
<!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
<include refid="com.yice.webadmin.app.dao.PromptTemplateMapper.inputFilterRef"/>
AND lmp_prompt_template.deleted_flag = ${@com.yice.common.core.constant.GlobalDeletedFlag@NORMAL}
</sql>
<!-- 这里仅包含调用接口输入的主表过滤条件 -->
<sql id="inputFilterRef">
<if test="promptTemplateFilter != null">
<if test="promptTemplateFilter.searchString != null and promptTemplateFilter.searchString != ''">
<bind name = "safePromptTemplateSearchString" value = "'%' + promptTemplateFilter.searchString + '%'" />
AND CONCAT(IFNULL(lmp_prompt_template.template_name,''), IFNULL(lmp_prompt_template.template_content,'')) LIKE #{safePromptTemplateSearchString}
</if>
</if>
</sql>
<select id="getPromptTemplateList" resultMap="BaseResultMap" parameterType="com.yice.webadmin.app.model.PromptTemplate">
SELECT * FROM lmp_prompt_template
<where>
<include refid="filterRef"/>
</where>
<if test="orderBy != null and orderBy != ''">
ORDER BY ${orderBy}
</if>
</select>
</mapper>
package com.yice.webadmin.app.dto;
import com.yice.common.core.validator.UpdateGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.*;
/**
* PromptTemplateDto对象。
*
* @author linking
* @date 2023-04-13
*/
@ApiModel("PromptTemplateDto对象")
@Data
public class PromptTemplateDto {
/**
* 模板ID。
*/
@ApiModelProperty(value = "模板ID", required = true)
@NotNull(message = "数据验证失败,模板ID不能为空!", groups = {UpdateGroup.class})
private Long templateId;
/**
* 模板名称。
*/
@ApiModelProperty(value = "模板名称")
private String templateName;
/**
* 模板标签。
*/
@ApiModelProperty(value = "模板标签")
private String templateLabel;
/**
* 浏览量。
*/
@ApiModelProperty(value = "浏览量")
private Long pageView;
/**
* 模板内容。
*/
@ApiModelProperty(value = "模板内容")
private String templateContent;
/**
* 模板来源。
*/
@ApiModelProperty(value = "模板来源")
private Integer templateSource;
/**
* 场景类型。
*/
@ApiModelProperty(value = "场景类型")
private Integer scenarioType;
/**
* 参数格式。
*/
@ApiModelProperty(value = "参数格式")
private String parameterFormat;
/**
* 接口地址。
*/
@ApiModelProperty(value = "接口地址")
private String interfaceAddress;
/**
* 模板框架。
*/
@ApiModelProperty(value = "模板框架")
private Integer templateFramework;
/**
* 变量列表。
*/
@ApiModelProperty(value = "变量列表")
private String variable;
/**
* template_name / template_content LIKE搜索字符串。
*/
@ApiModelProperty(value = "LIKE模糊搜索字符串")
private String searchString;
}
package com.yice.webadmin.app.model;
import com.baomidou.mybatisplus.annotation.*;
import com.yice.common.core.util.MyCommonUtil;
import com.yice.common.core.annotation.*;
import com.yice.common.core.base.model.BaseModel;
import com.yice.common.core.base.mapper.BaseModelMapper;
import com.yice.webadmin.app.vo.PromptTemplateVo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import java.util.Map;
/**
* PromptTemplate实体对象。
*
* @author linking
* @date 2023-04-13
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(value = "lmp_prompt_template")
public class PromptTemplate extends BaseModel {
/**
* 模板ID。
*/
@TableId(value = "template_id")
private Long templateId;
/**
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
*/
@TableLogic
private Integer deletedFlag;
/**
* 模板名称。
*/
private String templateName;
/**
* 模板标签。
*/
private String templateLabel;
/**
* 浏览量。
*/
private Long pageView;
/**
* 模板内容。
*/
private String templateContent;
/**
* 模板来源。
*/
private Integer templateSource;
/**
* 场景类型。
*/
private Integer scenarioType;
/**
* 参数格式。
*/
private String parameterFormat;
/**
* 接口地址。
*/
private String interfaceAddress;
/**
* 模板框架。
*/
private Integer templateFramework;
/**
* 变量列表。
*/
private String variable;
/**
* template_name / template_content LIKE搜索字符串。
*/
@TableField(exist = false)
private String searchString;
public void setSearchString(String searchString) {
this.searchString = MyCommonUtil.replaceSqlWildcard(searchString);
}
@RelationGlobalDict(
masterIdField = "templateSource",
dictCode = "TemplateSourceLabel")
@TableField(exist = false)
private Map<String, Object> templateSourceDictMap;
@RelationGlobalDict(
masterIdField = "scenarioType",
dictCode = "ScenarioTypeLabel")
@TableField(exist = false)
private Map<String, Object> scenarioTypeDictMap;
@RelationGlobalDict(
masterIdField = "templateFramework",
dictCode = "TemplateFrameworkLabel")
@TableField(exist = false)
private Map<String, Object> templateFrameworkDictMap;
@Mapper
public interface PromptTemplateModelMapper extends BaseModelMapper<PromptTemplateVo, PromptTemplate> {
/**
* 转换Vo对象到实体对象。
*
* @param promptTemplateVo 域对象。
* @return 实体对象。
*/
@Override
PromptTemplate toModel(PromptTemplateVo promptTemplateVo);
/**
* 转换实体对象到VO对象。
*
* @param promptTemplate 实体对象。
* @return 域对象。
*/
@Override
PromptTemplateVo fromModel(PromptTemplate promptTemplate);
}
public static final PromptTemplateModelMapper INSTANCE = Mappers.getMapper(PromptTemplateModelMapper.class);
}
package com.yice.webadmin.app.service;
import com.yice.webadmin.app.model.*;
import com.yice.common.core.base.service.IBaseService;
import java.util.*;
/**
* 提示词模板数据操作服务接口。
*
* @author linking
* @date 2023-04-13
*/
public interface PromptTemplateService extends IBaseService<PromptTemplate, Long> {
/**
* 保存新增对象。
*
* @param promptTemplate 新增对象。
* @return 返回新增对象。
*/
PromptTemplate saveNew(PromptTemplate promptTemplate);
/**
* 利用数据库的insertList语法,批量插入对象列表。
*
* @param promptTemplateList 新增对象列表。
*/
void saveNewBatch(List<PromptTemplate> promptTemplateList);
/**
* 更新数据对象。
*
* @param promptTemplate 更新的对象。
* @param originalPromptTemplate 原有数据对象。
* @return 成功返回true,否则false。
*/
boolean update(PromptTemplate promptTemplate, PromptTemplate originalPromptTemplate);
/**
* 删除指定数据。
*
* @param templateId 主键Id。
* @return 成功返回true,否则false。
*/
boolean remove(Long templateId);
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getPromptTemplateListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
List<PromptTemplate> getPromptTemplateList(PromptTemplate filter, String orderBy);
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
* 如果仅仅需要获取主表数据,请移步(getPromptTemplateList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
List<PromptTemplate> getPromptTemplateListWithRelation(PromptTemplate filter, String orderBy);
}
package com.yice.webadmin.app.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yice.webadmin.app.service.*;
import com.yice.webadmin.app.dao.*;
import com.yice.webadmin.app.model.*;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.common.core.constant.GlobalDeletedFlag;
import com.yice.common.core.object.MyRelationParam;
import com.yice.common.core.object.CallResult;
import com.yice.common.core.base.service.BaseService;
import com.yice.common.core.util.MyModelUtil;
import com.yice.common.sequence.wrapper.IdGeneratorWrapper;
import com.yice.common.dict.service.GlobalDictService;
import com.github.pagehelper.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* 提示词模板数据操作服务类。
*
* @author linking
* @date 2023-04-13
*/
@Slf4j
@Service("promptTemplateService")
public class PromptTemplateServiceImpl extends BaseService<PromptTemplate, Long> implements PromptTemplateService {
@Autowired
private PromptTemplateMapper promptTemplateMapper;
@Autowired
private GlobalDictService globalDictService;
@Autowired
private IdGeneratorWrapper idGenerator;
/**
* 返回当前Service的主表Mapper对象。
*
* @return 主表Mapper对象。
*/
@Override
protected BaseDaoMapper<PromptTemplate> mapper() {
return promptTemplateMapper;
}
/**
* 保存新增对象。
*
* @param promptTemplate 新增对象。
* @return 返回新增对象。
*/
@Transactional(rollbackFor = Exception.class)
@Override
public PromptTemplate saveNew(PromptTemplate promptTemplate) {
promptTemplateMapper.insert(this.buildDefaultValue(promptTemplate));
return promptTemplate;
}
/**
* 利用数据库的insertList语法,批量插入对象列表。
*
* @param promptTemplateList 新增对象列表。
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void saveNewBatch(List<PromptTemplate> promptTemplateList) {
if (CollUtil.isNotEmpty(promptTemplateList)) {
promptTemplateList.forEach(this::buildDefaultValue);
promptTemplateMapper.insertList(promptTemplateList);
}
}
/**
* 更新数据对象。
*
* @param promptTemplate 更新的对象。
* @param originalPromptTemplate 原有数据对象。
* @return 成功返回true,否则false。
*/
@Transactional(rollbackFor = Exception.class)
@Override
public boolean update(PromptTemplate promptTemplate, PromptTemplate originalPromptTemplate) {
MyModelUtil.fillCommonsForUpdate(promptTemplate, originalPromptTemplate);
// 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
UpdateWrapper<PromptTemplate> uw = this.createUpdateQueryForNullValue(promptTemplate, promptTemplate.getTemplateId());
return promptTemplateMapper.update(promptTemplate, uw) == 1;
}
/**
* 删除指定数据。
*
* @param templateId 主键Id。
* @return 成功返回true,否则false。
*/
@Transactional(rollbackFor = Exception.class)
@Override
public boolean remove(Long templateId) {
return promptTemplateMapper.deleteById(templateId) == 1;
}
/**
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
* 如果需要同时获取关联数据,请移步(getPromptTemplateListWithRelation)方法。
*
* @param filter 过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
@Override
public List<PromptTemplate> getPromptTemplateList(PromptTemplate filter, String orderBy) {
return promptTemplateMapper.getPromptTemplateList(filter, orderBy);
}
/**
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
* 如果仅仅需要获取主表数据,请移步(getPromptTemplateList),以便获取更好的查询性能。
*
* @param filter 主表过滤对象。
* @param orderBy 排序参数。
* @return 查询结果集。
*/
@Override
public List<PromptTemplate> getPromptTemplateListWithRelation(PromptTemplate filter, String orderBy) {
List<PromptTemplate> resultList = promptTemplateMapper.getPromptTemplateList(filter, orderBy);
// 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
// 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
int batchSize = resultList instanceof Page ? 0 : 1000;
this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
return resultList;
}
/**
* 根据最新对象和原有对象的数据对比,判断关联的字典数据和多对一主表数据是否都是合法数据。
*
* @param promptTemplate 最新数据对象。
* @param originalPromptTemplate 原有数据对象。
* @return 数据全部正确返回true,否则false。
*/
@Override
public CallResult verifyRelatedData(PromptTemplate promptTemplate, PromptTemplate originalPromptTemplate) {
String errorMessageFormat = "数据验证失败,关联的%s并不存在,请刷新后重试!";
//这里是基于字典的验证。
if (this.needToVerify(promptTemplate, originalPromptTemplate, PromptTemplate::getTemplateSource)
&& !globalDictService.existDictItemFromCache("TemplateSourceLabel", promptTemplate.getTemplateSource())) {
return CallResult.error(String.format(errorMessageFormat, "模板来源"));
}
//这里是基于字典的验证。
if (this.needToVerify(promptTemplate, originalPromptTemplate, PromptTemplate::getScenarioType)
&& !globalDictService.existDictItemFromCache("ScenarioTypeLabel", promptTemplate.getScenarioType())) {
return CallResult.error(String.format(errorMessageFormat, "场景类型"));
}
//这里是基于字典的验证。
if (this.needToVerify(promptTemplate, originalPromptTemplate, PromptTemplate::getTemplateFramework)
&& !globalDictService.existDictItemFromCache("TemplateFrameworkLabel", promptTemplate.getTemplateFramework())) {
return CallResult.error(String.format(errorMessageFormat, "模板框架"));
}
return CallResult.ok();
}
private PromptTemplate buildDefaultValue(PromptTemplate promptTemplate) {
if (promptTemplate.getTemplateId() == null) {
promptTemplate.setTemplateId(idGenerator.nextLongId());
}
MyModelUtil.fillCommonsForInsert(promptTemplate);
promptTemplate.setDeletedFlag(GlobalDeletedFlag.NORMAL);
return promptTemplate;
}
}
package com.yice.webadmin.app.util;
import com.anji.captcha.service.CaptchaCacheService;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.TimeUnit;
/**
* Aj验证码 redis实现
*/
public class CaptchaCacheServiceRedisImpl implements CaptchaCacheService {
@Autowired
private RedissonClient redissonClient;
@Override
public String type() {
return "redis";
}
@Override
public void set(String key, String value, long expiresInSeconds) {
redissonClient.getBucket(key).set(value, expiresInSeconds, TimeUnit.SECONDS);
}
@Override
public boolean exists(String key) {
return redissonClient.getBucket(key).isExists();
}
@Override
public void delete(String key) {
redissonClient.getBucket(key).delete();
}
@Override
public String get(String key) {
return (String) redissonClient.getBucket(key).get();
}
@Override
public Long increment(String key, long val) {
RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
return atomicLong.addAndGet(val);
}
}
package com.yice.webadmin.app.vo;
import com.yice.common.core.base.vo.BaseVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.util.Map;
/**
* PromptTemplateVO视图对象。
*
* @author linking
* @date 2023-04-13
*/
@ApiModel("PromptTemplateVO视图对象")
@Data
@EqualsAndHashCode(callSuper = true)
public class PromptTemplateVo extends BaseVo {
/**
* 模板ID。
*/
@ApiModelProperty(value = "模板ID")
private Long templateId;
/**
* 模板名称。
*/
@ApiModelProperty(value = "模板名称")
private String templateName;
/**
* 模板标签。
*/
@ApiModelProperty(value = "模板标签")
private String templateLabel;
/**
* 浏览量。
*/
@ApiModelProperty(value = "浏览量")
private Long pageView;
/**
* 模板内容。
*/
@ApiModelProperty(value = "模板内容")
private String templateContent;
/**
* 模板来源。
*/
@ApiModelProperty(value = "模板来源")
private Integer templateSource;
/**
* 场景类型。
*/
@ApiModelProperty(value = "场景类型")
private Integer scenarioType;
/**
* 参数格式。
*/
@ApiModelProperty(value = "参数格式")
private String parameterFormat;
/**
* 接口地址。
*/
@ApiModelProperty(value = "接口地址")
private String interfaceAddress;
/**
* 模板框架。
*/
@ApiModelProperty(value = "模板框架")
private Integer templateFramework;
/**
* 变量列表。
*/
@ApiModelProperty(value = "变量列表")
private String variable;
/**
* templateSource 全局字典关联数据。
*/
@ApiModelProperty(value = "templateSource 全局字典关联数据")
private Map<String, Object> templateSourceDictMap;
/**
* scenarioType 全局字典关联数据。
*/
@ApiModelProperty(value = "scenarioType 全局字典关联数据")
private Map<String, Object> scenarioTypeDictMap;
/**
* templateFramework 全局字典关联数据。
*/
@ApiModelProperty(value = "templateFramework 全局字典关联数据")
private Map<String, Object> templateFrameworkDictMap;
}
package com.yice.webadmin.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 应用程序自定义的程序属性配置文件。
*
* @author linking
* @date 2023-04-13
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "application")
public class ApplicationConfig {
/**
* token的Http Request Header的key
*/
private String tokenHeaderKey;
/**
* token在过期之前,但是已经需要被刷新时,response返回的header信息的key。
*/
private String refreshedTokenHeaderKey;
/**
* token 加密用的密钥,该值的长度最少10个字符(过短会报错)。
*/
private String tokenSigningKey;
/**
* 令牌的过期时间,单位毫秒
*/
private Long expiration;
/**
* 用户密码被重置之后的缺省密码
*/
private String defaultUserPassword;
/**
* 上传文件的基础目录
*/
private String uploadFileBaseDir;
/**
* 授信ip列表,没有填写表示全部信任。多个ip之间逗号分隔,如: http://10.10.10.1:8080,http://10.10.10.2:8080
*/
private String credentialIpList;
/**
* Session的用户权限在Redis中的过期时间(秒)。
* 缺省值是 one day
*/
private int sessionExpiredSeconds = 86400;
/**
* 是否排他登录。
*/
private Boolean excludeLogin = false;
}
package com.yice.webadmin.config;
import com.yice.common.core.constant.ApplicationConstant;
import java.util.HashMap;
import java.util.Map;
/**
* 表示数据源类型的常量对象。
*
* @author linking
* @date 2023-04-13
*/
public final class DataSourceType {
public static final int MAIN = 0;
/**
* 以下所有数据源的类都型是固定值。如果有冲突,请修改上面定义的业务服务的数据源类型值。
*/
public static final int OPERATION_LOG = ApplicationConstant.OPERATION_LOG_DATASOURCE_TYPE;
public static final int COMMON_FLOW_AND_ONLINE = ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE;
public static final int COMMON_REPORT = ApplicationConstant.COMMON_REPORT_DATASOURCE_TYPE;
private static final Map<String, Integer> TYPE_MAP = new HashMap<>(8);
static {
TYPE_MAP.put("main", MAIN);
TYPE_MAP.put("operation-log", OPERATION_LOG);
TYPE_MAP.put("common-flow-online", COMMON_FLOW_AND_ONLINE);
TYPE_MAP.put("common-report", COMMON_REPORT);
}
/**
* 根据名称获取字典类型。
*
* @param name 数据源在配置中的名称。
* @return 返回可用于多数据源切换的数据源类型。
*/
public static Integer getDataSourceTypeByName(String name) {
return TYPE_MAP.get(name);
}
/**
* 私有构造函数,明确标识该常量类的作用。
*/
private DataSourceType() {
}
}
package com.yice.webadmin.config;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import javax.servlet.Filter;
import java.nio.charset.StandardCharsets;
/**
* 这里主要配置Web的各种过滤器和监听器等Servlet容器组件。
*
* @author linking
* @date 2023-04-13
*/
@Configuration
public class FilterConfig {
/**
* 配置Ajax跨域过滤器。
*/
@Bean
public CorsFilter corsFilterRegistration(ApplicationConfig applicationConfig) {
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
if (StringUtils.isNotBlank(applicationConfig.getCredentialIpList())) {
if ("*".equals(applicationConfig.getCredentialIpList())) {
corsConfiguration.addAllowedOriginPattern("*");
} else {
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
if (credentialIpList.length > 0) {
for (String ip : credentialIpList) {
corsConfiguration.addAllowedOrigin(ip);
}
}
}
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addExposedHeader(applicationConfig.getRefreshedTokenHeaderKey());
corsConfiguration.setAllowCredentials(true);
configSource.registerCorsConfiguration("/**", corsConfiguration);
}
return new CorsFilter(configSource);
}
@Bean
public FilterRegistrationBean<Filter> characterEncodingFilterRegistration() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>(
new org.springframework.web.filter.CharacterEncodingFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("encoding", StandardCharsets.UTF_8.name());
// forceEncoding强制response也被编码,另外即使request中已经设置encoding,forceEncoding也会重新设置
filterRegistrationBean.addInitParameter("forceEncoding", "true");
filterRegistrationBean.setAsyncSupported(true);
return filterRegistrationBean;
}
}
package com.yice.webadmin.config;
import com.yice.webadmin.interceptor.AuthenticationInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 所有的项目拦截器都在这里集中配置
*
* @author linking
* @date 2023-04-13
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/admin/**");
}
}
package com.yice.webadmin.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.yice.common.core.config.BaseMultiDataSourceConfig;
import com.yice.common.core.config.DynamicDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.mybatis.spring.annotation.MapperScan;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 多数据源配置对象。
*
* @author linking
* @date 2023-04-13
*/
@Configuration
@EnableTransactionManagement
@MapperScan(value = {"com.yice.webadmin.*.dao", "com.yice.common.*.dao"})
public class MultiDataSourceConfig extends BaseMultiDataSourceConfig {
@Bean(initMethod = "init", destroyMethod = "close")
@ConfigurationProperties(prefix = "spring.datasource.druid.main")
public DataSource mainDataSource() {
return super.applyCommonProps(DruidDataSourceBuilder.create().build());
}
/**
* 默认生成的用于保存操作日志的数据源,可根据需求修改。
* 这里我们还是非常推荐给操作日志使用独立的数据源,这样便于今后的数据迁移。
*/
@Bean(initMethod = "init", destroyMethod = "close")
@ConfigurationProperties(prefix = "spring.datasource.druid.operation-log")
public DataSource operationLogDataSource() {
return super.applyCommonProps(DruidDataSourceBuilder.create().build());
}
@Bean
@Primary
public DynamicDataSource dataSource() {
Map<Object, Object> targetDataSources = new HashMap<>(1);
targetDataSources.put(DataSourceType.MAIN, mainDataSource());
targetDataSources.put(DataSourceType.OPERATION_LOG, operationLogDataSource());
// 如果当前工程支持在线表单,这里请务必保证upms数据表所在数据库为缺省数据源。
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(mainDataSource());
return dynamicDataSource;
}
}
package com.yice.webadmin.config;
import cn.hutool.core.collection.CollUtil;
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 第三方应用鉴权配置。
*
* @author linking
* @date 2023-04-13
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "third-party")
public class ThirdPartyAuthConfig implements InitializingBean {
private List<AuthProperties> auth;
private Map<String, AuthProperties> applicationMap;
@Override
public void afterPropertiesSet() throws Exception {
if (CollUtil.isEmpty(auth)) {
applicationMap = new HashMap<>(1);
} else {
applicationMap = auth.stream().collect(Collectors.toMap(AuthProperties::getAppCode, c -> c));
}
}
@Data
public static class AuthProperties {
/**
* 应用Id。
*/
private String appCode;
/**
* 身份验证相关url的base地址。
*/
private String baseUrl;
/**
* 是否为橙单框架。
*/
private Boolean orangeFramework = true;
/**
* 数据权限和用户操作权限缓存过期时间,单位秒。
*/
private Integer permExpiredSeconds = 86400;
/**
* 用户Token缓存过期时间,单位秒。
* 如果为0,则每次都要去第三方服务进行验证。
*/
private Integer tokenExpiredSeconds = 0;
}
}
package com.yice.webadmin.upms.bo;
import lombok.Data;
import java.util.HashSet;
import java.util.Set;
/**
* 菜单相关的业务对象。
*
* @author linking
* @date 2023-04-13
*/
@Data
public class SysMenuPerm {
/**
* 菜单Id。
*/
private Long menuId;
/**
* 父菜单Id,目录菜单的父菜单为null
*/
private Long parentId;
/**
* 菜单显示名称。
*/
private String menuName;
/**
* 菜单类型 (0: 目录 1: 菜单 2: 按钮 3: UI片段)。
*/
private Integer menuType;
/**
* 在线表单主键Id,仅用于在线表单绑定的菜单。
*/
private Long onlineFormId;
/**
* 在线表单菜单的权限控制类型,具体值可参考SysOnlineMenuPermType常量对象。
*/
private Integer onlineMenuPermType;
/**
* 统计页面主键Id,仅用于统计页面绑定的菜单。
*/
private Long reportPageId;
/**
* 仅用于在线表单的流程Id。
*/
private Long onlineFlowEntryId;
/**
* 关联权限URL集合。
*/
Set<String> permUrlSet = new HashSet<>();
/**
* 关联的某一个url。
*/
String url;
}
package com.yice.webadmin.upms.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.core.object.*;
import com.yice.common.core.util.RedisKeyUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 在线用户控制器对象。
*
* @author linking
* @date 2023-04-13
*/
@Api(tags = "在线用户接口")
@Slf4j
@RestController
@RequestMapping("/admin/upms/loginUser")
public class LoginUserController {
@Autowired
private RedissonClient redissonClient;
/**
* 显示在线用户列表。
*
* @param loginName 登录名过滤。
* @param pageParam 分页参数。
* @return 登录用户信息列表。
*/
@PostMapping("/list")
public ResponseResult<MyPageData<LoginUserInfo>> list(
@MyRequestBody String loginName, @MyRequestBody MyPageParam pageParam) {
int skipCount = (pageParam.getPageNum() - 1) * pageParam.getPageSize();
String patternKey;
if (StrUtil.isBlank(loginName)) {
patternKey = RedisKeyUtil.getSessionIdPrefix() + "*";
} else {
patternKey = RedisKeyUtil.getSessionIdPrefix(loginName) + "*";
}
List<LoginUserInfo> loginUserInfoList = new LinkedList<>();
Iterable<String> keys = redissonClient.getKeys().getKeysByPattern(patternKey);
for (String key : keys) {
loginUserInfoList.add(this.buildTokenDataByRedisKey(key));
}
loginUserInfoList.sort((o1, o2) -> (int) (o2.getLoginTime().getTime() - o1.getLoginTime().getTime()));
int toIndex = Math.min(skipCount + pageParam.getPageSize(), loginUserInfoList.size());
List<LoginUserInfo> resultList = loginUserInfoList.subList(skipCount, toIndex);
return ResponseResult.success(new MyPageData<>(resultList, (long) loginUserInfoList.size()));
}
/**
* 强制下线指定登录会话。
*
* @param sessionId 待强制下线的SessionId。
* @return 应答结果对象。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody String sessionId) {
// 为了保证被剔除用户正在进行的操作不被干扰,这里只是删除sessionIdKey即可,这样可以使强制下线操作更加平滑。
// 比如,如果删除操作权限或数据权限的redis session key,那么正在请求数据的操作就会报错。
redissonClient.getBucket(RedisKeyUtil.makeSessionIdKey(sessionId)).delete();
return ResponseResult.success();
}
private LoginUserInfo buildTokenDataByRedisKey(String key) {
RBucket<String> sessionData = redissonClient.getBucket(key);
TokenData tokenData = JSON.parseObject(sessionData.get(), TokenData.class);
return BeanUtil.copyProperties(tokenData, LoginUserInfo.class);
}
}
package com.yice.webadmin.upms.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import io.swagger.annotations.Api;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.core.object.*;
import com.yice.common.core.util.MyModelUtil;
import com.yice.common.core.util.MyPageUtil;
import com.yice.common.log.model.SysOperationLog;
import com.yice.common.log.service.SysOperationLogService;
import com.yice.common.log.dto.SysOperationLogDto;
import com.yice.common.log.vo.SysOperationLogVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 操作日志接口控制器对象。
*
* @author linking
* @date 2023-04-13
*/
@Api(tags = "操作日志接口")
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysOperationLog")
public class SysOperationLogController {
@Autowired
private SysOperationLogService operationLogService;
/**
* 数据权限列表。
*
* @param sysOperationLogDtoFilter 操作日志查询过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象。包含操作日志列表。
*/
@PostMapping("/list")
public ResponseResult<MyPageData<SysOperationLogVo>> list(
@MyRequestBody SysOperationLogDto sysOperationLogDtoFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
SysOperationLog filter = MyModelUtil.copyTo(sysOperationLogDtoFilter, SysOperationLog.class);
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysOperationLog.class);
List<SysOperationLog> operationLogList = operationLogService.getSysOperationLogList(filter, orderBy);
List<SysOperationLogVo> operationLogVoList = MyModelUtil.copyCollectionTo(operationLogList, SysOperationLogVo.class);
long totalCount = 0L;
if (operationLogList instanceof Page) {
totalCount = ((Page<SysOperationLog>) operationLogList).getTotal();
}
return ResponseResult.success(MyPageUtil.makeResponseData(operationLogVoList, totalCount));
}
}
package com.yice.webadmin.upms.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import com.yice.webadmin.upms.dto.SysPermCodeDto;
import com.yice.webadmin.upms.vo.SysPermCodeVo;
import com.yice.webadmin.upms.model.SysPermCode;
import com.yice.webadmin.upms.service.SysPermCodeService;
import com.yice.common.core.constant.ErrorCodeEnum;
import com.yice.common.core.object.*;
import com.yice.common.core.util.*;
import com.yice.common.core.validator.UpdateGroup;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.log.annotation.OperationLog;
import com.yice.common.log.model.constant.SysOperationLogType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import javax.validation.groups.Default;
import java.util.*;
/**
* 权限字管理接口控制器类。
*
* @author linking
* @date 2023-04-13
*/
@Api(tags = "权限字管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysPermCode")
public class SysPermCodeController {
@Autowired
private SysPermCodeService sysPermCodeService;
/**
* 新增权限字操作。
*
* @param sysPermCodeDto 新增权限字对象。
* @param permIdListString 与当前权限Id绑定的权限资源Id列表,多个权限资源之间逗号分隔。
* @return 应答结果对象,包含新增权限字的主键Id。
*/
@ApiOperationSupport(ignoreParameters = {"sysPermCodeDto.permCodeId"})
@OperationLog(type = SysOperationLogType.ADD)
@PostMapping("/add")
public ResponseResult<Long> add(
@MyRequestBody SysPermCodeDto sysPermCodeDto, @MyRequestBody String permIdListString) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPermCodeDto);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED);
}
SysPermCode sysPermCode = MyModelUtil.copyTo(sysPermCodeDto, SysPermCode.class);
CallResult result = sysPermCodeService.verifyRelatedData(sysPermCode, null, permIdListString);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
}
Set<Long> permIdSet = null;
if (result.getData() != null) {
permIdSet = result.getData().getObject("permIdSet", new TypeReference<Set<Long>>(){});
}
sysPermCode = sysPermCodeService.saveNew(sysPermCode, permIdSet);
return ResponseResult.success(sysPermCode.getPermCodeId());
}
/**
* 更新权限字操作。
*
* @param sysPermCodeDto 更新权限字对象。
* @param permIdListString 与当前权限Id绑定的权限资源Id列表,多个权限资源之间逗号分隔。
* @return 应答结果对象。
*/
@OperationLog(type = SysOperationLogType.UPDATE)
@PostMapping("/update")
public ResponseResult<Void> update(
@MyRequestBody SysPermCodeDto sysPermCodeDto, @MyRequestBody String permIdListString) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPermCodeDto, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
SysPermCode originalSysPermCode = sysPermCodeService.getById(sysPermCodeDto.getPermCodeId());
if (originalSysPermCode == null) {
errorMessage = "数据验证失败,当前权限字并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
SysPermCode sysPermCode = MyModelUtil.copyTo(sysPermCodeDto, SysPermCode.class);
CallResult result = sysPermCodeService.verifyRelatedData(sysPermCode, originalSysPermCode, permIdListString);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
}
Set<Long> permIdSet = null;
if (result.getData() != null) {
permIdSet = result.getData().getObject("permIdSet", new TypeReference<Set<Long>>(){});
}
try {
if (!sysPermCodeService.update(sysPermCode, originalSysPermCode, permIdSet)) {
errorMessage = "数据验证失败,当前权限字并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
} catch (DuplicateKeyException e) {
errorMessage = "数据操作失败,权限字编码已经存在!";
return ResponseResult.error(ErrorCodeEnum.DUPLICATED_UNIQUE_KEY, errorMessage);
}
return ResponseResult.success();
}
/**
* 删除指定权限字操作。
*
* @param permCodeId 指定的权限字主键Id。
* @return 应答结果对象。
*/
@OperationLog(type = SysOperationLogType.DELETE)
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long permCodeId) {
if (MyCommonUtil.existBlankArgument(permCodeId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
String errorMessage;
if (sysPermCodeService.hasChildren(permCodeId)) {
errorMessage = "数据验证失败,当前权限字存在下级权限字!";
return ResponseResult.error(ErrorCodeEnum.HAS_CHILDREN_DATA, errorMessage);
}
if (!sysPermCodeService.remove(permCodeId)) {
errorMessage = "数据操作失败,权限字不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 查看权限字列表。
*
* @return 应答结果对象,包含权限字列表。
*/
@PostMapping("/list")
public ResponseResult<List<SysPermCodeVo>> list() {
List<SysPermCode> sysPermCodeList =
sysPermCodeService.getAllListByOrder("permCodeType", "showOrder");
return ResponseResult.success(MyModelUtil.copyCollectionTo(sysPermCodeList, SysPermCodeVo.class));
}
/**
* 查看权限字对象详情。
*
* @param permCodeId 指定权限字主键Id。
* @return 应答结果对象,包含权限字对象详情。
*/
@GetMapping("/view")
public ResponseResult<SysPermCodeVo> view(@RequestParam Long permCodeId) {
if (MyCommonUtil.existBlankArgument(permCodeId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
SysPermCode sysPermCode =
sysPermCodeService.getByIdWithRelation(permCodeId, MyRelationParam.full());
if (sysPermCode == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
SysPermCodeVo sysPermCodeVo = MyModelUtil.copyTo(sysPermCode, SysPermCodeVo.class);
return ResponseResult.success(sysPermCodeVo);
}
/**
* 查询权限字的用户列表。同时返回详细的分配路径。
*
* @param permCodeId 权限字Id。
* @param loginName 登录名。
* @return 应答对象。包含从权限字到用户的完整权限分配路径信息的查询结果列表。
*/
@GetMapping("/listSysUserWithDetail")
public ResponseResult<List<Map<String, Object>>> listSysUserWithDetail(Long permCodeId, String loginName) {
if (MyCommonUtil.isBlankOrNull(permCodeId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
return ResponseResult.success(sysPermCodeService.getSysUserListWithDetail(permCodeId, loginName));
}
/**
* 查询权限字的角色列表。同时返回详细的分配路径。
*
* @param permCodeId 权限字Id。
* @param roleName 角色名。
* @return 应答对象。包含从权限字到角色的权限分配路径信息的查询结果列表。
*/
@GetMapping("/listSysRoleWithDetail")
public ResponseResult<List<Map<String, Object>>> listSysRoleWithDetail(Long permCodeId, String roleName) {
if (MyCommonUtil.isBlankOrNull(permCodeId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
return ResponseResult.success(sysPermCodeService.getSysRoleListWithDetail(permCodeId, roleName));
}
}
package com.yice.webadmin.upms.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import com.yice.webadmin.upms.dto.SysPermDto;
import com.yice.webadmin.upms.vo.SysPermVo;
import com.yice.webadmin.upms.model.SysPerm;
import com.yice.webadmin.upms.service.SysPermService;
import com.yice.common.core.constant.ErrorCodeEnum;
import com.yice.common.core.object.*;
import com.yice.common.core.util.*;
import com.yice.common.core.validator.UpdateGroup;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.log.annotation.OperationLog;
import com.yice.common.log.model.constant.SysOperationLogType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.groups.Default;
import java.util.List;
import java.util.Map;
/**
* 权限资源管理接口控制器类。
*
* @author linking
* @date 2023-04-13
*/
@Api(tags = "权限资源管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysPerm")
public class SysPermController {
@Autowired
private SysPermService sysPermService;
/**
* 新增权限资源操作。
*
* @param sysPermDto 新增权限资源对象。
* @return 应答结果对象,包含新增权限资源的主键Id。
*/
@ApiOperationSupport(ignoreParameters = {"sysPermDto.permId"})
@OperationLog(type = SysOperationLogType.ADD)
@PostMapping("/add")
public ResponseResult<Long> add(@MyRequestBody SysPermDto sysPermDto) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPermDto);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
SysPerm sysPerm = MyModelUtil.copyTo(sysPermDto, SysPerm.class);
CallResult result = sysPermService.verifyRelatedData(sysPerm, null);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
}
sysPerm = sysPermService.saveNew(sysPerm);
return ResponseResult.success(sysPerm.getPermId());
}
/**
* 更新权限资源操作。
*
* @param sysPermDto 更新权限资源对象。
* @return 应答结果对象,包含更新权限资源的主键Id。
*/
@OperationLog(type = SysOperationLogType.UPDATE)
@PostMapping("/update")
public ResponseResult<Void> update(@MyRequestBody SysPermDto sysPermDto) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPermDto, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
SysPerm originalPerm = sysPermService.getById(sysPermDto.getPermId());
if (originalPerm == null) {
errorMessage = "数据验证失败,当前权限资源并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
SysPerm sysPerm = MyModelUtil.copyTo(sysPermDto, SysPerm.class);
CallResult result = sysPermService.verifyRelatedData(sysPerm, originalPerm);
if (!result.isSuccess()) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
}
sysPermService.update(sysPerm, originalPerm);
return ResponseResult.success();
}
/**
* 删除指定权限资源操作。
*
* @param permId 指定的权限资源主键Id。
* @return 应答结果对象。
*/
@OperationLog(type = SysOperationLogType.DELETE)
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long permId) {
if (MyCommonUtil.existBlankArgument(permId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
if (!sysPermService.remove(permId)) {
String errorMessage = "数据操作失败,权限不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 查看权限资源对象详情。
*
* @param permId 指定权限资源主键Id。
* @return 应答结果对象,包含权限资源对象详情。
*/
@GetMapping("/view")
public ResponseResult<SysPermVo> view(@RequestParam Long permId) {
if (MyCommonUtil.existBlankArgument(permId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
SysPerm perm = sysPermService.getById(permId);
if (perm == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
SysPermVo permVo = MyModelUtil.copyTo(perm, SysPermVo.class);
return ResponseResult.success(permVo);
}
/**
* 查看权限资源列表。
*
* @param sysPermDtoFilter 过滤对象。
* @param pageParam 分页参数。
* @return 应答结果对象,包含权限资源列表。
*/
@PostMapping("/list")
public ResponseResult<MyPageData<SysPermVo>> list(
@MyRequestBody SysPermDto sysPermDtoFilter, @MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
SysPerm filter = MyModelUtil.copyTo(sysPermDtoFilter, SysPerm.class);
List<SysPerm> permList = sysPermService.getPermListWithRelation(filter);
List<SysPermVo> permVoList = MyModelUtil.copyCollectionTo(permList, SysPermVo.class);
long totalCount = 0L;
if (permList instanceof Page) {
totalCount = ((Page<SysPerm>) permList).getTotal();
}
return ResponseResult.success(MyPageUtil.makeResponseData(permVoList, totalCount));
}
/**
* 查询权限资源地址的用户列表。同时返回详细的分配路径。
*
* @param permId 权限资源Id。
* @param loginName 登录名。
* @return 应答对象。包含从权限资源到用户的完整权限分配路径信息的查询结果列表。
*/
@GetMapping("/listSysUserWithDetail")
public ResponseResult<List<Map<String, Object>>> listSysUserWithDetail(Long permId, String loginName) {
if (MyCommonUtil.isBlankOrNull(permId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
return ResponseResult.success(sysPermService.getSysUserListWithDetail(permId, loginName));
}
/**
* 查询权限资源地址的角色列表。同时返回详细的分配路径。
*
* @param permId 权限资源Id。
* @param roleName 角色名。
* @return 应答对象。包含从权限资源到角色的权限分配路径信息的查询结果列表。
*/
@GetMapping("/listSysRoleWithDetail")
public ResponseResult<List<Map<String, Object>>> listSysRoleWithDetail(Long permId, String roleName) {
if (MyCommonUtil.isBlankOrNull(permId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
return ResponseResult.success(sysPermService.getSysRoleListWithDetail(permId, roleName));
}
/**
* 查询权限资源地址的菜单列表。同时返回详细的分配路径。
*
* @param permId 权限资源Id。
* @param menuName 菜单名。
* @return 应答对象。包含从权限资源到菜单的权限分配路径信息的查询结果列表。
*/
@GetMapping("/listSysMenuWithDetail")
public ResponseResult<List<Map<String, Object>>> listSysMenuWithDetail(Long permId, String menuName) {
if (MyCommonUtil.isBlankOrNull(permId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
return ResponseResult.success(sysPermService.getSysMenuListWithDetail(permId, menuName));
}
}
package com.yice.webadmin.upms.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import com.yice.webadmin.upms.dto.SysPermModuleDto;
import com.yice.webadmin.upms.vo.SysPermModuleVo;
import com.yice.webadmin.upms.model.SysPerm;
import com.yice.webadmin.upms.model.SysPermModule;
import com.yice.webadmin.upms.service.SysPermModuleService;
import com.yice.common.core.constant.ErrorCodeEnum;
import com.yice.common.core.object.*;
import com.yice.common.core.util.*;
import com.yice.common.core.validator.UpdateGroup;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.log.annotation.OperationLog;
import com.yice.common.log.model.constant.SysOperationLogType;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.groups.Default;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 权限资源模块管理接口控制器类。
*
* @author linking
* @date 2023-04-13
*/
@Api(tags = "权限资源模块管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysPermModule")
public class SysPermModuleController {
@Autowired
private SysPermModuleService sysPermModuleService;
/**
* 新增权限资源模块操作。
*
* @param sysPermModuleDto 新增权限资源模块对象。
* @return 应答结果对象,包含新增权限资源模块的主键Id。
*/
@ApiOperationSupport(ignoreParameters = {"sysPermModuleDto.moduleId"})
@OperationLog(type = SysOperationLogType.ADD)
@PostMapping("/add")
public ResponseResult<Long> add(@MyRequestBody SysPermModuleDto sysPermModuleDto) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPermModuleDto);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
SysPermModule sysPermModule = MyModelUtil.copyTo(sysPermModuleDto, SysPermModule.class);
if (sysPermModule.getParentId() != null
&& sysPermModuleService.getById(sysPermModule.getParentId()) == null) {
errorMessage = "数据验证失败,关联的上级权限模块并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_PARENT_ID_NOT_EXIST, errorMessage);
}
sysPermModuleService.saveNew(sysPermModule);
return ResponseResult.success(sysPermModule.getModuleId());
}
/**
* 更新权限资源模块操作。
*
* @param sysPermModuleDto 更新权限资源模块对象。
* @return 应答结果对象,包含新增权限资源模块的主键Id。
*/
@OperationLog(type = SysOperationLogType.UPDATE)
@PostMapping("/update")
public ResponseResult<Void> update(@MyRequestBody SysPermModuleDto sysPermModuleDto) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPermModuleDto, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
SysPermModule sysPermModule = MyModelUtil.copyTo(sysPermModuleDto, SysPermModule.class);
SysPermModule originalPermModule = sysPermModuleService.getById(sysPermModule.getModuleId());
if (originalPermModule == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
if (sysPermModule.getParentId() != null
&& !sysPermModule.getParentId().equals(originalPermModule.getParentId())
&& sysPermModuleService.getById(sysPermModule.getParentId()) == null) {
errorMessage = "数据验证失败,关联的上级权限模块并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_PARENT_ID_NOT_EXIST, errorMessage);
}
if (!sysPermModuleService.update(sysPermModule, originalPermModule)) {
errorMessage = "数据验证失败,当前模块并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 删除指定权限资源模块操作。
*
* @param moduleId 指定的权限资源模块主键Id。
* @return 应答结果对象。
*/
@OperationLog(type = SysOperationLogType.DELETE)
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long moduleId) {
if (MyCommonUtil.existBlankArgument(moduleId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
String errorMessage;
if (sysPermModuleService.hasChildren(moduleId)
|| sysPermModuleService.hasModulePerms(moduleId)) {
errorMessage = "数据验证失败,当前权限模块存在子模块或权限资源,请先删除关联数据!";
return ResponseResult.error(ErrorCodeEnum.HAS_CHILDREN_DATA, errorMessage);
}
if (!sysPermModuleService.remove(moduleId)) {
errorMessage = "数据操作失败,权限模块不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 查看全部权限资源模块列表。
*
* @return 应答结果对象,包含权限资源模块列表。
*/
@PostMapping("/list")
public ResponseResult<List<SysPermModuleVo>> list() {
List<SysPermModule> permModuleList = sysPermModuleService.getAllListByOrder("showOrder");
return ResponseResult.success(MyModelUtil.copyCollectionTo(permModuleList, SysPermModuleVo.class));
}
/**
* 列出全部权限资源模块及其下级关联的权限资源列表。
*
* @return 应答结果对象,包含树状列表,结构为权限资源模块和权限资源之间的树状关系。
*/
@PostMapping("/listAll")
public ResponseResult<List<Map<String, Object>>> listAll() {
List<SysPermModule> sysPermModuleList = sysPermModuleService.getPermModuleAndPermList();
List<Map<String, Object>> resultList = new LinkedList<>();
for (SysPermModule sysPermModule : sysPermModuleList) {
Map<String, Object> permModuleMap = new HashMap<>(5);
permModuleMap.put("id", sysPermModule.getModuleId());
permModuleMap.put("name", sysPermModule.getModuleName());
permModuleMap.put("type", sysPermModule.getModuleType());
permModuleMap.put("isPerm", false);
if (MyCommonUtil.isNotBlankOrNull(sysPermModule.getParentId())) {
permModuleMap.put("parentId", sysPermModule.getParentId());
}
resultList.add(permModuleMap);
if (CollectionUtils.isNotEmpty(sysPermModule.getSysPermList())) {
for (SysPerm sysPerm : sysPermModule.getSysPermList()) {
Map<String, Object> permMap = new HashMap<>(4);
permMap.put("id", sysPerm.getPermId());
permMap.put("name", sysPerm.getPermName());
permMap.put("isPerm", true);
permMap.put("url", sysPerm.getUrl());
permMap.put("parentId", sysPermModule.getModuleId());
resultList.add(permMap);
}
}
}
return ResponseResult.success(resultList);
}
}
package com.yice.webadmin.upms.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import com.github.pagehelper.page.PageMethod;
import com.yice.common.core.object.*;
import com.yice.common.core.util.*;
import com.yice.common.core.constant.*;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.core.validator.UpdateGroup;
import com.yice.webadmin.upms.dto.SysPostDto;
import com.yice.webadmin.upms.model.SysPost;
import com.yice.webadmin.upms.service.SysPostService;
import com.yice.webadmin.upms.vo.SysPostVo;
import com.yice.common.log.annotation.OperationLog;
import com.yice.common.log.model.constant.SysOperationLogType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import javax.validation.groups.Default;
/**
* 岗位管理操作控制器类。
*
* @author linking
* @date 2023-04-13
*/
@Api(tags = "岗位管理操作管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/upms/sysPost")
public class SysPostController {
@Autowired
private SysPostService sysPostService;
/**
* 新增岗位管理数据。
*
* @param sysPostDto 新增对象。
* @return 应答结果对象,包含新增对象主键Id。
*/
@ApiOperationSupport(ignoreParameters = {"sysPostDto.postId"})
@OperationLog(type = SysOperationLogType.ADD)
@PostMapping("/add")
public ResponseResult<Long> add(@MyRequestBody SysPostDto sysPostDto) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPostDto);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
SysPost sysPost = MyModelUtil.copyTo(sysPostDto, SysPost.class);
sysPost = sysPostService.saveNew(sysPost);
return ResponseResult.success(sysPost.getPostId());
}
/**
* 更新岗位管理数据。
*
* @param sysPostDto 更新对象。
* @return 应答结果对象。
*/
@OperationLog(type = SysOperationLogType.UPDATE)
@PostMapping("/update")
public ResponseResult<Void> update(@MyRequestBody SysPostDto sysPostDto) {
String errorMessage = MyCommonUtil.getModelValidationError(sysPostDto, Default.class, UpdateGroup.class);
if (errorMessage != null) {
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
}
SysPost sysPost = MyModelUtil.copyTo(sysPostDto, SysPost.class);
SysPost originalSysPost = sysPostService.getById(sysPost.getPostId());
if (originalSysPost == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!sysPostService.update(sysPost, originalSysPost)) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
return ResponseResult.success();
}
/**
* 删除岗位管理数据。
*
* @param postId 删除对象主键Id。
* @return 应答结果对象。
*/
@OperationLog(type = SysOperationLogType.DELETE)
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody Long postId) {
String errorMessage;
if (MyCommonUtil.existBlankArgument(postId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
// 验证关联Id的数据合法性
SysPost originalSysPost = sysPostService.getById(postId);
if (originalSysPost == null) {
// NOTE: 修改下面方括号中的话述
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
if (!sysPostService.remove(postId)) {
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
}
return ResponseResult.success();
}
/**
* 列出符合过滤条件的岗位管理列表。
*
* @param sysPostDtoFilter 过滤对象。
* @param orderParam 排序参数。
* @param pageParam 分页参数。
* @return 应答结果对象,包含查询结果集。
*/
@PostMapping("/list")
public ResponseResult<MyPageData<SysPostVo>> list(
@MyRequestBody SysPostDto sysPostDtoFilter,
@MyRequestBody MyOrderParam orderParam,
@MyRequestBody MyPageParam pageParam) {
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
SysPost sysPostFilter = MyModelUtil.copyTo(sysPostDtoFilter, SysPost.class);
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysPost.class);
List<SysPost> sysPostList = sysPostService.getSysPostListWithRelation(sysPostFilter, orderBy);
return ResponseResult.success(MyPageUtil.makeResponseData(sysPostList, SysPost.INSTANCE));
}
/**
* 查看指定岗位管理对象详情。
*
* @param postId 指定对象主键Id。
* @return 应答结果对象,包含对象详情。
*/
@GetMapping("/view")
public ResponseResult<SysPostVo> view(@RequestParam Long postId) {
if (MyCommonUtil.existBlankArgument(postId)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
SysPost sysPost = sysPostService.getByIdWithRelation(postId, MyRelationParam.full());
if (sysPost == null) {
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
SysPostVo sysPostVo = SysPost.INSTANCE.fromModel(sysPost);
return ResponseResult.success(sysPostVo);
}
/**
* 以字典形式返回全部岗位管理数据集合。字典的键值为[postId, postName]。
* 白名单接口,登录用户均可访问。
*
* @param filter 过滤对象。
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
*/
@GetMapping("/listDict")
public ResponseResult<List<Map<String, Object>>> listDict(SysPost filter) {
List<SysPost> resultList = sysPostService.getListByFilter(filter);
return ResponseResult.success(MyCommonUtil.toDictDataList(resultList, SysPost::getPostId, SysPost::getPostName));
}
/**
* 根据字典Id集合,获取查询后的字典数据。
*
* @param postIds 字典Id集合。
* @return 应答结果对象,包含字典形式的数据集合。
*/
@PostMapping("/listDictByIds")
public ResponseResult<List<Map<String, Object>>> listDictByIds(@MyRequestBody List<Long> postIds) {
List<SysPost> resultList = sysPostService.getInList(new HashSet<>(postIds));
return ResponseResult.success(MyCommonUtil.toDictDataList(resultList, SysPost::getPostId, SysPost::getPostName));
}
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysDataPermDept;
/**
* 数据权限与部门关系数据访问操作接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysDataPermDeptMapper extends BaseDaoMapper<SysDataPermDept> {
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysDataPerm;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 数据权限数据访问操作接口。
* NOTE: 该对象一定不能被 @EnableDataPerm 注解标注,否则会导致无限递归。
*
* @author linking
* @date 2023-04-13
*/
public interface SysDataPermMapper extends BaseDaoMapper<SysDataPerm> {
/**
* 获取数据权限列表。
*
* @param sysDataPermFilter 过滤对象。
* @param orderBy 排序字符串。
* @return 过滤后的数据权限列表。
*/
List<SysDataPerm> getSysDataPermList(
@Param("sysDataPermFilter") SysDataPerm sysDataPermFilter, @Param("orderBy") String orderBy);
/**
* 获取指定用户的数据权限列表。
*
* @param userId 用户Id。
* @return 数据权限列表。
*/
List<SysDataPerm> getSysDataPermListByUserId(@Param("userId") Long userId);
/**
* 查询与指定菜单关联的数据权限列表。
*
* @param menuId 菜单Id。
* @return 与菜单Id关联的数据权限列表。
*/
List<SysDataPerm> getSysDataPermListByMenuId(@Param("menuId") Long menuId);
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysDataPermMenu;
/**
* 数据权限与菜单关系数据访问操作接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysDataPermMenuMapper extends BaseDaoMapper<SysDataPermMenu> {
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysDataPermUser;
/**
* 数据权限与用户关系数据访问操作接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysDataPermUserMapper extends BaseDaoMapper<SysDataPermUser> {
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysDept;
import org.apache.ibatis.annotations.Param;
import java.util.*;
/**
* 部门管理数据操作访问接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysDeptMapper extends BaseDaoMapper<SysDept> {
/**
* 批量插入对象列表。
*
* @param sysDeptList 新增对象列表。
*/
void insertList(List<SysDept> sysDeptList);
/**
* 获取过滤后的对象列表。
*
* @param sysDeptFilter 主表过滤对象。
* @param orderBy 排序字符串,order by从句的参数。
* @return 对象列表。
*/
List<SysDept> getSysDeptList(
@Param("sysDeptFilter") SysDept sysDeptFilter, @Param("orderBy") String orderBy);
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysDeptPost;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 部门岗位数据操作访问接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysDeptPostMapper extends BaseDaoMapper<SysDeptPost> {
/**
* 获取指定部门Id的部门岗位多对多关联数据列表,以及关联的部门和岗位数据。
*
* @param deptId 部门Id。如果参数为空则返回全部数据。
* @return 部门岗位多对多数据列表。
*/
List<Map<String, Object>> getSysDeptPostListWithRelationByDeptId(@Param("deptId") Long deptId);
/**
* 获取指定部门Id的领导部门岗位列表。
*
* @param deptId 部门Id。
* @return 指定部门Id的领导部门岗位列表
*/
List<SysDeptPost> getLeaderDeptPostList(@Param("deptId") Long deptId);
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysDeptRelation;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 部门关系树关联关系表访问接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysDeptRelationMapper extends BaseDaoMapper<SysDeptRelation> {
/**
* 将myDeptId的所有子部门,与其父部门parentDeptId解除关联关系。
*
* @param parentDeptIds myDeptId的父部门Id列表。
* @param myDeptId 当前部门。
*/
void removeBetweenChildrenAndParents(
@Param("parentDeptIds") List<Long> parentDeptIds, @Param("myDeptId") Long myDeptId);
/**
* 批量插入部门关联数据。
* 由于目前版本(3.4.1)的Mybatis Plus没有提供真正的批量插入,为了保证效率需要自己实现。
* 目前我们仅仅给出MySQL和PostgresSQL的insert list实现作为参考,其他数据库需要自行修改。
*
* @param deptRelationList 部门关联关系数据列表。
*/
void insertList(List<SysDeptRelation> deptRelationList);
/**
* 批量插入当前部门的所有父部门列表,包括自己和自己的关系。
*
* @param parentDeptId myDeptId的父部门Id。
* @param myDeptId 当前部门。
*/
void insertParentList(@Param("parentDeptId") Long parentDeptId, @Param("myDeptId") Long myDeptId);
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysMenuPermCode;
/**
* 菜单与权限字关系数据访问操作接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysMenuPermCodeMapper extends BaseDaoMapper<SysMenuPermCode> {
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysPermCodePerm;
/**
* 权限字与权限资源关系数据访问操作接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysPermCodePermMapper extends BaseDaoMapper<SysPermCodePerm> {
}
package com.yice.webadmin.upms.dao;
import com.yice.common.core.base.dao.BaseDaoMapper;
import com.yice.webadmin.upms.model.SysPermWhitelist;
/**
* 权限资源白名单数据访问操作接口。
*
* @author linking
* @date 2023-04-13
*/
public interface SysPermWhitelistMapper extends BaseDaoMapper<SysPermWhitelist> {
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment