feat:审批

This commit is contained in:
dzc committed 2025-01-12 20:50:10 +08:00
1 parent 15509313fc
commit 01b0623913
40 files changed
+1354 -575

No files matched your search

+2
View File
@@ -188,6 +188,8 @@ CREATE TABLE wallet_recharge_apply
(
id bigint NOT NULL COMMENT '主键ID',
user_id bigint NOT NULL COMMENT '申请人ID',
process_id varchar(256) COMMENT '流程id',
process_status varchar(10) COMMENT '审核状体',
biz_type tinytext DEFAULT NULL COMMENT '充值类型',
wallet_type_id bigint DEFAULT NULL COMMENT '饭卡类型id',
dept_id bigint NOT NULL COMMENT '部门ID',
@@ -0,0 +1,32 @@
package com.bsd.pjcloud.flow.task.dto.base;
import lombok.Data;
@Data
public class FlowBaseDto {
/**
* 发起人
*/
private String applyUsername;
/**
* 发起人id
*/
private Long applyUserId;
/**
* 发起人部门
*/
private String applyDeptName;
/**
* 发起人部门id
*/
private Long applyDeptId;
/**
* 发起时间
*/
private String applyCreateTime;
}
@@ -5,7 +5,9 @@ import cn.hutool.core.util.ObjectUtil;
import com.bsd.pjcloud.admin.api.entity.SysDept;
import com.bsd.pjcloud.admin.api.entity.SysMenu;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.vo.SysUserFaceVo;
import com.bsd.pjcloud.admin.api.vo.base.BaseDeptInterface;
import com.bsd.pjcloud.admin.api.vo.base.BaseFacesInterface;
import com.bsd.pjcloud.admin.api.vo.base.BaseUserInterface;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import lombok.experimental.UtilityClass;
@@ -115,4 +117,14 @@ public class DataUtil {
return v;
}
public <T extends BaseFacesInterface> List<T> convertFacesList(List<T> list, Map<Long, SysUserFaceVo> map) {
return CollectionUtils.convertList(list, entity -> convertFaces(entity, map.get(entity.getUserId())));
}
public <T extends BaseFacesInterface> T convertFaces(T v, SysUserFaceVo dept) {
if (ObjectUtil.isEmpty(dept)) return v;
v.setFaceImgs(dept.getFaceImgs());
return v;
}
}
@@ -8,6 +8,11 @@ import lombok.Data;
@Data
public class SysUserFaceVo extends SysUserFaceEntity implements BaseUserInterface, BaseDeptInterface {
/**
* 人脸图片
*/
private String faceImgs;
/**
* 用户相关
*/
@@ -0,0 +1,47 @@
package com.bsd.pjcloud.admin.api.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.bsd.pjcloud.common.excel.annotation.ExcelLine;
import lombok.Data;
@Data
@ColumnWidth(30)
public class UserExcelFaceVo {
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 账号登录名没有就用手机号
*/
@ExcelProperty("用户名称")
private String username;
/**
* 用户真实姓名
*/
@ExcelProperty("用户昵称")
private String name;
/**
* 部门名称
*/
@ExcelProperty("部门名称")
private String deptName;
/**
* 手机号码
*/
@ExcelProperty("手机号码")
private String mobile;
/**
* 用户性别
*/
@ExcelProperty("用户性别")
private String sex;
}
@@ -19,6 +19,7 @@
package com.bsd.pjcloud.admin.api.vo;
import com.bsd.pjcloud.admin.api.vo.base.BaseFacesInterface;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.bsd.pjcloud.admin.api.entity.SysPost;
import com.bsd.pjcloud.admin.api.entity.SysRole;
@@ -37,169 +38,173 @@ import java.util.List;
*/
@Data
@Schema(description = "前端用户展示对象")
public class UserVO implements Serializable {
public class UserVO implements BaseFacesInterface, Serializable {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@Schema(description = "主键")
private Long userId;
/**
* 主键ID
*/
@Schema(description = "主键")
private Long userId;
/**
* 用户名
*/
@Schema(description = "用户名")
private String username;
/**
* 用户名
*/
@Schema(description = "用户名")
private String username;
/**
* 密码
*/
@JsonIgnore
private String password;
/**
* 密码
*/
@JsonIgnore
private String password;
/**
* 随机盐
*/
@JsonIgnore
private String salt;
/**
* 随机盐
*/
@JsonIgnore
private String salt;
/**
* 微信openid
*/
@Schema(description = "微信open id")
private String wxOpenid;
/**
* 微信openid
*/
@Schema(description = "微信open id")
private String wxOpenid;
/**
* QQ openid
*/
@Schema(description = "qq open id")
private String qqOpenid;
/**
* QQ openid
*/
@Schema(description = "qq open id")
private String qqOpenid;
/**
* gitee openid
*/
@Schema(description = "gitee open id")
private String giteeOpenId;
/**
* gitee openid
*/
@Schema(description = "gitee open id")
private String giteeOpenId;
/**
* 开源中国 openid
*/
@Schema(description = "开源中国 open id")
private String oscOpenId;
/**
* 开源中国 openid
*/
@Schema(description = "开源中国 open id")
private String oscOpenId;
/**
* 企微微信 userid
*/
@Schema(description = "企微微信 userid")
private String wxCpUserid;
/**
* 企微微信 userid
*/
@Schema(description = "企微微信 userid")
private String wxCpUserid;
/**
* 钉钉 userid
*/
@Schema(description = "钉钉 userid")
private String wxDingUserid;
/**
* 钉钉 userid
*/
@Schema(description = "钉钉 userid")
private String wxDingUserid;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
private LocalDateTime updateTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
private LocalDateTime updateTime;
/**
* 0-正常,1-删除
*/
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 0-正常,1-删除
*/
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 锁定标记
*/
@Schema(description = "锁定标记,0:正常,9:已锁定")
private String lockFlag;
/**
* 锁定标记
*/
@Schema(description = "锁定标记,0:正常,9:已锁定")
private String lockFlag;
/**
* 密码过期标记
*/
@Schema(description = "密码过期标记")
private String passwordExpireFlag;
/**
* 密码过期标记
*/
@Schema(description = "密码过期标记")
private String passwordExpireFlag;
/**
* 密码修改时间
*/
@Schema(description = "密码修改时间")
private LocalDateTime passwordModifyTime;
/**
* 密码修改时间
*/
@Schema(description = "密码修改时间")
private LocalDateTime passwordModifyTime;
/**
* 手机号
*/
@Sensitive(type = SensitiveTypeEnum.MOBILE_PHONE)
@Schema(description = "手机号")
private String phone;
/**
* 手机号
*/
@Sensitive(type = SensitiveTypeEnum.MOBILE_PHONE)
@Schema(description = "手机号")
private String phone;
/**
* 头像
*/
@Schema(description = "头像")
private String avatar;
/**
* 头像
*/
@Schema(description = "头像")
private String avatar;
/**
* 部门ID
*/
@Schema(description = "所属部门")
private Long deptId;
/**
* 部门ID
*/
@Schema(description = "所属部门")
private Long deptId;
/**
* 租户ID
*/
@Schema(description = "所属租户")
private Long tenantId;
/**
* 租户ID
*/
@Schema(description = "所属租户")
private Long tenantId;
/**
* 部门名称
*/
@Schema(description = "所属部门名称")
private String deptName;
/**
* 部门名称
*/
@Schema(description = "所属部门名称")
private String deptName;
/**
* 角色列表
*/
@Schema(description = "拥有的角色列表")
private List<SysRole> roleList;
/**
* 角色列表
*/
@Schema(description = "拥有的角色列表")
private List<SysRole> roleList;
/**
* 岗位列表
*/
private List<SysPost> postList;
/**
* 岗位列表
*/
private List<SysPost> postList;
/**
* 昵称
*/
@Schema(description = "昵称")
private String nickname;
/**
* 昵称
*/
@Schema(description = "昵称")
private String nickname;
/**
* 姓名
*/
@Schema(description = "姓名")
private String name;
/**
* 姓名
*/
@Schema(description = "姓名")
private String name;
/**
* 邮箱
*/
@Schema(description = "邮箱")
private String email;
/**
* 邮箱
*/
@Schema(description = "邮箱")
private String email;
@Schema(description = "员工浙政钉编码")
private String dingtalkEmployeeCode;
@Schema(description = "员工浙政钉编码")
private String dingtalkEmployeeCode;
/**
* 人脸
*/
private String faceImgs;
}
@@ -0,0 +1,12 @@
package com.bsd.pjcloud.admin.api.vo.base;
public interface BaseFacesInterface {
Long getUserId();
void setUserId(Long userId);
String getFaceImgs();
void setFaceImgs(String faceImgs);
}
+5
View File
@@ -189,6 +189,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!--测试: spring boot test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.bsd</groupId>
<artifactId>pjcloud-wallet-api</artifactId>
@@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.vo.UserExcelFaceVo;
import com.bsd.pjcloud.admin.api.vo.UserExcelVO;
import com.bsd.pjcloud.admin.service.SysUserService;
import com.bsd.pjcloud.common.core.constant.CommonConstants;
@@ -47,6 +48,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@@ -258,6 +260,12 @@ public class SysUserController {
return userService.importUser(excelVOList, bindingResult);
}
@PostMapping("/import-face")
@HasPermission("sys_user_export")
public R importUserFace(@RequestParam("file") MultipartFile file, @RequestExcel List<UserExcelFaceVo> excelList, BindingResult bindingResult) {
return userService.importUserFace(file, excelList, bindingResult);
}
/**
* 锁定指定用户
*
@@ -1,26 +1,27 @@
package com.bsd.pjcloud.admin.mapper;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.SysUserFaceDto;
import com.bsd.pjcloud.admin.api.entity.SysDept;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.entity.SysUserFaceEntity;
import com.bsd.pjcloud.admin.api.vo.SysUserFaceVo;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.github.yulichang.query.MPJLambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SysUserFaceMapper extends PjcloudBaseMapper<SysUserFaceEntity> {
Page<SysUserFaceVo> scopePageList(Page page, @Param("pa") SysUserFaceDto dto, DataScope dataScope);
List<SysUserFaceVo> groupConcatFaces(@Param("pa") SysUserFaceDto dto);
Long selectAllCount();
default SysUserFaceVo join(Long id) {
@@ -40,57 +40,71 @@ import java.util.Map;
*/
public interface SysDeptService extends IService<SysDept> {
/**
* 查询部门树菜单
* @param deptName 部门名称
* @return 树
*/
List<Tree<Long>> selectTree(String deptName, Long parentId);
/**
* 查询部门树菜单
*
* @param deptName 部门名称
* @return 树
*/
List<Tree<Long>> selectTree(String deptName, Long parentId);
/**
* 删除部门
* @param id 部门 ID
* @return 成功、失败
*/
Boolean removeDeptById(Long id);
/**
* 删除部门
*
* @param id 部门 ID
* @return 成功、失败
*/
Boolean removeDeptById(Long id);
List<DeptExcelVO> listExcelVo();
List<DeptExcelVO> listExcelVo();
R importDept(List<DeptExcelVO> excelVOList, BindingResult bindingResult);
R importDept(List<DeptExcelVO> excelVOList, BindingResult bindingResult);
/**
* 获取部门的所有后代部门列表
* @param deptId 部门ID
* @return 后代部门列表
*/
List<SysDept> listDescendant(Long deptId);
/**
* 获取部门的所有后代部门列表
*
* @param deptId 部门ID
* @return 后代部门列表
*/
List<SysDept> listDescendant(Long deptId);
/**
* 获取部门负责人
* @param deptId deptId
* @return user id list
*/
List<Long> listDeptLeader(Long deptId);
/**
* 获取部门负责人
*
* @param deptId deptId
* @return user id list
*/
List<Long> listDeptLeader(Long deptId);
/**
* 查询全部部门包含用户
* @param parentDeptId 父部门ID
* @param type 查询类型
*/
Map<String, Object> listOrgTree(Long parentDeptId, String type);
/**
* 查询全部部门包含用户
*
* @param parentDeptId 父部门ID
* @param type 查询类型
*/
Map<String, Object> listOrgTree(Long parentDeptId, String type);
/**
* 根据用户名模糊搜索用户
* @param username 用户名
* @return List user
*/
List<OrgTreeVO> getOrgTreeUser(String username);
/**
* 根据用户名模糊搜索用户
*
* @param username 用户名
* @return List user
*/
List<OrgTreeVO> getOrgTreeUser(String username);
/**
* 根据ids查询map集合
* @param deptIds
* @return
*/
Map<Long, SysDept> getDeptListByDeptIds(List<Long> deptIds);
/**
* 根据ids查询map集合
*
* @param deptIds
* @return
*/
Map<Long, SysDept> getDeptListByDeptIds(List<Long> deptIds);
/**
* 根据部门名查询部门
* @param names 部门名
* @return
*/
List<SysDept> selectByNames(List<String> names);
}
@@ -25,10 +25,12 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.vo.UserExcelFaceVo;
import com.bsd.pjcloud.admin.api.vo.UserExcelVO;
import com.bsd.pjcloud.admin.api.vo.UserVO;
import com.bsd.pjcloud.common.core.util.R;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@@ -101,7 +103,7 @@ public interface SysUserService extends IService<SysUser> {
* @param userDto DTO 对象
* @return success/fail
*/
Boolean saveUser(UserDTO userDto);
Long saveUser(UserDTO userDto);
/**
* 查询全部的用户
@@ -121,6 +123,8 @@ public interface SysUserService extends IService<SysUser> {
*/
R importUser(List<UserExcelVO> excelVOList, BindingResult bindingResult);
R importUserFace(MultipartFile file, List<UserExcelFaceVo> excelList, BindingResult bindingResult);
/**
* 注册用户
*
@@ -24,7 +24,9 @@ import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
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.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.admin.api.constant.OrgTypeEnum;
@@ -59,306 +61,321 @@ import java.util.stream.Collectors;
@AllArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {
private final SysUserMapper userMapper;
private final SysUserMapper userMapper;
private final SysDeptMapper deptMapper;
private final SysDeptMapper deptMapper;
private final SysPostMapper postMapper;
private final SysPostMapper postMapper;
private final SysRoleMapper roleMapper;
private final SysRoleMapper roleMapper;
private final SysUserPostMapper userPostMapper;
private final SysUserPostMapper userPostMapper;
/**
* 删除部门
* @param id 部门 ID
* @return 成功、失败
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeDeptById(Long id) {
// 级联删除部门
List<Long> idList = this.listDescendant(id).stream().map(SysDept::getDeptId).collect(Collectors.toList());
/**
* 删除部门
*
* @param id 部门 ID
* @return 成功、失败
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeDeptById(Long id) {
// 级联删除部门
List<Long> idList = this.listDescendant(id).stream().map(SysDept::getDeptId).collect(Collectors.toList());
Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds);
Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds);
return Boolean.TRUE;
}
return Boolean.TRUE;
}
/**
* 查询全部部门树
* @param deptName
* @param parentId
* @return 树 部门名称
*/
@Override
public List<Tree<Long>> selectTree(String deptName, Long parentId) {
// 查询全部部门
List<SysDept> deptAllList = deptMapper
.selectList(Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName));
// 查询数据权限内部门
List<Long> deptOwnIdList = deptMapper
.selectListByScope(
Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName),
DataScope.of())
.stream()
.map(SysDept::getDeptId)
.toList();
/**
* 查询全部部门树
*
* @param deptName
* @param parentId
* @return 树 部门名称
*/
@Override
public List<Tree<Long>> selectTree(String deptName, Long parentId) {
// 查询全部部门
List<SysDept> deptAllList = deptMapper
.selectList(Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName));
// 查询数据权限内部门
List<Long> deptOwnIdList = deptMapper
.selectListByScope(
Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName),
DataScope.of())
.stream()
.map(SysDept::getDeptId)
.toList();
// 权限内部门
List<TreeNode<Long>> collect = deptAllList.stream()
.filter(dept -> dept.getDeptId().intValue() != dept.getParentId())
.sorted(Comparator.comparingInt(SysDept::getSortOrder))
.map(dept -> {
TreeNode<Long> treeNode = new TreeNode<>();
treeNode.setId(dept.getDeptId());
treeNode.setParentId(dept.getParentId());
treeNode.setName(dept.getName());
treeNode.setWeight(dept.getSortOrder());
// 有权限不返回标识
Map<String, Object> extra = new HashMap<>(8);
extra.put("isLock", !deptOwnIdList.contains(dept.getDeptId()));
extra.put("createTime", dept.getCreateTime());
treeNode.setExtra(extra);
return treeNode;
})
.collect(Collectors.toList());
// 权限内部门
List<TreeNode<Long>> collect = deptAllList.stream()
.filter(dept -> dept.getDeptId().intValue() != dept.getParentId())
.sorted(Comparator.comparingInt(SysDept::getSortOrder))
.map(dept -> {
TreeNode<Long> treeNode = new TreeNode<>();
treeNode.setId(dept.getDeptId());
treeNode.setParentId(dept.getParentId());
treeNode.setName(dept.getName());
treeNode.setWeight(dept.getSortOrder());
// 有权限不返回标识
Map<String, Object> extra = new HashMap<>(8);
extra.put("isLock", !deptOwnIdList.contains(dept.getDeptId()));
extra.put("createTime", dept.getCreateTime());
treeNode.setExtra(extra);
return treeNode;
})
.collect(Collectors.toList());
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(deptName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).collect(Collectors.toList());
}
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(deptName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).collect(Collectors.toList());
}
return TreeUtil.build(collect, parentId == null ? 0 : parentId);
}
return TreeUtil.build(collect, parentId == null ? 0 : parentId);
}
/**
* 导出部门
* @return
*/
@Override
public List<DeptExcelVO> listExcelVo() {
List<SysDept> list = this.list();
List<DeptExcelVO> deptExcelVos = list.stream().map(item -> {
DeptExcelVO deptExcelVo = new DeptExcelVO();
deptExcelVo.setName(item.getName());
Optional<String> first = this.list()
.stream()
.filter(it -> item.getParentId().equals(it.getDeptId()))
.map(SysDept::getName)
.findFirst();
deptExcelVo.setParentName(first.orElse("根部门"));
deptExcelVo.setSortOrder(item.getSortOrder());
return deptExcelVo;
}).collect(Collectors.toList());
return deptExcelVos;
}
/**
* 导出部门
*
* @return
*/
@Override
public List<DeptExcelVO> listExcelVo() {
List<SysDept> list = this.list();
List<DeptExcelVO> deptExcelVos = list.stream().map(item -> {
DeptExcelVO deptExcelVo = new DeptExcelVO();
deptExcelVo.setName(item.getName());
Optional<String> first = this.list()
.stream()
.filter(it -> item.getParentId().equals(it.getDeptId()))
.map(SysDept::getName)
.findFirst();
deptExcelVo.setParentName(first.orElse("根部门"));
deptExcelVo.setSortOrder(item.getSortOrder());
return deptExcelVo;
}).collect(Collectors.toList());
return deptExcelVos;
}
@Override
public R importDept(List<DeptExcelVO> excelVOList, BindingResult bindingResult) {
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
@Override
public R importDept(List<DeptExcelVO> excelVOList, BindingResult bindingResult) {
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = this.list();
for (DeptExcelVO item : excelVOList) {
Set<String> errorMsg = new HashSet<>();
boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName()));
if (exsitUsername) {
errorMsg.add("部门名称已经存在");
}
SysDept one = this.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getName, item.getParentName()));
if (item.getParentName().equals("根部门")) {
one = new SysDept();
one.setDeptId(0L);
}
if (one == null) {
errorMsg.add("上级部门不存在");
}
if (CollUtil.isEmpty(errorMsg)) {
SysDept sysDept = new SysDept();
sysDept.setName(item.getName());
sysDept.setParentId(one.getDeptId());
sysDept.setSortOrder(item.getSortOrder());
baseMapper.insert(sysDept);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, "部门导入成功");
}
List<SysDept> deptList = this.list();
for (DeptExcelVO item : excelVOList) {
Set<String> errorMsg = new HashSet<>();
boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName()));
if (exsitUsername) {
errorMsg.add("部门名称已经存在");
}
SysDept one = this.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getName, item.getParentName()));
if (item.getParentName().equals("根部门")) {
one = new SysDept();
one.setDeptId(0L);
}
if (one == null) {
errorMsg.add("上级部门不存在");
}
if (CollUtil.isEmpty(errorMsg)) {
SysDept sysDept = new SysDept();
sysDept.setName(item.getName());
sysDept.setParentId(one.getDeptId());
sysDept.setSortOrder(item.getSortOrder());
baseMapper.insert(sysDept);
} else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, "部门导入成功");
}
/**
* 查询所有子节点 (包含当前节点)
* @param deptId 部门ID 目标部门ID
* @return ID
*/
@Override
public List<SysDept> listDescendant(Long deptId) {
// 查询全部部门
List<SysDept> allDeptList = baseMapper.selectList(Wrappers.emptyWrapper());
/**
* 查询所有子节点 (包含当前节点)
*
* @param deptId 部门ID 目标部门ID
* @return ID
*/
@Override
public List<SysDept> listDescendant(Long deptId) {
// 查询全部部门
List<SysDept> allDeptList = baseMapper.selectList(Wrappers.emptyWrapper());
// 递归查询所有子节点
List<SysDept> resDeptList = new ArrayList<>();
recursiveDept(allDeptList, deptId, resDeptList);
// 递归查询所有子节点
List<SysDept> resDeptList = new ArrayList<>();
recursiveDept(allDeptList, deptId, resDeptList);
// 添加当前节点
resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId())).toList());
return resDeptList;
}
// 添加当前节点
resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId())).toList());
return resDeptList;
}
/**
* 获取部门负责人
*
* 1. 根据dept 查询用户 2. 筛选用户列表中 post
* @param deptId deptId
* @return user id list
*/
@Override
public List<Long> listDeptLeader(Long deptId) {
List<SysUser> sysUserList = userMapper
.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getDeptId, deptId));
if (CollUtil.isEmpty(sysUserList)) {
return null;
}
/**
* 获取部门负责人
* <p>
* 1. 根据dept 查询用户 2. 筛选用户列表中 post
*
* @param deptId deptId
* @return user id list
*/
@Override
public List<Long> listDeptLeader(Long deptId) {
List<SysUser> sysUserList = userMapper
.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getDeptId, deptId));
if (CollUtil.isEmpty(sysUserList)) {
return null;
}
SysPost deptLeader = postMapper
.selectOne(Wrappers.<SysPost>lambdaQuery().eq(SysPost::getPostCode, PostCodeEnum.TEAM_LEADER.getCode()));
if (deptLeader == null) {
return null;
}
SysPost deptLeader = postMapper
.selectOne(Wrappers.<SysPost>lambdaQuery().eq(SysPost::getPostCode, PostCodeEnum.TEAM_LEADER.getCode()));
if (deptLeader == null) {
return null;
}
List<Long> userIdList = sysUserList.stream().map(SysUser::getUserId).toList();
return userPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery().in(SysUserPost::getUserId, userIdList))
.stream()
.filter(post -> Objects.equals(post.getPostId(), deptLeader.getPostId()))
.map(SysUserPost::getUserId)
.toList();
}
List<Long> userIdList = sysUserList.stream().map(SysUser::getUserId).toList();
return userPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery().in(SysUserPost::getUserId, userIdList))
.stream()
.filter(post -> Objects.equals(post.getPostId(), deptLeader.getPostId()))
.map(SysUserPost::getUserId)
.toList();
}
/**
* 根据父部门ID和类型获取组织树
* @param parentDeptId 父部门ID
* @param type 类型
* @return 组织树信息
*/
public Map<String, Object> listOrgTree(Long parentDeptId, String type) {
/**
* 根据父部门ID和类型获取组织树
*
* @param parentDeptId 父部门ID
* @param type 类型
* @return 组织树信息
*/
public Map<String, Object> listOrgTree(Long parentDeptId, String type) {
List<OrgTreeVO> orgs = new LinkedList<>();
List<OrgTreeVO> orgs = new LinkedList<>();
if (StrUtil.equals(type, OrgTypeEnum.ROLE.getType())) {
// 角色
List<SysRole> roleList = roleMapper.selectList(Wrappers.emptyWrapper());
if (StrUtil.equals(type, OrgTypeEnum.ROLE.getType())) {
// 角色
List<SysRole> roleList = roleMapper.selectList(Wrappers.emptyWrapper());
roleList.forEach(role -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(role.getRoleId());
orgTreeVo.setName(role.getRoleName());
orgTreeVo.setType(OrgTypeEnum.ROLE.getType());
orgTreeVo.setSelected(false);
orgs.add(orgTreeVo);
});
roleList.forEach(role -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(role.getRoleId());
orgTreeVo.setName(role.getRoleName());
orgTreeVo.setType(OrgTypeEnum.ROLE.getType());
orgTreeVo.setSelected(false);
orgs.add(orgTreeVo);
});
return Dict.create()
.set("roleList", orgs)
.set("childDepartments", orgs)
.set("employees", new ArrayList<>());
}
return Dict.create()
.set("roleList", orgs)
.set("childDepartments", orgs)
.set("employees", new ArrayList<>());
}
Dict dict = Dict.create()
.set("titleDepartments", new ArrayList<>())
.set("roleList", new ArrayList<>())
.set("employees", new ArrayList<>());
Dict dict = Dict.create()
.set("titleDepartments", new ArrayList<>())
.set("roleList", new ArrayList<>())
.set("employees", new ArrayList<>());
List<SysDept> deptList = this.list(
Wrappers.<SysDept>lambdaQuery().eq(Objects.nonNull(parentDeptId), SysDept::getParentId, parentDeptId));
List<SysDept> deptList = this.list(
Wrappers.<SysDept>lambdaQuery().eq(Objects.nonNull(parentDeptId), SysDept::getParentId, parentDeptId));
// 查询所有部门及员工
List<OrgTreeVO> deptVoList = new ArrayList<>();
deptList.forEach(dept -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(dept.getDeptId());
orgTreeVo.setName(dept.getName());
orgTreeVo.setType(OrgTypeEnum.DEPT.getType());
orgTreeVo.setSelected(false);
deptVoList.add(orgTreeVo);
});
dict.set("childDepartments", deptVoList);
// 查询所有部门及员工
List<OrgTreeVO> deptVoList = new ArrayList<>();
deptList.forEach(dept -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(dept.getDeptId());
orgTreeVo.setName(dept.getName());
orgTreeVo.setType(OrgTypeEnum.DEPT.getType());
orgTreeVo.setSelected(false);
deptVoList.add(orgTreeVo);
});
dict.set("childDepartments", deptVoList);
if (!StrUtil.equals(type, OrgTypeEnum.DEPT.getType())) {
if (!StrUtil.equals(type, OrgTypeEnum.DEPT.getType())) {
List<OrgTreeVO> userVoList = new ArrayList<>();
List<OrgTreeVO> userVoList = new ArrayList<>();
List<SysUser> userList = userMapper
.selectList(Wrappers.<SysUser>lambdaQuery().in(SysUser::getDeptId, CollUtil.toList(parentDeptId)));
List<SysUser> userList = userMapper
.selectList(Wrappers.<SysUser>lambdaQuery().in(SysUser::getDeptId, CollUtil.toList(parentDeptId)));
userList.forEach(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
userVoList.add(orgTreeVo);
});
dict.set("employees", userVoList);
}
userList.forEach(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
userVoList.add(orgTreeVo);
});
dict.set("employees", userVoList);
}
if (parentDeptId > 0) {
List<SysDept> allDept = this.list();
List<SysDept> depts = DataUtil.selectParentByDept(parentDeptId, allDept);
dict.set("titleDepartments", CollUtil.reverse(depts));
}
if (parentDeptId > 0) {
List<SysDept> allDept = this.list();
List<SysDept> depts = DataUtil.selectParentByDept(parentDeptId, allDept);
dict.set("titleDepartments", CollUtil.reverse(depts));
}
return dict;
}
return dict;
}
/**
* 模糊搜索用户
* @param username 用户名/拼音/首字母
* @return 匹配到的用户
*/
public List<OrgTreeVO> getOrgTreeUser(String username) {
return userMapper.selectList(Wrappers.<SysUser>lambdaQuery().like(SysUser::getUsername, username))
.stream()
.map(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
return orgTreeVo;
})
.collect(Collectors.toList());
}
/**
* 模糊搜索用户
*
* @param username 用户名/拼音/首字母
* @return 匹配到的用户
*/
public List<OrgTreeVO> getOrgTreeUser(String username) {
return userMapper.selectList(Wrappers.<SysUser>lambdaQuery().like(SysUser::getUsername, username))
.stream()
.map(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
return orgTreeVo;
})
.collect(Collectors.toList());
}
@Override
public Map<Long, SysDept> getDeptListByDeptIds(List<Long> deptIds) {
List<SysDept> sysDepts = baseMapper.selectList(Wrappers.<SysDept>lambdaQuery().in(SysDept::getDeptId, deptIds));
return sysDepts.stream().collect(Collectors.toMap(SysDept::getDeptId, sysDept -> sysDept));
}
@Override
public Map<Long, SysDept> getDeptListByDeptIds(List<Long> deptIds) {
List<SysDept> sysDepts = baseMapper.selectList(Wrappers.<SysDept>lambdaQuery().in(SysDept::getDeptId, deptIds));
return sysDepts.stream().collect(Collectors.toMap(SysDept::getDeptId, sysDept -> sysDept));
}
/**
* 递归查询所有子节点。
* @param allDeptList 所有部门列表
* @param parentId 父部门ID
* @param resDeptList 结果集合
*/
private void recursiveDept(List<SysDept> allDeptList, Long parentId, List<SysDept> resDeptList) {
// 使用 Stream API 进行筛选和遍历
allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> {
resDeptList.add(sysDept);
recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList);
});
}
@Override
public List<SysDept> selectByNames(List<String> names) {
if (ObjectUtil.isEmpty(names)) return null;
return baseMapper.selectList(new LambdaQueryWrapper<SysDept>()
.in(SysDept::getName, names)
);
}
/**
* 递归查询所有子节点。
*
* @param allDeptList 所有部门列表
* @param parentId 父部门ID
* @param resDeptList 结果集合
*/
private void recursiveDept(List<SysDept> allDeptList, Long parentId, List<SysDept> resDeptList) {
// 使用 Stream API 进行筛选和遍历
allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> {
resDeptList.add(sysDept);
recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList);
});
}
}
@@ -181,7 +181,16 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
*/
@Override
public IPage<SysMessageVO> pageUserMessage(Page page, SysMessageVO sysMessage) {
MPJLambdaWrapper<SysMessageEntity> wrapper = new MPJLambdaWrapper<SysMessageEntity>().selectAll(SysMessageEntity.class).select(SysMessageRelationEntity::getReadFlag).leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId).eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()).eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode()).eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory()).eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag, sysMessage.getReadFlag()).orderByDesc(SysMessageEntity::getSort).orderByDesc(SysMessageEntity::getCreateTime);
MPJLambdaWrapper<SysMessageEntity> wrapper = new MPJLambdaWrapper<SysMessageEntity>()
.selectAll(SysMessageEntity.class)
.select(SysMessageRelationEntity::getReadFlag)
.leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId)
.eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId())
.eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode())
.eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory())
.eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag, sysMessage.getReadFlag())
.orderByDesc(SysMessageEntity::getSort)
.orderByDesc(SysMessageEntity::getCreateTime);
return baseMapper.selectJoinPage(page, SysMessageVO.class, wrapper);
}
@@ -20,7 +20,11 @@
package com.bsd.pjcloud.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -29,39 +33,55 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.admin.api.constant.UserStateEnum;
import com.bsd.pjcloud.admin.api.dto.SysUserFaceDto;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
import com.bsd.pjcloud.admin.api.entity.*;
import com.bsd.pjcloud.admin.api.utils.DataUtil;
import com.bsd.pjcloud.admin.api.vo.SysUserFaceVo;
import com.bsd.pjcloud.admin.api.vo.UserExcelFaceVo;
import com.bsd.pjcloud.admin.api.vo.UserExcelVO;
import com.bsd.pjcloud.admin.api.vo.UserVO;
import com.bsd.pjcloud.admin.mapper.SysUserFaceMapper;
import com.bsd.pjcloud.admin.mapper.SysUserMapper;
import com.bsd.pjcloud.admin.mapper.SysUserPostMapper;
import com.bsd.pjcloud.admin.mapper.SysUserRoleMapper;
import com.bsd.pjcloud.admin.service.*;
import com.bsd.pjcloud.admin.utils.excel.ExcelTool;
import com.bsd.pjcloud.common.audit.annotation.Audit;
import com.bsd.pjcloud.common.core.constant.CacheConstants;
import com.bsd.pjcloud.common.core.constant.CommonConstants;
import com.bsd.pjcloud.common.core.exception.ErrorCodes;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.MsgUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.resolver.ParamResolver;
import com.bsd.pjcloud.common.excel.vo.ErrorMessage;
import com.bsd.pjcloud.common.file.core.FileProperties;
import com.bsd.pjcloud.common.file.core.FileTemplate;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.wallet.api.feign.RemoteWalletService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.apache.poi.ss.usermodel.PictureData;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.annotation.Lazy;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@@ -76,6 +96,8 @@ import java.util.stream.Collectors;
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
private static final String TAG = "系统用户";
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private final SysMenuService sysMenuService;
@@ -86,6 +108,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private final SysDeptService sysDeptService;
@Lazy
private final SysUserFaceService sysUserFaceService;
private final SysUserFaceMapper sysUserFaceMapper;
private final SysUserRoleMapper sysUserRoleMapper;
private final SysUserPostMapper sysUserPostMapper;
@@ -94,6 +120,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private final RemoteWalletService remoteWalletService;
private final SysFileService sysFileService;
/**
* 保存用户信息
*
@@ -102,7 +130,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUser(UserDTO userDto) {
public Long saveUser(UserDTO userDto) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setLockFlag(
@@ -141,9 +169,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}).forEach(sysUserRoleMapper::insert);
// 创建用户默认钱包
CompletableFuture.runAsync(() -> remoteWalletService.createWallet(userDto.getUserId()));
CompletableFuture.runAsync(() -> remoteWalletService.createWallet(sysUser.getUserId()));
return Boolean.TRUE;
return sysUser.getUserId();
}
/**
@@ -193,7 +221,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
*/
@Override
public IPage getUsersWithRolePage(Page page, UserDTO userDTO) {
return baseMapper.getUserVosPage(page, userDTO, DataScope.of());
IPage<UserVO> list = baseMapper.getUserVosPage(page, userDTO, DataScope.of());
if (ObjectUtil.isNotEmpty(list.getRecords())) {
List<Long> userIds = list.getRecords().stream().map(UserVO::getUserId).distinct().toList();
if (ObjectUtil.isNotEmpty(userIds)) {
SysUserFaceDto faceDto = new SysUserFaceDto();
List<SysUserFaceVo> faceList = sysUserFaceMapper.groupConcatFaces(faceDto);
DataUtil.convertFacesList(list.getRecords(), CollectionUtils.convertMap(faceList, SysUserFaceVo::getUserId));
}
}
return list;
}
/**
@@ -414,6 +451,77 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED));
}
@Override
public R importUserFace(MultipartFile file, List<UserExcelFaceVo> excelList, BindingResult bindingResult) {
try {
if (ObjectUtil.isEmpty(excelList)) R.failed("excel内容为空");
// 校验导入的内容
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<String> deptNames = excelList.stream().map(UserExcelFaceVo::getDeptName).distinct().filter(ObjectUtil::isNotEmpty).toList();
// 部门
List<SysDept> sysDeptList = sysDeptService.selectByNames(deptNames);
// 角色
List<SysRole> roleList = sysRoleService.list();
// 用户
List<SysUser> userList = this.list();
String walletAutoCreate = ParamResolver.getStr("WALLET_AUTO_CREATE");
String userDefaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
List<Long> roleIds = roleList.stream().filter(v -> ObjectUtil.equals(v.getRoleCode(), walletAutoCreate) || ObjectUtil.equals(v.getRoleCode(), userDefaultRole)).map(SysRole::getRoleId).toList();
// 读取图片
Map<String, PictureData> images = ExcelTool.getPictureFromExcel(file, 1);
for (UserExcelFaceVo v : excelList) {
Long deptId = null;
Set<String> errorMsg = new HashSet<>();
String username = v.getUsername(), name = v.getName(), mobile = v.getMobile(), sex = v.getSex(), deptName = v.getDeptName();
if (ObjectUtil.isEmpty(name)) {
errorMsg.add("用户昵称为空");
}
if (ObjectUtil.isEmpty(mobile)) {
errorMsg.add("手机号码为空");
} else if (!Validator.isMobile(mobile.trim())) {
errorMsg.add("手机号码格式不正确");
} else {
// 校验用户名是否存在
boolean existMobile = userList.stream().anyMatch(i -> ObjectUtil.equals(i.getPhone(), mobile.trim()));
if (existMobile) {
errorMsg.add("手机号已存在");
}
}
if (ObjectUtil.isEmpty(deptName)) {
errorMsg.add("部门名称为空");
} else {
Optional<SysDept> targetDept = sysDeptList.stream().filter(i -> ObjectUtil.equals(i.getName(), deptName)).findFirst();
if (targetDept.isEmpty()) {
errorMsg.add("没有该部门");
} else {
deptId = targetDept.get().getDeptId();
}
}
PictureData face = null;
if (ObjectUtil.isNotEmpty(images)) {
String key = String.valueOf(v.getLineNum() - 1);
face = images.getOrDefault(key, null);
}
if (ObjectUtil.isEmpty(face)) {
errorMsg.add("人脸照片为空");
}
if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(v, deptId, roleIds, face);
} else {
errorMessageList.add(new ErrorMessage(v.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED));
} catch (Exception e) {
e.printStackTrace();
log.error("|{}|导入用户意外的错误error:|{}|", TAG, e.getMessage());
}
return null;
}
/**
* 插入excel User
*/
@@ -441,6 +549,42 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
this.saveUser(userDTO);
}
public void insertExcelUser(UserExcelFaceVo excel, Long deptId, List<Long> roleList, PictureData face) {
String username = ObjectUtil.isEmpty(excel.getUsername()) ? excel.getMobile() : excel.getUsername();
UserDTO userDTO = new UserDTO();
userDTO.setUsername(username.replaceAll("\\s+", ""));
userDTO.setName(excel.getName().replaceAll("\\s+", ""));
userDTO.setNickname(excel.getName().replaceAll("\\s+", ""));
userDTO.setPhone(excel.getMobile().replaceAll("\\s+", ""));
userDTO.setDeptId(deptId);
// 批量导入初始密码为手机号
userDTO.setPasswordModifyTime(LocalDateTime.now());
userDTO.setPassword(userDTO.getPhone().replaceAll("\\s+", ""));
// 根据角色名称查询角色ID
userDTO.setRole(roleList);
// 插入用户
Long usrId = this.saveUser(userDTO);
userDTO.setUserId(usrId);
insertExcelFace(userDTO, face);
}
public void insertExcelFace(UserDTO user, PictureData face) {
try {
// 查询用户
MultipartFile multipartFile = new MockMultipartFile("file", UUID.randomUUID() + "_face.png", "image/png", new ByteArrayInputStream(face.getData()));
Map data = (Map) sysFileService.uploadFile(multipartFile, null, null, null).getData();
String url = data.get("url").toString();
SysUserFaceEntity updateObj = new SysUserFaceEntity();
updateObj.setUserId(user.getUserId());
updateObj.setFaceImg(url);
sysUserFaceService.create(updateObj);
} catch (Exception e) {
e.printStackTrace();
log.error("|{}|获取人脸图片错误error:|{}|", TAG, e.getMessage());
}
}
/**
* 注册用户 赋予用户默认角色
*
@@ -465,7 +609,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone());
return R.failed(message);
}
return R.ok(saveUser(userDto));
saveUser(userDto);
return R.ok(true);
}
/**
@@ -0,0 +1,95 @@
package com.bsd.pjcloud.admin.utils.excel;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import lombok.experimental.UtilityClass;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@UtilityClass
public class ExcelTool {
/**
* 读取sheet的所有图片
*/
public static Map<String, PictureData> getPictureFromExcel(MultipartFile file, int sheetNum) throws EncryptedDocumentException, IOException {
String fileName = file.getOriginalFilename();
Workbook workbook = null;
if (ObjectUtil.isEmpty(fileName)) return null;
InputStream fileInputStream = file.getInputStream();
if (fileName.endsWith("xls")) {
//2003
workbook = new HSSFWorkbook(fileInputStream);
HSSFSheet sheet = (HSSFSheet) workbook.getSheetAt(sheetNum - 1);
Map<String, PictureData> pictures = getPictures(sheet);
return pictures;
} else if (fileName.endsWith("xlsx")) {
//2007
workbook = new XSSFWorkbook(fileInputStream);
XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(sheetNum - 1);
Map<String, PictureData> pictures = getPictures(sheet);
return pictures;
}
return new HashMap();
}
/**
* 获取图片和位置 (xls版)
*/
public static Map<String, PictureData> getPictures(HSSFSheet sheet) throws IOException {
Map<String, PictureData> map = new HashMap<String, PictureData>();
List<HSSFShape> list = sheet.getDrawingPatriarch().getChildren();
for (HSSFShape shape : list) {
if (shape instanceof HSSFPicture) {
HSSFPicture picture = (HSSFPicture) shape;
HSSFClientAnchor cAnchor = picture.getClientAnchor();
PictureData pdata = picture.getPictureData();
String key = String.valueOf(cAnchor.getRow1());
map.put(key, pdata);
}
}
return map;
}
/**
* 获取图片和位置 (xlsx版)
*/
public static Map<String, PictureData> getPictures(XSSFSheet sheet) throws IOException {
Map<String, PictureData> map = new HashMap<String, PictureData>();
List<POIXMLDocumentPart> list = sheet.getRelations();
for (POIXMLDocumentPart part : list) {
if (part instanceof XSSFDrawing) {
XSSFDrawing drawing = (XSSFDrawing) part;
List<XSSFShape> shapes = drawing.getShapes();
for (XSSFShape shape : shapes) {
XSSFPicture picture = (XSSFPicture) shape;
XSSFClientAnchor anchor = picture.getPreferredSize();
CTMarker marker = anchor.getFrom();
String key = String.valueOf(marker.getRow());
map.put(key, picture.getPictureData());
}
}
}
return map;
}
public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
return EasyExcel.read(file.getInputStream(), head, null)
.autoCloseStream(false)
.doReadAllSync();
}
}
@@ -46,4 +46,19 @@
<select id="selectAllCount" resultType="java.lang.Long">
select count(0) from sys_user_face
</select>
<select id="groupConcatFaces" resultType="com.bsd.pjcloud.admin.api.vo.SysUserFaceVo">
select a.user_id, group_concat(a.face_img) as faceImgs
from sys_user_face a
<where>
del_flag = '0'
<if test="pa.userIds != null and pa.userIds.size() != 0">
and user_id in
<foreach collection="pa.userIds" index="index" item="v" open="(" separator="," close=")">
#{v}
</foreach>
</if>
</where>
GROUP BY a.user_id
</select>
</mapper>
@@ -3,8 +3,7 @@ package com.bsd.pjcloud.wallet.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.*;
import com.bsd.pjcloud.common.core.util.TenantTable;
import java.time.LocalDateTime;
@@ -14,6 +13,9 @@ import java.time.LocalDateTime;
* @author dzc
* @date 2024-12-31 18:53:31
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@TenantTable
@TableName("wallet_active")
@@ -5,8 +5,7 @@ import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.*;
import com.bsd.pjcloud.common.core.util.TenantTable;
import java.time.LocalDate;
@@ -18,6 +17,9 @@ import java.time.LocalDateTime;
* @author pjcloud
* @date 2024-12-31 14:23:57
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@TenantTable
@TableName("wallet_recharge_apply")
@@ -32,6 +34,18 @@ public class WalletRechargeApplyEntity extends Model<WalletRechargeApplyEntity>
@Schema(description = "主键ID")
private Long id;
/**
* 流程id
*/
@Schema(description = "流程id")
private String processId;
/**
* 流程状态
*/
@Schema(description = "流程状态")
private String processStatus;
/**
* 申请人ID
*/
@@ -4,11 +4,12 @@ import com.bsd.pjcloud.admin.api.vo.base.BaseDeptInterface;
import com.bsd.pjcloud.admin.api.vo.base.BaseUserInterface;
import com.bsd.pjcloud.wallet.api.entity.WalletActiveEntity;
import com.bsd.pjcloud.wallet.api.vo.base.BaseMchInterface;
import com.bsd.pjcloud.wallet.api.vo.base.BaseWalletTypeInterface;
import lombok.Data;
@Data
public class WalletActiveVo extends WalletActiveEntity implements BaseUserInterface, BaseDeptInterface, BaseMchInterface {
public class WalletActiveVo extends WalletActiveEntity implements BaseUserInterface, BaseDeptInterface, BaseMchInterface, BaseWalletTypeInterface {
/**
* 用户相关
*/
@@ -29,4 +30,15 @@ public class WalletActiveVo extends WalletActiveEntity implements BaseUserInterf
private String merchantName;
private String logoPic;
/**
* 钱包类型相关
*/
private Long walletTypeId;
private String walletTypeName;
private String walletTypeUniqueCode;
private String walletTypeIcon;
}
@@ -10,6 +10,7 @@ import com.bsd.pjcloud.common.idempotent.annotation.Idempotent;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.wallet.api.dto.WalletActiveDto;
import com.bsd.pjcloud.wallet.api.entity.WalletActiveEntity;
import com.bsd.pjcloud.wallet.api.vo.WalletActiveVo;
import com.bsd.pjcloud.wallet.service.WalletActiveService;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -41,6 +42,37 @@ public class WalletActiveController {
private final WalletActiveService walletActiveService;
/* ************************************* start android start ************************************* */
@GetMapping("/ad/open-card-list")
@Operation(summary = "android开卡列表")
public R<List<WalletActiveVo>> AdOpenCardList(@ParameterObject Page page, @ParameterObject WalletActiveDto dto) {
return R.ok(walletActiveService.pageJoin(page, dto).getRecords());
}
@GetMapping("/ad/open-card-success")
@Operation(summary = "android开卡成功通知")
@Idempotent(info = "正在开卡中,请勿重复提交")
public R<Boolean> AdOpenCardSuccess(@RequestParam Long id) {
return R.ok(walletActiveService.openCardSuccess(id));
}
@GetMapping("/ad/refresh-avatar")
@Operation(summary = "重新激活")
@SysLog("android重新激活")
@Idempotent(info = "正在处理中,请勿重复提交")
public R<Boolean> adRefreshAvatar(@RequestParam Long id) {
return R.ok(walletActiveService.refreshAvatar(id));
}
/* ************************************* end android end ************************************* */
@GetMapping("/refresh-avatar")
@Operation(summary = "重新激活")
@SysLog("重新激活")
@Idempotent(info = "正在处理中,请勿重复提交")
public R<Boolean> refreshAvatar(@RequestParam Long id) {
return R.ok(walletActiveService.refreshAvatar(id));
}
@PostMapping("/fast-create-card")
@Operation(summary = "一键开卡")
@Idempotent(info = "正在开卡中,请勿重复提交")
@@ -49,13 +81,6 @@ public class WalletActiveController {
return R.ok(true);
}
/**
* 分页查询
*
* @param page 分页对象
* @param walletActive 钱包开卡
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('wallet_walletActive_view')")
@@ -64,27 +89,13 @@ public class WalletActiveController {
return R.ok(walletActiveService.page(page, wrapper));
}
/**
* 分页复杂查询
*
* @param page 分页对象
* @param walletActive 钱包开卡
* @return
*/
@Operation(summary = "分页复杂查询", description = "分页复杂查询")
@GetMapping("/page-join")
@PreAuthorize("@pms.hasPermission('wallet_walletActive_view')")
public R getWalletActivePageJoin(@ParameterObject Page page, @ParameterObject WalletActiveDto dto) {
return R.ok(walletActiveService.pageJoin(page, dto));
return R.ok(walletActiveService.scopePage(page, dto));
}
/**
* 通过id查询钱包开卡
*
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('wallet_walletActive_view')")
@@ -92,12 +103,6 @@ public class WalletActiveController {
return R.ok(walletActiveService.getById(id));
}
/**
* 新增钱包开卡
*
* @param walletActive 钱包开卡
* @return R
*/
@Operation(summary = "新增钱包开卡", description = "新增钱包开卡")
@SysLog("新增钱包开卡")
@PostMapping
@@ -106,12 +111,6 @@ public class WalletActiveController {
return R.ok(walletActiveService.save(walletActive));
}
/**
* 修改钱包开卡
*
* @param walletActive 钱包开卡
* @return R
*/
@Operation(summary = "修改钱包开卡", description = "修改钱包开卡")
@SysLog("修改钱包开卡")
@PutMapping
@@ -120,12 +119,6 @@ public class WalletActiveController {
return R.ok(walletActiveService.updateById(walletActive));
}
/**
* 通过id删除钱包开卡
*
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除钱包开卡", description = "通过id删除钱包开卡")
@SysLog("通过id删除钱包开卡")
@DeleteMapping
@@ -134,14 +127,6 @@ public class WalletActiveController {
return R.ok(walletActiveService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
*
* @param walletActive 查询条件
* @param ids 导出指定ID
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('wallet_walletActive_export')")
@@ -8,6 +8,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.excel.annotation.RequestExcel;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.common.security.annotation.Inner;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeApplyDto;
import com.bsd.pjcloud.wallet.api.dto.excel.WalletRechargeExcelDto;
import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeApplyEntity;
@@ -34,12 +38,20 @@ public class WalletRechargeApplyController {
private final WalletRechargeApplyService walletRechargeApplyService;
/* ************************************* start callback start ************************************* */
@Inner(value = false)
@PostMapping("/apply-callback")
public void applyCallback(@RequestBody ProcessNodeRecordAssignUserParamDto dto) {
walletRechargeApplyService.applyCallback(dto);
}
/* ************************************* start callback start ************************************* */
@Operation(summary = "提交申请", description = "提交申请")
@SysLog("提交申请")
@PostMapping("/apply")
@PreAuthorize("@pms.hasPermission('wallet_walletRechargeApply_apply')")
public R apply(@RequestBody WalletRechargeApplyDto dto) {
walletRechargeApplyService.apply(dto);
@GetMapping("/apply")
// @PreAuthorize("@pms.hasPermission('wallet_walletRechargeApply_apply')")
public R apply(@RequestParam Long id) {
walletRechargeApplyService.apply(id);
return R.ok(true);
}
@@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.common.security.annotation.Inner;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.app.WalletAppRechargeDto;
@@ -1,7 +1,10 @@
package com.bsd.pjcloud.wallet.mapper;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.bsd.pjcloud.wallet.api.dto.WalletActiveDto;
import com.bsd.pjcloud.wallet.api.entity.WalletActiveEntity;
@@ -17,7 +20,21 @@ public interface WalletActiveMapper extends PjcloudBaseMapper<WalletActiveEntity
.selectAll(WalletActiveEntity.class)
.likeIfExists(WalletActiveEntity::getCardNumber, dto.getCardNumber())
.eqIfExists(WalletActiveEntity::getIsActiveHardware, dto.getIsActiveHardware())
.eqIfExists(WalletActiveEntity::getDeptId, dto.getDeptId())
.in(ObjectUtil.isNotEmpty(dto.getUserIds()), WalletActiveEntity::getId, dto.getUserIds());
return selectJoinPage(page, WalletActiveVo.class, wrapper);
}
default Page<WalletActiveVo> scopePage(Page page, WalletActiveDto dto) {
LambdaQueryWrapper<WalletActiveEntity> wrapper = new LambdaQueryWrapper<WalletActiveEntity>()
.like(ObjectUtil.isNotEmpty(dto.getCardNumber()), WalletActiveEntity::getCardNumber, dto.getCardNumber())
.eq(ObjectUtil.isNotEmpty(dto.getIsActiveHardware()), WalletActiveEntity::getIsActiveHardware, dto.getIsActiveHardware())
.eq(ObjectUtil.isNotEmpty(dto.getDeptId()), WalletActiveEntity::getDeptId, dto.getDeptId())
.in(ObjectUtil.isNotEmpty(dto.getUserIds()), WalletActiveEntity::getId, dto.getUserIds());
Page list = selectPageByScope(page, wrapper, DataScope.of());
list.setRecords(BeanUtils.toBean(list.getRecords(), WalletActiveVo.class));
return list;
}
WalletActiveEntity getLast();
}
@@ -14,5 +14,20 @@ public interface WalletActiveService extends IService<WalletActiveEntity> {
*/
void fastCreateCard(WalletActiveDto dto);
/**
* 开卡成功的通知
*
* @param id 开卡id
*/
Boolean openCardSuccess(Long id);
/**
* 重新激活
* @param id 开卡id
*/
Boolean refreshAvatar(Long id);
Page<WalletActiveVo> pageJoin(Page page, WalletActiveDto dto);
Page<WalletActiveVo> scopePage(Page page, WalletActiveDto dto);
}
@@ -3,6 +3,7 @@ package com.bsd.pjcloud.wallet.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeApplyDto;
import com.bsd.pjcloud.wallet.api.dto.excel.WalletRechargeExcelDto;
import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeApplyEntity;
@@ -20,9 +21,9 @@ public interface WalletRechargeApplyService extends IService<WalletRechargeApply
/**
* 提交申请
*
* @param dto
* @param id
*/
void apply(WalletRechargeApplyDto dto);
void apply(Long id);
/**
* 取消申请
@@ -33,8 +34,14 @@ public interface WalletRechargeApplyService extends IService<WalletRechargeApply
/**
* 读取excel内容
*
* @param excelVOList
* @param bindingResult
*/
R readExcel(List<WalletRechargeExcelDto> excelVOList, BindingResult bindingResult);
/**
* 审批回调
*/
void applyCallback(ProcessNodeRecordAssignUserParamDto dto);
}
@@ -2,6 +2,7 @@ package com.bsd.pjcloud.wallet.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto;
import com.bsd.pjcloud.wallet.api.dto.recharge.app.WalletAppRechargeDto;
@@ -14,6 +15,7 @@ public interface WalletRechargeService extends IService<WalletRechargeEntity> {
/**
* app充值
*
* @param dto
* @return
*/
@@ -21,6 +23,7 @@ public interface WalletRechargeService extends IService<WalletRechargeEntity> {
/**
* 远程调用-退款
*
* @param dto
* @return
*/
@@ -29,6 +32,7 @@ public interface WalletRechargeService extends IService<WalletRechargeEntity> {
/**
* 根据退款id查询
*
* @return
*/
WalletRechargeEntity getByRefundId(Long refundId);
@@ -17,6 +17,7 @@ import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.wallet.api.constant.WalletTypeEnum;
import com.bsd.pjcloud.wallet.api.dto.MchManageDto;
import com.bsd.pjcloud.wallet.api.dto.WalletActiveDto;
import com.bsd.pjcloud.wallet.api.dto.WalletTypeDto;
import com.bsd.pjcloud.wallet.api.entity.MchManageEntity;
import com.bsd.pjcloud.wallet.api.entity.WalletActiveEntity;
import com.bsd.pjcloud.wallet.api.entity.WalletTypeEntity;
@@ -24,6 +25,7 @@ import com.bsd.pjcloud.wallet.api.utils.WalletDataUtil;
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
import com.bsd.pjcloud.wallet.api.vo.WalletActiveVo;
import com.bsd.pjcloud.wallet.mapper.WalletActiveMapper;
import com.bsd.pjcloud.wallet.mapper.WalletTypeMapper;
import com.bsd.pjcloud.wallet.service.MchManageService;
import com.bsd.pjcloud.wallet.service.WalletActiveService;
import com.bsd.pjcloud.wallet.service.WalletTypeService;
@@ -49,6 +51,8 @@ import java.util.Map;
@Service
public class WalletActiveServiceImpl extends ServiceImpl<WalletActiveMapper, WalletActiveEntity> implements WalletActiveService {
private final WalletTypeMapper walletTypeMapper;
private final WalletTypeService walletTypeService;
private final MchManageService mchManageService;
@@ -66,7 +70,7 @@ public class WalletActiveServiceImpl extends ServiceImpl<WalletActiveMapper, Wal
MchManageEntity mchManage = mchManageService.getById(dto.getMerchantId());
if (ObjectUtil.isEmpty(mchManage)) throw new CheckedException("商户不存在");
int startNum = 1;
WalletActiveEntity last = getLast();
WalletActiveEntity last = baseMapper.getLast();
if (ObjectUtil.isNotEmpty(last)) startNum = last.getCardSort();
List<WalletActiveEntity> batchSaveList = new ArrayList<>();
for (int i = 0; i < count; i++) {
@@ -84,6 +88,30 @@ public class WalletActiveServiceImpl extends ServiceImpl<WalletActiveMapper, Wal
baseMapper.insert(batchSaveList);
}
@Override
public Boolean openCardSuccess(Long id) {
// 校验存在
WalletActiveEntity detail = baseMapper.selectById(id);
if (ObjectUtil.isEmpty(detail)) throw new RuntimeException("开卡记录不存在");
if (ObjectUtil.isNotEmpty(detail.getIsActiveHardware()) && ObjectUtil.equals(detail.getIsActiveHardware(), YesNoEnum.YES.getCode())) {
throw new RuntimeException("该卡已经激活,无需重复激活");
}
WalletActiveEntity updateObj = WalletActiveEntity.builder().id(detail.getId()).isActiveHardware(YesNoEnum.YES.getCode()).build();
return baseMapper.updateById(updateObj) > 0;
}
@Override
public Boolean refreshAvatar(Long id) {
// 校验存在
WalletActiveEntity detail = baseMapper.selectById(id);
if (ObjectUtil.isEmpty(detail)) throw new RuntimeException("开卡记录不存在");
if (ObjectUtil.isNotEmpty(detail.getIsActiveHardware()) && ObjectUtil.equals(detail.getIsActiveHardware(), YesNoEnum.NO.getCode())) {
throw new RuntimeException("该卡未激活,无需重新激活");
}
WalletActiveEntity updateObj = WalletActiveEntity.builder().id(detail.getId()).isActiveHardware(YesNoEnum.NO.getCode()).build();
return baseMapper.updateById(updateObj) > 0;
}
@Override
public Page<WalletActiveVo> pageJoin(Page page, WalletActiveDto dto) {
Page<WalletActiveVo> list = baseMapper.pageJoin(page, dto);
@@ -92,27 +120,63 @@ public class WalletActiveServiceImpl extends ServiceImpl<WalletActiveMapper, Wal
List<Long> userIds = list.getRecords().stream().map(WalletActiveVo::getUserId).distinct().toList();
R<List<SysUser>> userList = userService.getUserById(new ArrayList<>(userIds));
if (ObjectUtil.isNotEmpty(userList.getData())) {
DataUtil.convertUserList(page.getRecords(), CollectionUtils.convertMap(userList.getData(), SysUser::getUserId));
DataUtil.convertUserList(list.getRecords(), CollectionUtils.convertMap(userList.getData(), SysUser::getUserId));
}
// 部门
List<Long> deptIds = list.getRecords().stream().map(WalletActiveVo::getDeptId).distinct().toList();
R<Map<Long, SysDept>> deptList = deptService.getDeptByDeptIds(deptIds);
if (ObjectUtil.isNotEmpty(deptList.getData())) {
DataUtil.convertDeptList(page.getRecords(), deptList.getData());
DataUtil.convertDeptList(list.getRecords(), deptList.getData());
}
// 商户
List<Long> mchIds = list.getRecords().stream().map(WalletActiveVo::getMerchantId).distinct().toList();
List<MchManageVo> mchList = mchManageService.list(MchManageDto.builder().ids(mchIds).build());
if (ObjectUtil.isNotEmpty(mchList)) {
WalletDataUtil.convertMchList(page.getRecords(), CollectionUtils.convertMap(mchList, MchManageVo::getId));
WalletDataUtil.convertMchList(list.getRecords(), CollectionUtils.convertMap(mchList, MchManageVo::getId));
}
// 饭卡类型
List<Long> walletTypeIds = list.getRecords().stream().map(WalletActiveVo::getWalletTypeId).distinct().toList();
if (ObjectUtil.isNotEmpty(walletTypeIds)) {
WalletTypeDto walletTypeDto = new WalletTypeDto();
walletTypeDto.setWalletTypeIds(walletTypeIds);
List<WalletTypeEntity> walletTypeList = walletTypeMapper.list(walletTypeDto);
if (ObjectUtil.isNotEmpty(walletTypeList)) {
WalletDataUtil.convertWalletTYpeList(list.getRecords(), CollectionUtils.convertMap(walletTypeList, WalletTypeEntity::getId));
}
}
}
return list;
}
private WalletActiveEntity getLast() {
LambdaQueryWrapper<WalletActiveEntity> query = new LambdaQueryWrapper<WalletActiveEntity>();
query.orderByDesc(WalletActiveEntity::getId).last("LIMIT 1");
return baseMapper.selectOne(query);
@Override
public Page<WalletActiveVo> scopePage(Page page, WalletActiveDto dto) {
Page<WalletActiveVo> list = baseMapper.scopePage(page, dto);
if (ObjectUtil.isNotEmpty(list.getRecords())) {
// 用户
List<Long> userIds = list.getRecords().stream().map(WalletActiveVo::getUserId).distinct().toList();
if (ObjectUtil.isNotEmpty(userIds)) {
R<List<SysUser>> userList = userService.getUserById(new ArrayList<>(userIds));
if (ObjectUtil.isNotEmpty(userList.getData())) {
DataUtil.convertUserList(page.getRecords(), CollectionUtils.convertMap(userList.getData(), SysUser::getUserId));
}
}
// 部门
List<Long> deptIds = list.getRecords().stream().map(WalletActiveVo::getDeptId).distinct().toList();
if (ObjectUtil.isNotEmpty(deptIds)) {
R<Map<Long, SysDept>> deptList = deptService.getDeptByDeptIds(deptIds);
if (ObjectUtil.isNotEmpty(deptList.getData())) {
DataUtil.convertDeptList(page.getRecords(), deptList.getData());
}
}
// 商户
List<Long> mchIds = list.getRecords().stream().map(WalletActiveVo::getMerchantId).distinct().toList();
if (ObjectUtil.isNotEmpty(mchIds)) {
List<MchManageVo> mchList = mchManageService.list(MchManageDto.builder().ids(mchIds).build());
if (ObjectUtil.isNotEmpty(mchList)) {
WalletDataUtil.convertMchList(page.getRecords(), CollectionUtils.convertMap(mchList, MchManageVo::getId));
}
}
}
return list;
}
}
@@ -1,5 +1,7 @@
package com.bsd.pjcloud.wallet.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -22,13 +24,15 @@ import com.bsd.pjcloud.wallet.api.entity.WalletForeignEntity;
import com.bsd.pjcloud.wallet.api.vo.WalletForeignVo;
import com.bsd.pjcloud.wallet.mapper.WalletForeignMapper;
import com.bsd.pjcloud.wallet.service.WalletForeignService;
import com.bsd.pjcloud.wallet.utils.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.dto.WalletForeignApplyFlowDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -57,19 +61,27 @@ public class WalletForeignServiceImpl extends ServiceImpl<WalletForeignMapper, W
@Override
public Long create(WalletForeignDto dto) {
// 查询发起人
R<UserInfo> userData = userService.getByUserId(dto.getUserId());
if (ObjectUtil.isEmpty(userData.getData())) {
throw new RuntimeException("发起人不存在");
}
// 判断之前有没有在审核的
if (isCheckData(dto.getUserId())) {
throw new RuntimeException("已提交申请,请勿重复提交");
}
dto.setDeptId(userData.getData().getSysUser().getDeptId());
UserInfo userData = userService.getByUserId(dto.getUserId()).getData();
if (ObjectUtil.isEmpty(userData)) throw new RuntimeException("发起人不存在");
dto.setDeptId(userData.getSysUser().getDeptId());
dto.setProcessStatus(TaskCheckStatusEnum.PADDING.getCode());
// 查询部门
SysDept dept = deptService.getDeptByDeptId(dto.getDeptId()).getData();
if (ObjectUtil.isEmpty(dept)) throw new RuntimeException("发起人部门不存在");
// 判断之前有没有在审核的
if (isCheckData(dto.getUserId())) throw new RuntimeException("已提交申请,请勿重复提交");
baseMapper.insert(dto);
// 发起审批
String processId = flowUtil.startFlow("TASK_FOREIGN_FLOW", userData.getData().getSysUser(), dto.getId());
WalletForeignApplyFlowDto flowDto = new WalletForeignApplyFlowDto();
flowDto.setApplyUsername(userData.getSysUser().getUsername());
flowDto.setApplyUserId(userData.getSysUser().getUserId());
flowDto.setApplyDeptName(dept.getName());
flowDto.setApplyDeptId(dept.getDeptId());
flowDto.setApplyCreateTime(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN));
flowDto.setCount(dto.getCount());
flowDto.setRemark(dto.getRemark());
flowDto.setApplyTime(LocalDateTimeUtil.format(dto.getApplyStartTime(), DatePattern.NORM_DATE_PATTERN) + " - " + LocalDateTimeUtil.format(dto.getApplyEndTime(), DatePattern.NORM_DATE_PATTERN));
String processId = flowUtil.startFlow("TASK_FOREIGN_FLOW", userData.getSysUser(), dto.getId(), flowDto);
baseMapper.updateById(WalletForeignEntity.builder().id(dto.getId()).processId(processId).build());
return dto.getId();
}
@@ -98,7 +110,7 @@ public class WalletForeignServiceImpl extends ServiceImpl<WalletForeignMapper, W
public WalletForeignVo join(Long id) {
WalletForeignVo detail = baseMapper.join(id);
if (ObjectUtil.isNotEmpty(detail)) {
}
return detail;
}
@@ -112,6 +124,10 @@ public class WalletForeignServiceImpl extends ServiceImpl<WalletForeignMapper, W
.eq(WalletForeignEntity::getProcessId, processId)
);
if (ObjectUtil.isEmpty(detail)) return;
if (!ObjectUtil.equals(detail.getProcessStatus(), TaskCheckStatusEnum.PADDING.getCode())) {
log.error("|{}|重复的回调,dto:|{}|", TAG);
return;
}
try {
Boolean isConsent = flowUtil.isConsent(dto);
String processStatus = isConsent ? TaskCheckStatusEnum.RESULT.getCode() : TaskCheckStatusEnum.REJECT.getCode();
@@ -1,5 +1,7 @@
package com.bsd.pjcloud.wallet.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -16,7 +18,6 @@ import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.wallet.api.constant.WalletCodeBizEnum;
import com.bsd.pjcloud.wallet.api.dto.WalletFreezeDto;
import com.bsd.pjcloud.wallet.api.entity.*;
import com.bsd.pjcloud.wallet.api.vo.WalletFreezeVo;
@@ -24,8 +25,8 @@ import com.bsd.pjcloud.wallet.mapper.WalletFreezeMapper;
import com.bsd.pjcloud.wallet.service.WalletCodeUseService;
import com.bsd.pjcloud.wallet.service.WalletFreezeService;
import com.bsd.pjcloud.wallet.service.WalletManageService;
import com.bsd.pjcloud.wallet.service.WalletTypeService;
import com.bsd.pjcloud.wallet.utils.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.dto.WalletFreezeApplyFlowDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -83,22 +84,29 @@ public class WalletFreezeServiceImpl extends ServiceImpl<WalletFreezeMapper, Wal
@Transactional(rollbackFor = Exception.class)
public Long create(WalletFreezeDto dto) {
// 查询发起人
R<UserInfo> userData = userService.getByUserId(dto.getUserId());
if (ObjectUtil.isEmpty(userData.getData())) {
throw new RuntimeException("发起人不存在");
}
UserInfo userData = userService.getByUserId(dto.getUserId()).getData();
if (ObjectUtil.isEmpty(userData)) throw new RuntimeException("发起人不存在");
// 查询钱包
WalletManageEntity wallet = walletManageService.getWallet(dto.getUserId(), dto.getWalletTypeId());
if (ObjectUtil.isEmpty(wallet)) {
throw new RuntimeException("用户钱包不存在");
}
dto.setDeptId(userData.getData().getSysUser().getDeptId());
if (ObjectUtil.isEmpty(wallet)) throw new RuntimeException("用户钱包不存在");
dto.setDeptId(userData.getSysUser().getDeptId());
dto.setFreeStatus(YesNoEnum.NO.getCode());
dto.setWalletId(wallet.getId());
dto.setProcessStatus(TaskCheckStatusEnum.PADDING.getCode());
// 查询部门
SysDept dept = deptService.getDeptByDeptId(dto.getDeptId()).getData();
if (ObjectUtil.isEmpty(dept)) throw new RuntimeException("发起人部门不存在");
baseMapper.insert(dto);
// 发起审批
String processId = flowUtil.startFlow("TASK_FREEZE_FLOW", userData.getData().getSysUser(), dto.getId());
WalletFreezeApplyFlowDto flowDto = new WalletFreezeApplyFlowDto();
flowDto.setApplyUsername(userData.getSysUser().getUsername());
flowDto.setApplyUserId(userData.getSysUser().getUserId());
flowDto.setApplyDeptName(dept.getName());
flowDto.setApplyDeptId(dept.getDeptId());
flowDto.setApplyCreateTime(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN));
flowDto.setCardNumber(wallet.getCardNumber());
flowDto.setRemark(dto.getRemark());
String processId = flowUtil.startFlow("TASK_FREEZE_FLOW", userData.getSysUser(), dto.getId(), flowDto);
baseMapper.updateById(WalletFreezeEntity.builder().id(dto.getId()).processId(processId).build());
return dto.getId();
}
@@ -112,6 +120,10 @@ public class WalletFreezeServiceImpl extends ServiceImpl<WalletFreezeMapper, Wal
.eq(WalletFreezeEntity::getProcessId, processId)
);
if (ObjectUtil.isEmpty(detail)) return;
if (!ObjectUtil.equals(detail.getProcessStatus(), TaskCheckStatusEnum.PADDING.getCode())) {
log.error("|{}|重复的回调,dto:|{}|", TAG);
return;
}
try {
Boolean isConsent = flowUtil.isConsent(dto);
String processStatus = isConsent ? TaskCheckStatusEnum.RESULT.getCode() : TaskCheckStatusEnum.REJECT.getCode();
@@ -1,5 +1,7 @@
package com.bsd.pjcloud.wallet.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -11,6 +13,7 @@ import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.feign.RemoteDeptService;
import com.bsd.pjcloud.admin.api.feign.RemoteUserService;
import com.bsd.pjcloud.admin.api.utils.DataUtil;
import com.bsd.pjcloud.common.core.exception.CheckedException;
import com.bsd.pjcloud.common.core.util.CollectionUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.flow.task.api.feign.RemoteFlowApiFlowService;
@@ -19,18 +22,20 @@ import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.wallet.api.constant.WalletCodeBizEnum;
import com.bsd.pjcloud.wallet.api.dto.WalletStrideDto;
import com.bsd.pjcloud.wallet.api.entity.WalletForeignEntity;
import com.bsd.pjcloud.wallet.api.entity.WalletStrideEntity;
import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeApplyEntity;
import com.bsd.pjcloud.wallet.api.vo.WalletStrideVo;
import com.bsd.pjcloud.wallet.mapper.WalletStrideMapper;
import com.bsd.pjcloud.wallet.service.WalletStrideService;
import com.bsd.pjcloud.wallet.utils.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.dto.WalletStrideApplyFlowDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -66,19 +71,28 @@ public class WalletStrideServiceImpl extends ServiceImpl<WalletStrideMapper, Wal
@Transactional(rollbackFor = Exception.class)
public Long create(WalletStrideDto dto) {
// 查询发起人
R<UserInfo> userData = userService.getByUserId(dto.getUserId());
if (ObjectUtil.isEmpty(userData.getData())) {
throw new RuntimeException("发起人不存在");
}
UserInfo userData = userService.getByUserId(dto.getUserId()).getData();
if (ObjectUtil.isEmpty(userData)) throw new RuntimeException("发起人不存在");
dto.setDeptId(userData.getSysUser().getDeptId());
dto.setProcessStatus(TaskCheckStatusEnum.PADDING.getCode());
// 查询部门
SysDept dept = deptService.getDeptByDeptId(dto.getDeptId()).getData();
if (ObjectUtil.isEmpty(dept)) throw new RuntimeException("发起人部门不存在");
// 判断之前有没有在审核的
if (isCheckData(dto.getUserId())) {
throw new RuntimeException("已提交申请,请勿重复提交");
}
dto.setDeptId(userData.getData().getSysUser().getDeptId());
dto.setProcessStatus(TaskCheckStatusEnum.PADDING.getCode());
baseMapper.insert(dto);
// 发起审批
String processId = flowUtil.startFlow("TASK_STRIDE_FLOW", userData.getData().getSysUser(), dto.getId());
WalletStrideApplyFlowDto flowDto = new WalletStrideApplyFlowDto();
flowDto.setApplyUsername(userData.getSysUser().getUsername());
flowDto.setApplyUserId(userData.getSysUser().getUserId());
flowDto.setApplyDeptName(dept.getName());
flowDto.setApplyDeptId(dept.getDeptId());
flowDto.setApplyCreateTime(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN));
flowDto.setCount(dto.getCount());
flowDto.setRemark(dto.getRemark());
String processId = flowUtil.startFlow("TASK_STRIDE_FLOW", userData.getSysUser(), dto.getId(), flowDto);
baseMapper.updateById(WalletStrideEntity.builder().id(dto.getId()).processId(processId).build());
return dto.getId();
}
@@ -121,6 +135,10 @@ public class WalletStrideServiceImpl extends ServiceImpl<WalletStrideMapper, Wal
.eq(WalletStrideEntity::getProcessId, processId)
);
if (ObjectUtil.isEmpty(detail)) return;
if (!ObjectUtil.equals(detail.getProcessStatus(), TaskCheckStatusEnum.PADDING.getCode())) {
log.error("|{}|重复的回调,dto:|{}|", TAG);
return;
}
try {
Boolean isConsent = flowUtil.isConsent(dto);
String processStatus = isConsent ? TaskCheckStatusEnum.RESULT.getCode() : TaskCheckStatusEnum.REJECT.getCode();
@@ -112,8 +112,7 @@ public class WalletTransactionServiceImpl extends ServiceImpl<WalletTransactionM
}
switch (bizType) {
case UPDATE:
case BATCH:
case RECHARGE: {
case RECHARGE, BATCH: {
walletManageMapper.updateWhenRecharge(wallet.getId(), price);
break;
}
@@ -1,7 +1,11 @@
package com.bsd.pjcloud.wallet.service.impl.recharge;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.admin.api.dto.UserInfo;
@@ -18,14 +22,25 @@ import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.excel.vo.ErrorMessage;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.flow.task.constant.TaskCheckStatusEnum;
import com.bsd.pjcloud.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
import com.bsd.pjcloud.wallet.api.constant.WalletBizEnum;
import com.bsd.pjcloud.wallet.api.constant.WalletBizRechargeEnum;
import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeApplyDto;
import com.bsd.pjcloud.wallet.api.dto.excel.WalletRechargeExcelDto;
import com.bsd.pjcloud.wallet.api.entity.WalletManageEntity;
import com.bsd.pjcloud.wallet.api.entity.WalletTransactionEntity;
import com.bsd.pjcloud.wallet.api.entity.WalletTypeEntity;
import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeApplyEntity;
import com.bsd.pjcloud.wallet.api.entity.recharge.WalletRechargeImportEntity;
import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeApplyVo;
import com.bsd.pjcloud.wallet.mapper.recharge.WalletRechargeApplyMapper;
import com.bsd.pjcloud.wallet.service.WalletManageService;
import com.bsd.pjcloud.wallet.service.WalletRechargeApplyService;
import com.bsd.pjcloud.wallet.service.WalletTransactionService;
import com.bsd.pjcloud.wallet.service.WalletTypeService;
import com.bsd.pjcloud.wallet.utils.flow.FlowUtil;
import com.bsd.pjcloud.wallet.utils.flow.dto.WalletRechargeApplyFlowDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -48,12 +63,18 @@ import java.util.*;
@Service
public class WalletRechargeApplyServiceImpl extends ServiceImpl<WalletRechargeApplyMapper, WalletRechargeApplyEntity> implements WalletRechargeApplyService {
static private final String TAG = "充值/扣款申请";
private final WalletRechargeImportServiceImpl rechargeImportService;
private final WalletManageService walletManageService;
private final WalletTransactionService walletTransactionService;
private final WalletTypeService walletTypeService;
private final RemoteUserService userService;
private final RemoteDeptService deptService;
private final FlowUtil flowUtil;
@Override
public void create(WalletRechargeApplyEntity dto) {
PjcloudUser loginUser = SecurityUtils.getUser();
@@ -83,12 +104,35 @@ public class WalletRechargeApplyServiceImpl extends ServiceImpl<WalletRechargeAp
}
@Override
public void apply(WalletRechargeApplyDto dto) {
WalletRechargeApplyEntity rechargeApply = baseMapper.selectById(dto.getId());
if (ObjectUtil.isEmpty(rechargeApply)) {
throw new CheckedException("充值申请不存在");
}
baseMapper.updateById(dto);
public void apply(Long id) {
// 查询详情
WalletRechargeApplyEntity detail = baseMapper.selectById(id);
if (ObjectUtil.isEmpty(detail)) throw new CheckedException("充值申请不存在");
// 查询用户
UserInfo user = userService.getByUserId(detail.getUserId()).getData();
if (ObjectUtil.isEmpty(user)) throw new CheckedException("发起人不存在");
// 查询部门
SysDept dept = deptService.getDeptByDeptId(detail.getDeptId()).getData();
if (ObjectUtil.isEmpty(dept)) throw new RuntimeException("发起人部门不存在");
// 查询饭卡类型
WalletTypeEntity walletType = walletTypeService.getById(detail.getWalletTypeId());
if (ObjectUtil.isEmpty(walletType)) throw new RuntimeException("饭卡类型不存在");
// 发起审批
WalletRechargeApplyFlowDto flowDto = new WalletRechargeApplyFlowDto();
flowDto.setApplyUsername(user.getSysUser().getUsername());
flowDto.setApplyUserId(user.getSysUser().getUserId());
flowDto.setApplyDeptName(dept.getName());
flowDto.setApplyDeptId(dept.getDeptId());
flowDto.setApplyCreateTime(LocalDateTimeUtil.format(detail.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
flowDto.setWalletTypeStr(walletType.getName());
flowDto.setImportTime(LocalDateTimeUtil.format(detail.getImportTime(), DatePattern.NORM_MONTH_PATTERN));
flowDto.setRemark(detail.getRemark());
String processId = flowUtil.startFlow("TASK_RECHARGE_APPLY_FLOW", user.getSysUser(), detail.getId(), flowDto);
WalletRechargeApplyEntity updateObj = new WalletRechargeApplyEntity();
updateObj.setId(detail.getId());
updateObj.setProcessId(processId);
updateObj.setProcessStatus(TaskCheckStatusEnum.PADDING.getCode());
baseMapper.updateById(updateObj);
}
@Override
@@ -157,4 +201,43 @@ public class WalletRechargeApplyServiceImpl extends ServiceImpl<WalletRechargeAp
}
/* ************************************* end excel end ************************************* */
@Override
@Transactional(rollbackFor = Exception.class)
public void applyCallback(ProcessNodeRecordAssignUserParamDto dto) {
if (!flowUtil.checkCallback(dto)) return;
String processId = dto.getProcessInstanceId();
WalletRechargeApplyEntity detail = baseMapper.selectOne(new LambdaQueryWrapper<WalletRechargeApplyEntity>()
.eq(WalletRechargeApplyEntity::getProcessId, processId)
);
if (ObjectUtil.isEmpty(detail)) return;
if (!ObjectUtil.equals(detail.getProcessStatus(), TaskCheckStatusEnum.PADDING.getCode())) {
log.error("|{}|重复的回调,dto:|{}|", TAG);
return;
}
try {
Boolean isConsent = flowUtil.isConsent(dto);
String processStatus = isConsent ? TaskCheckStatusEnum.RESULT.getCode() : TaskCheckStatusEnum.REJECT.getCode();
baseMapper.updateById(WalletRechargeApplyEntity.builder().id(detail.getId()).processStatus(processStatus).build());
if (isConsent) {
List<WalletRechargeImportEntity> importList = rechargeImportService.list(new LambdaQueryWrapper<WalletRechargeImportEntity>()
.eq(WalletRechargeImportEntity::getApplyId, detail.getId())
);
if (ObjectUtil.isEmpty(importList)) return;
if (ObjectUtil.equals(detail.getBizType(), WalletBizRechargeEnum.REDUCTION.getCode())) {
importList.forEach(v -> v.setPrice(-1 * Math.abs(v.getPrice())));
}
for (WalletRechargeImportEntity v : importList) {
// 查询每个人的钱包余额
WalletManageEntity wallet = walletManageService.getWallet(v.getUserId(), detail.getWalletTypeId());
if (ObjectUtil.isEmpty(wallet)) continue;
walletTransactionService.addWalletBalance(wallet.getId(), v.getPrice(), String.valueOf(v.getId()), WalletBizEnum.BATCH);
}
log.info("|{}|审批回调成功,dto:|{}", TAG, JSON.toJSONString(dto));
}
} catch (Exception e) {
e.printStackTrace();
log.error("|{}|审批回调意外的错误,dto:|{}|error:|{}|", TAG, JSON.toJSONString(dto), e.getMessage());
}
}
}
@@ -21,7 +21,6 @@ import com.bsd.pjcloud.wallet.service.WalletRechargeService;
import com.bsd.pjcloud.wallet.service.WalletTransactionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -1,5 +1,6 @@
package com.bsd.pjcloud.wallet.utils;
package com.bsd.pjcloud.wallet.utils.flow;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
@@ -40,6 +41,10 @@ public class FlowUtil {
private final ObjectMapper objectMapper;
public String startFlow(String flowIdKey, SysUser user, Long businessId) {
return startFlow(flowIdKey, user, businessId, null);
}
public String startFlow(String flowIdKey, SysUser user, Long businessId, Object dto) {
// 发起工作流
String defaultRole = ParamResolver.getStr(flowIdKey);
if (ObjectUtil.isEmpty(defaultRole)) {
@@ -53,7 +58,11 @@ public class FlowUtil {
}
ProcessVO processVo = detail.getData();
ProcessInstanceParamDto processDto = new ProcessInstanceParamDto();
Map<String, Object> paramMap = readMap(processVo, user);
Map<String, Object> dtoMap = null;
if (ObjectUtil.isNotEmpty(dto)) {
dtoMap = BeanUtil.beanToMap(dto);
}
Map<String, Object> paramMap = readMap(user, dtoMap);
processDto.setFlowId(processVo.getFlowId());
processDto.setParamMap(paramMap);
processDto.setStartUserId(String.valueOf(user.getUserId()));
@@ -61,24 +70,14 @@ public class FlowUtil {
return startVo.getData();
}
public Map<String, Object> readMap(ProcessVO vo, SysUser user) {
public Map<String, Object> readMap(SysUser user, Map<String, Object> dtoMap) {
Map<String, Object> paramMap = new HashMap<>();
if (ObjectUtil.isNotEmpty(dtoMap)) paramMap = dtoMap;
Dict rootUser = Dict.create()
.set("id", user.getUserId())
.set("name", user.getUsername())
.set("type", NodeUserTypeEnum.USER.getKey());
paramMap.put("root", CollUtil.newArrayList(rootUser));
try {
List<FormItemVO> formItemVOList = objectMapper.readValue(vo.getFormItems(), new TypeReference<>() {
});
for (FormItemVO v : formItemVOList) {
if (ObjectUtil.equals(v.getType(), "Layout")) continue;
if (!ObjectUtil.isAllNotEmpty(v.getId(), v.getProps())) continue;
paramMap.put(v.getId(), v.getProps().getValue());
}
} catch (Exception e) {
e.printStackTrace();
}
return paramMap;
}
@@ -0,0 +1,24 @@
package com.bsd.pjcloud.wallet.utils.flow.dto;
import com.bsd.pjcloud.flow.task.dto.base.FlowBaseDto;
import lombok.Data;
@Data
public class WalletForeignApplyFlowDto extends FlowBaseDto {
/**
* 申请数量
*/
private Integer count;
/**
* 备注
*/
private String remark;
/**
* 使用时间
*/
private String applyTime;
}
@@ -0,0 +1,20 @@
package com.bsd.pjcloud.wallet.utils.flow.dto;
import com.bsd.pjcloud.flow.task.dto.base.FlowBaseDto;
import lombok.Data;
@Data
public class WalletFreezeApplyFlowDto extends FlowBaseDto {
/**
* 卡号
*/
private String cardNumber;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,24 @@
package com.bsd.pjcloud.wallet.utils.flow.dto;
import com.bsd.pjcloud.flow.task.dto.base.FlowBaseDto;
import lombok.Data;
@Data
public class WalletRechargeApplyFlowDto extends FlowBaseDto {
/**
* 饭卡类型
*/
private String walletTypeStr;
/**
* 充值年月
*/
private String importTime;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,19 @@
package com.bsd.pjcloud.wallet.utils.flow.dto;
import com.bsd.pjcloud.flow.task.dto.base.FlowBaseDto;
import lombok.Data;
@Data
public class WalletStrideApplyFlowDto extends FlowBaseDto {
/**
* 申请数量
*/
private Integer count;
/**
* 备注
*/
private String remark;
}
@@ -19,4 +19,8 @@
<result property="delFlag" column="del_flag"/>
<result property="tenantId" column="tenant_id"/>
</resultMap>
<select id="getLast" resultMap="walletActiveMap">
select * from wallet_active order by card_sort desc limit 1
</select>
</mapper>