110
社区成员
发帖
与我相关
我的任务
分享在 application-dev.yml 文件中,有这么一段 swagger 相关的代码
#是否开启 swagger-ui
swagger:
enabled: true
title: 管理后台API
serverUrl: http://127.0.0.1:8000
version: 2.2
在 IDEA 中,用查找用法搜索 swagger ,可以找到一个叫 SecurityConfig 的类,类中有这么一段 swagger 相关的代码:
// swagger 文档
.antMatchers("/swagger-ui.html").permitAll()
.antMatchers("/swagger-resources/**").permitAll()
.antMatchers("/webjars/**").permitAll()
.antMatchers("/*/api-docs").permitAll()
.antMatchers("/v2/api-docs-ext").permitAll()
//.antMatchers("/api/wxmp/**").permitAll()
按照代码的设置,先启动项目,再访问 localhost:8000/swagger-ui.html,可成功访问,效果如图:

将 AuthController 类中的相关代码编辑为如下:
// 保存
redisUtils.set(uuid, result, expiration, TimeUnit.HOURS);
这样,验证码的失效时间就变为了 1 小时(原为 1 分钟)
在 swagger 页面,系统:系统授权接口 -> try it out -> excute
获取到的响应如下:
{
"uuid": "code-key050d4698495246588e6f46c50a87bf2c",
"img": "data:image/png;base64,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"
这其中,uuid 后面的字符串是 uuid,img 后面的字符串是验证码图片的 base64 码,需要转化成图像。
专门写一个 html 文件,用于将 base64 格式的图片编码转化为图像吗,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>我的前端练习</title>
</head>
<body>
<div>我的前端练习--二进制流图片及RSA加密</div>
<img src=""></img>
</body>
</html>
其中,src 是要转为图片的 base64 码,将刚刚的base64 码填进去,再打开 HTML 页面。
可得到验证码图片:

在刚刚的 html 文件中,添加 RSA 加密的相关脚本:
<!--引入jsencrypt.js-->
<script src="https://cdn.bootcss.com/jsencrypt/3.0.0-beta.1/jsencrypt.js"></script>
<script type="text/javascript">
//公钥
var PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD\n' +
'2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ=='
//私钥
var PRIVATE_KEY = 'data:image/png;base64,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'
//使用公钥加密
var encrypt = new JSEncrypt();
//encrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----'+PRIVATE_KEY+'-----END RSA PRIVATE KEY-----');
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + PUBLIC_KEY + '-----END PUBLIC KEY-----');
var encrypted = encrypt.encrypt("123456");
console.log('加密前数据:%o', "");
console.log('加密后数据:%o', encrypted);
//使用私钥解密
//var decrypt = new JSEncrypt();
//decrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + PUBLIC_KEY + '-----END PUBLIC KEY-----');
//decrypt.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----'+PRIVATE_KEY+'-----END RSA PRIVATE KEY-----');
//var uncrypted = decrypt.decrypt(encrypted);
//console.log('解密后数据:%o', uncrypted);
</script>
添加后,在加密前数据后面填写原本的密码。完成后启动浏览器,在控制台可以获取 RSA 加密后的密码。

打开登录接口,然后 try it out:

在 addUser 中,把后面的内容填上,如下:
{
"code": "4",
"password": "dqzr75SJUPUL0MERjBerOHRsRMJRaT27mNIwQL2igJ2G/EB1VdJZ83gesfmwHEBfGGlC51b8LuT6qbXpm81P8w==",
"username": "admin",
"uuid": "code-key050d4698495246588e6f46c50a87bf2c"
}
填写完毕后点击 excute,即可获得一个响应,内容如下:
{
"user": {
"id": 1,
"username": "admin",
"nickName": "管理员",
"sex": "男",
"avatar": null,
"email": "yshop@qq.com",
"phone": "18888888888",
"dept": "研发部",
"job": "全栈开发2",
"enabled": true,
"createTime": 1534986716000,
"roles": [
"YXUSER_SELECT",
"YXSTOREORDER_SELECT",
"YXSTORECOMBINATION_SELECT",
"YXSTORESECKILL_SELECT",
"YXSYSTEMUSERLEVEL_SELECT",
"YXSTORECATEGORY_SELECT",
"admin",
"YXSTOREBARGAIN_SELECT",
"YXSTOREPRODUCT_EDIT",
"YXSTORECOUPONISSUE_SELECT",
"storage:list",
"YXSTOREPRODUCT_CREATE",
"YXSTOREPRODUCTREPLY_SELECT",
"YXEXPRESS_SELECT",
"YXSTOREPRODUCT_SELECT",
"admin,menu:list,roles:list",
"YXSYSTEMUSERTASK_SELECT",
"timing:list",
"YXSTOREPRODUCT_DELETE",
"YXSTORECOUPON_SELECT"
]
},
"token": "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImF1dGgiOiJZWFVTRVJfU0VMRUNULFlYU1RPUkVPUkRFUl9TRUxFQ1QsWVhTVE9SRUNPTUJJTkFUSU9OX1NFTEVDVCxZWFNUT1JFU0VDS0lMTF9TRUxFQ1QsWVhTWVNURU1VU0VSTEVWRUxfU0VMRUNULFlYU1RPUkVDQVRFR09SWV9TRUxFQ1QsYWRtaW4sWVhTVE9SRUJBUkdBSU5fU0VMRUNULFlYU1RPUkVQUk9EVUNUX0VESVQsWVhTVE9SRUNPVVBPTklTU1VFX1NFTEVDVCxzdG9yYWdlOmxpc3QsWVhTVE9SRVBST0RVQ1RfQ1JFQVRFLFlYU1RPUkVQUk9EVUNUUkVQTFlfU0VMRUNULFlYRVhQUkVTU19TRUxFQ1QsWVhTVE9SRVBST0RVQ1RfU0VMRUNULGFkbWluLG1lbnU6bGlzdCxyb2xlczpsaXN0LFlYU1lTVEVNVVNFUlRBU0tfU0VMRUNULHRpbWluZzpsaXN0LFlYU1RPUkVQUk9EVUNUX0RFTEVURSxZWFNUT1JFQ09VUE9OX1NFTEVDVCIsImV4cCI6MTY0MjUxMjQ2OH0.TxPFNiFuQdETy4t5Ax5-j_9ZuB2TEn3vYinZOUgI3B7jHvfXotxETLqUJOB78o6n3Z1UrzOvYtuT1iTxn2mIxw"
}
说明登录成功,并且成功拿到了 token。
拿到 token 之后,就可以访问其他接口了,以获取用户信息为例。
进入 系统:系统授权接口,点击 try it out

在 Authorization 栏内填入刚刚的 token:

点击 excute,即可获得用户信息:

/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 80015
Source Host : 127.0.0.1:3306
Source Database : lab_mall_db
Target Server Type : MYSQL
Target Server Version : 80015
File Encoding : 65001
Date: 2022-01-18 20:26:43
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for myinfo
-- ----------------------------
DROP TABLE IF EXISTS `xxminfo`;
CREATE TABLE `xxminfo` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '我的ID',
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '我的姓名',
`remark` varchar(2000) DEFAULT NULL COMMENT '我的备注',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '最后修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='我的信息';
-- ----------------------------
-- Records of myinfo
-- ----------------------------
INSERT INTO `xxminfo` VALUES ('1', '嘘嘘喵', '备注1', '2022年1月19日15:37:52', '2022年1月19日15:37:55');
INSERT INTO `xxminfo` VALUES ('2', '嘘嘘喵22', '备注222', '2022年1月19日15:38:02', '2022年1月19日15:37:59');
项目直接沿用前面的项目,在 yshop-system 模块,/src/main/java/co.yixiang/modules 下创建文件夹 xxm ,以用作这次练习。
创建好三个文件夹:

domain :用于存放实体类
在 domain 文件夹下创建一个类 XxmInfo ,内容如下:
package co.yixiang.modules.xxm.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.security.Timestamp;
/**
* @author: xxm
* @Date: 2022/1/19 16:49
* xxminfo 表对应的实体类
*/
@Data
@TableName("xxminfo")
public class XxmInfo implements Serializable {
/**
* ID
*/
@TableId
private long id;
/**
* 姓名
*/
@NotBlank(message = "姓名不能为空")
private String name;
/**
* 备注
*/
private String remark;
/**
* 创建日期(自动填充)
*/
@TableField(fill = FieldFill.INSERT)
private Timestamp createTime;
/**
* 最后修改日期(自动填充)
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Timestamp updateTime;
}
在 dto 文件夹中创建一个新类:XxmInfoDto
答:
package co.yixiang.modules.xxm.service.dto;
import java.security.Timestamp;
/**
* @author: xxm
* @Date: 2022/1/20 10:56
* Dto类,一般用于与前端交互
*/
public class XxmInfoDto {
/**
* ID
*/
private long id;
/**
* 姓名
*/
private String name;
/**
* 备注
*/
private String remark;
/**
* 创建日期(自动填充)
*/
private Timestamp createTime;
/**
* 最后修改日期(自动填充)
*/
private Timestamp updateTime;
}
在 rest 文件夹下创建类 XxmInfoCrontroller。
内容如下:
package co.yixiang.modules.xxm.rest;
import co.yixiang.logging.aop.log.Log;
import co.yixiang.modules.xxm.service.XxmInfoService;
import co.yixiang.modules.xxm.service.dto.XxmInfoQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: xxm
* @Date: 2022/1/19 18:52
* xxminfo 接口
*/
@Api(tags = "xxm:用户信息")
@RestController
@RequestMapping("/api/xxminfo")
public class XxmInfoController {
private final XxmInfoService xxmInfoService;
public XxmInfoController(XxmInfoService xxmInfoService){
this.xxmInfoService = xxmInfoService;
}
/**
* 查询用户信息
*/
@Log("查询用户信息")
@ApiOperation("查询用户信息")
@GetMapping(value = "/all")
@PreAuthorize("@el.check('admin','xxminfo:list')")
public ResponseEntity<Object> all() {
return new ResponseEntity<>(xxmInfoService.queryAll(new XxmInfoQueryCriteria()), HttpStatus.OK);
}
}
在 service 文件夹下创建 dto 文件夹,并创建 XxmInfoQueryCriteria 类。
代码如下:
package co.yixiang.modules.xxm.service.dto;
import co.yixiang.annotation.Query;
import lombok.Data;
/**
* @author: xxm
* @Date: 2022/1/19 21:05
* 查询条件
*/
@Data
public class XxmInfoQueryCriteria {
@Query
private String name;
}
在 service 文件夹下创建 mapper 文件夹,并创建 XxmInfoMapper 类。
代码如下:
package co.yixiang.modules.xxm.service.mapper;
import co.yixiang.common.mapper.CoreMapper;
import co.yixiang.modules.xxm.domain.XxmInfo;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* @author: xxm
* @Date: 2022/1/19 21:28
* xxminfo 的 mapper 接口
*/
@Repository
@Mapper
public interface XxmInfoMapper extends CoreMapper<XxmInfo> {
}
创建 XxmInfoService 类,作为接口。
代码如下:
package co.yixiang.modules.xxm.service;
import co.yixiang.common.service.BaseService;
import co.yixiang.modules.my.service.dto.MyInfoQueryCriteria;
import co.yixiang.modules.xxm.domain.XxmInfo;
import co.yixiang.modules.xxm.service.dto.XxmInfoDto;
import co.yixiang.modules.xxm.service.dto.XxmInfoQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
/**
* @author: xxm
* @Date: 2022/1/19 20:08
* xxminfo 的 service 接口
*/
public interface XxmInfoService extends BaseService<XxmInfo> {
List<XxmInfoDto> queryAll(XxmInfoQueryCriteria criteria);
}
在 service 文件夹下创建 dto 文件夹,并创建 XxmInfoServiceImpl 类。
代码如下:
package co.yixiang.modules.xxm.service.impl;
import co.yixiang.common.service.impl.BaseServiceImpl;
import co.yixiang.common.utils.QueryHelpPlus;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.modules.xxm.domain.XxmInfo;
import co.yixiang.modules.xxm.service.XxmInfoService;
import co.yixiang.modules.xxm.service.dto.XxmInfoDto;
import co.yixiang.modules.xxm.service.dto.XxmInfoQueryCriteria;
import co.yixiang.modules.xxm.service.mapper.XxmInfoMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author: xxm
* @Date: 2022/1/19 21:11
*/
@Service
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class XxmInfoServiceImpl extends BaseServiceImpl<XxmInfoMapper, XxmInfo> implements XxmInfoService {
private final IGenerator generator;
// @Override
// public Map<String, Object> queryAll(MyInfoQueryCriteria criteria, Pageable pageable) {
// getPage(pageable);
// PageInfo page = new PageInfo(queryAll(criteria));
// Map<String, Object> map = new LinkedHashMap<>(2);
// map.put("content", generator.convert(page.getList(), XxmInfoDto.class));
// map.put("totalElements", page.getTotal());
// return map;
// }
@Override
public List<XxmInfoDto> queryAll(XxmInfoQueryCriteria criteria) {
return baseMapper.selectList(QueryHelpPlus.getPredicate(XxmInfoDto.class, criteria));
}
}
在 swagger 中 ,访问 xxm:用户信息接口,执行后可以得到响应:

按照第三章中的内容,给项目添加增、删、改的功能。
过程忽略,这边直接放上编辑过后的代码:
package co.yixiang.modules.xxm.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.security.Timestamp;
import java.util.Date;
/**
* @author: xxm
* @Date: 2022/1/19 16:49
* xxminfo 表对应的实体类
*/
@Data
@TableName("xxminfo")
public class XxmInfo implements Serializable {
/**
* ID
*/
@TableId
private Long id;
/**
* 姓名
*/
@NotBlank(message = "姓名不能为空")
private String name;
/**
* 备注
*/
private String remark;
/**
* 创建日期(自动填充)
*/
@TableField(fill= FieldFill.INSERT)
private Date createTime;
/**
* 最后修改日期(自动填充)
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
package co.yixiang.modules.xxm.service.dto;
import java.security.Timestamp;
/**
* @author: xxm
* @Date: 2022/1/20 10:56
* Dto类,一般用于与前端交互
*/
public class XxmInfoDto {
/**
* ID
*/
private long id;
/**
* 姓名
*/
private String name;
/**
* 备注
*/
private String remark;
/**
* 创建日期(自动填充)
*/
private Timestamp createTime;
/**
* 最后修改日期(自动填充)
*/
private Timestamp updateTime;
}
package co.yixiang.modules.xxm.rest;
import co.yixiang.exception.BadRequestException;
import co.yixiang.logging.aop.log.Log;
import co.yixiang.modules.xxm.domain.XxmInfo;
import co.yixiang.modules.xxm.service.XxmInfoService;
import co.yixiang.modules.xxm.service.dto.XxmInfoQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author: xxm
* @Date: 2022/1/19 18:52
* xxminfo 接口
*/
@Api(tags = "xxm:用户信息")
@RestController
@RequestMapping("/api/xxminfo")
public class XxmInfoController {
private final XxmInfoService xxmInfoService;
public static final String ENTITY_NAME = "xxminfo";
public XxmInfoController(XxmInfoService xxmInfoService){
this.xxmInfoService = xxmInfoService;
}
/**
* 查询用户信息
*/
@Log("查询全部用户信息")
@ApiOperation("查询全部用户信息")
@GetMapping(value = "/all")
@PreAuthorize("@el.check('admin','xxminfo:list')")
public ResponseEntity<Object> all() {
return new ResponseEntity<>(xxmInfoService.queryAll(new XxmInfoQueryCriteria()), HttpStatus.OK);
}
// @Log("查询字典")
// @ApiOperation("查询字典")
// @GetMapping
// @PreAuthorize("@el.check('admin','dict:list')")
// public ResponseEntity<Object> getDicts(DictQueryCriteria resources, Pageable pageable) {
// return new ResponseEntity<>(dictService.queryAll(resources, pageable), HttpStatus.OK);
// }
//
@Log("新增用户")
@ApiOperation("新增用户")
@PostMapping
@PreAuthorize("@el.check('admin','xxminfo:add')")
public ResponseEntity<Object> create(@Validated @RequestBody XxmInfo resources) {
if (resources.getId() != null) {
throw new BadRequestException("A new " + ENTITY_NAME + " cannot already have an ID");
}
return new ResponseEntity<>(xxmInfoService.save(resources), HttpStatus.CREATED);
}
@Log("修改用户信息")
@ApiOperation("修改用户信息")
@PutMapping
@PreAuthorize("@el.check('admin','xxminfo:edit')")
public ResponseEntity<Object> update(@Validated @RequestBody XxmInfo resources) {
xxmInfoService.saveOrUpdate(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除用户")
@ApiOperation("删除用户")
@DeleteMapping(value = "/{id}")
@PreAuthorize("@el.check('admin','xxminfo:del')")
public ResponseEntity<Object> delete(@PathVariable Long id) {
xxmInfoService.removeById(id);
return new ResponseEntity<>(HttpStatus.OK);
}
}
package co.yixiang.modules.xxm.service.dto;
import co.yixiang.annotation.Query;
import lombok.Data;
/**
* @author: xxm
* @Date: 2022/1/19 21:05
* 查询条件
*/
@Data
public class XxmInfoQueryCriteria {
@Query
private String name;
}
package co.yixiang.modules.xxm.service.mapper;
import co.yixiang.common.mapper.CoreMapper;
import co.yixiang.modules.xxm.domain.XxmInfo;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* @author: xxm
* @Date: 2022/1/19 21:28
* xxminfo 的 mapper 接口
*/
@Repository
@Mapper
public interface XxmInfoMapper extends CoreMapper<XxmInfo> {
}
package co.yixiang.modules.xxm.service;
import co.yixiang.common.service.BaseService;
import co.yixiang.modules.my.service.dto.MyInfoQueryCriteria;
import co.yixiang.modules.xxm.domain.XxmInfo;
import co.yixiang.modules.xxm.service.dto.XxmInfoDto;
import co.yixiang.modules.xxm.service.dto.XxmInfoQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
/**
* @author: xxm
* @Date: 2022/1/19 20:08
* xxminfo 的 service 接口
*/
public interface XxmInfoService extends BaseService<XxmInfo> {
// /**
// * 查询数据分页
// *
// * @param criteria 条件
// * @param pageable 分页参数
// * @return Map<String, Object>
// */
// Map<String, Object> queryAll(MyInfoQueryCriteria criteria, Pageable pageable);
/**
* 查询
*
* @param criteria
* @return
*/
List<XxmInfoDto> queryAll(XxmInfoQueryCriteria criteria);
/**
* 新增用户
*
* @param xxmInfo
*/
XxmInfoDto create(XxmInfo xxmInfo);
/**
* 编辑用户信息
*
* @param xxmInfo
*/
void update(XxmInfo xxmInfo);
// /**
// * 删除用户信息
// *
// * @param xxmInfo
// */
// void delete(XxmInfo xxmInfo);
}
package co.yixiang.modules.xxm.service.impl;
import co.yixiang.common.service.impl.BaseServiceImpl;
import co.yixiang.common.utils.QueryHelpPlus;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.exception.EntityExistException;
import co.yixiang.modules.xxm.domain.XxmInfo;
import co.yixiang.modules.xxm.service.XxmInfoService;
import co.yixiang.modules.xxm.service.dto.XxmInfoDto;
import co.yixiang.modules.xxm.service.dto.XxmInfoQueryCriteria;
import co.yixiang.modules.xxm.service.mapper.XxmInfoMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author: xxm
* @Date: 2022/1/19 21:11
*/
@Service
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class XxmInfoServiceImpl extends BaseServiceImpl<XxmInfoMapper, XxmInfo> implements XxmInfoService {
private final IGenerator generator;
// @Override
// public Map<String, Object> queryAll(MyInfoQueryCriteria criteria, Pageable pageable) {
// getPage(pageable);
// PageInfo page = new PageInfo(queryAll(criteria));
// Map<String, Object> map = new LinkedHashMap<>(2);
// map.put("content", generator.convert(page.getList(), XxmInfoDto.class));
// map.put("totalElements", page.getTotal());
// return map;
// }
/**
* 查询所有用户信息
*
* @param criteria
* @return
*/
@Override
public List<XxmInfoDto> queryAll(XxmInfoQueryCriteria criteria) {
return baseMapper.selectList(QueryHelpPlus.getPredicate(XxmInfoDto.class, criteria));
}
/**
* 增加用户
*
* @param resources
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public XxmInfoDto create(XxmInfo resources) {
if (this.getOne(new QueryWrapper<XxmInfo>().lambda().eq(XxmInfo::getName, resources.getName())) != null) {
throw new EntityExistException(XxmInfo.class, "username", resources.getName());
}
this.save(resources);
return generator.convert(resources, XxmInfoDto.class);
}
/**
* 修改用户信息
*
* @param resources
*/
@Override
public void update(XxmInfo resources) {
XxmInfo xxm1 = this.getById(resources.getId());
XxmInfo xxm2 = this.getOne(new QueryWrapper<XxmInfo>().lambda().eq(XxmInfo::getName, resources.getName()));
if (xxm2 != null && !xxm2.getId().equals(xxm1.getId())) {
throw new EntityExistException(XxmInfo.class, "username", resources.getName());
}
xxm2 = this.getOne(new QueryWrapper<XxmInfo>().lambda().eq(XxmInfo::getName, resources.getName()));
if (xxm2 != null && xxm2.getId().equals(xxm1.getId())) {
throw new EntityExistException(XxmInfo.class, "username", resources.getName());
}
xxm1.setName(resources.getName());
xxm1.setRemark(resources.getRemark());
this.saveOrUpdate(xxm1);
}
//
// /**
// * 删除用户
// * @param xxmInfo
// */
// @Override
// public void delete(XxmInfo xxmInfo) {
//
// }
}