更改目录结构

This commit is contained in:
liuyingfang
2024-03-02 18:31:44 +08:00
parent 8f7acca8e6
commit 0a70a66807
603 changed files with 2256 additions and 6114 deletions

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain;
import com.alibaba.fastjson.annotation.JSONField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Objects;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
@Entity
@Getter
@Setter
@Table(name="sys_dept")
public class Dept extends BaseEntity implements Serializable {
@Id
@Column(name = "dept_id")
@NotNull(groups = Update.class)
@ApiModelProperty(value = "ID", hidden = true)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JSONField(serialize = false)
@ManyToMany(mappedBy = "depts")
@ApiModelProperty(value = "角色")
private Set<Role> roles;
@ApiModelProperty(value = "排序")
private Integer deptSort;
@NotBlank
@ApiModelProperty(value = "部门名称")
private String name;
@NotNull
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
@ApiModelProperty(value = "上级部门")
private Long pid;
@ApiModelProperty(value = "子节点数目", hidden = true)
private Integer subCount = 0;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Dept dept = (Dept) o;
return Objects.equals(id, dept.id) &&
Objects.equals(name, dept.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Entity
@Getter
@Setter
@Table(name="sys_dict")
public class Dict extends BaseEntity implements Serializable {
@Id
@Column(name = "dict_id")
@NotNull(groups = Update.class)
@ApiModelProperty(value = "ID", hidden = true)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "dict",cascade={CascadeType.PERSIST,CascadeType.REMOVE})
private List<DictDetail> dictDetails;
@NotBlank
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "描述")
private String description;
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Entity
@Getter
@Setter
@Table(name="sys_dict_detail")
public class DictDetail extends BaseEntity implements Serializable {
@Id
@Column(name = "detail_id")
@NotNull(groups = Update.class)
@ApiModelProperty(value = "ID", hidden = true)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JoinColumn(name = "dict_id")
@ManyToOne(fetch=FetchType.LAZY)
@ApiModelProperty(value = "字典", hidden = true)
private Dict dict;
@ApiModelProperty(value = "字典标签")
private String label;
@ApiModelProperty(value = "字典值")
private String value;
@ApiModelProperty(value = "排序")
private Integer dictSort = 999;
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Objects;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
@Entity
@Getter
@Setter
@Table(name="sys_job")
public class Job extends BaseEntity implements Serializable {
@Id
@Column(name = "job_id")
@NotNull(groups = Update.class)
@ApiModelProperty(value = "ID", hidden = true)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@ApiModelProperty(value = "岗位名称")
private String name;
@NotNull
@ApiModelProperty(value = "岗位排序")
private Long jobSort;
@NotNull
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Job job = (Job) o;
return Objects.equals(id, job.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain;
import com.alibaba.fastjson.annotation.JSONField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Objects;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-12-17
*/
@Entity
@Getter
@Setter
@Table(name = "sys_menu")
public class Menu extends BaseEntity implements Serializable {
@Id
@Column(name = "menu_id")
@NotNull(groups = {Update.class})
@ApiModelProperty(value = "ID", hidden = true)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JSONField(serialize = false)
@ManyToMany(mappedBy = "menus")
@ApiModelProperty(value = "菜单角色")
private Set<Role> roles;
@ApiModelProperty(value = "菜单标题")
private String title;
@Column(name = "name")
@ApiModelProperty(value = "菜单组件名称")
private String componentName;
@ApiModelProperty(value = "排序")
private Integer menuSort = 999;
@ApiModelProperty(value = "组件路径")
private String component;
@ApiModelProperty(value = "路由地址")
private String path;
@ApiModelProperty(value = "菜单类型,目录、菜单、按钮")
private Integer type;
@ApiModelProperty(value = "权限标识")
private String permission;
@ApiModelProperty(value = "菜单图标")
private String icon;
@Column(columnDefinition = "bit(1) default 0")
@ApiModelProperty(value = "缓存")
private Boolean cache;
@Column(columnDefinition = "bit(1) default 0")
@ApiModelProperty(value = "是否隐藏")
private Boolean hidden;
@ApiModelProperty(value = "上级菜单")
private Long pid;
@ApiModelProperty(value = "子节点数目", hidden = true)
private Integer subCount = 0;
@ApiModelProperty(value = "外链菜单")
private Boolean iFrame;
@ApiModelProperty(value = "是否选中父级菜单")
private String activeMenu;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Menu menu = (Menu) o;
return Objects.equals(id, menu.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain;
import com.alibaba.fastjson.annotation.JSONField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity;
import cn.ysk.cashier.utils.enums.DataScopeEnum;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Objects;
import java.util.Set;
/**
* 角色
* @author Zheng Jie
* @date 2018-11-22
*/
@Getter
@Setter
@Entity
@Table(name = "sys_role")
public class Role extends BaseEntity implements Serializable {
@Id
@Column(name = "role_id")
@NotNull(groups = {Update.class})
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "ID", hidden = true)
private Long id;
@JSONField(serialize = false)
@ManyToMany(mappedBy = "roles")
@ApiModelProperty(value = "用户", hidden = true)
private Set<User> users;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "sys_roles_menus",
joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")},
inverseJoinColumns = {@JoinColumn(name = "menu_id",referencedColumnName = "menu_id")})
@ApiModelProperty(value = "菜单", hidden = true)
private Set<Menu> menus;
@ManyToMany
@JoinTable(name = "sys_roles_depts",
joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")},
inverseJoinColumns = {@JoinColumn(name = "dept_id",referencedColumnName = "dept_id")})
@ApiModelProperty(value = "部门", hidden = true)
private Set<Dept> depts;
@NotBlank
@ApiModelProperty(value = "名称", hidden = true)
private String name;
@ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义")
private String dataScope = DataScopeEnum.THIS_LEVEL.getValue();
@Column(name = "level")
@ApiModelProperty(value = "级别,数值越小,级别越大")
private Integer level = 3;
@ApiModelProperty(value = "描述")
private String description;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Role role = (Role) o;
return Objects.equals(id, role.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseEntity;
import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-11-22
*/
@Entity
@Getter
@Setter
@Table(name="sys_user")
public class User extends BaseEntity implements Serializable {
@Id
@Column(name = "user_id")
@NotNull(groups = Update.class)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "ID", hidden = true)
private Long id;
@ManyToMany(fetch = FetchType.EAGER)
@ApiModelProperty(value = "用户角色")
@JoinTable(name = "sys_users_roles",
joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")})
private Set<Role> roles;
@ManyToMany(fetch = FetchType.EAGER)
@ApiModelProperty(value = "用户岗位")
@JoinTable(name = "sys_users_jobs",
joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "job_id",referencedColumnName = "job_id")})
private Set<Job> jobs;
@OneToOne
@JoinColumn(name = "dept_id")
@ApiModelProperty(value = "用户部门")
private Dept dept;
@NotBlank
@Column(unique = true)
@ApiModelProperty(value = "用户名称")
private String username;
@NotBlank
@ApiModelProperty(value = "用户昵称")
private String nickName;
@Email
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "电话号码")
private String phone;
@ApiModelProperty(value = "用户性别")
private String gender;
@ApiModelProperty(value = "头像真实名称",hidden = true)
private String avatarName;
@ApiModelProperty(value = "头像存储的路径", hidden = true)
private String avatarPath;
@ApiModelProperty(value = "密码")
private String password;
@NotNull
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
@ApiModelProperty(value = "是否为admin账号", hidden = true)
private Boolean isAdmin = false;
@Column(name = "pwd_reset_time")
@ApiModelProperty(value = "最后修改密码的时间", hidden = true)
private Date pwdResetTime;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
User user = (User) o;
return Objects.equals(id, user.id) &&
Objects.equals(username, user.username);
}
@Override
public int hashCode() {
return Objects.hash(id, username);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2018-12-20
*/
@Data
@AllArgsConstructor
public class MenuMetaVo implements Serializable {
private String title;
private String icon;
private Boolean noCache;
private String activeMenu;
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 构建前端路由时用到
* @author Zheng Jie
* @date 2018-12-20
*/
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class MenuVo implements Serializable {
private String name;
private String path;
private Boolean hidden;
private String redirect;
private String component;
private Boolean alwaysShow;
private MenuMetaVo meta;
private List<MenuVo> children;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.domain.vo;
import lombok.Data;
/**
* 修改密码的 Vo 类
* @author Zheng Jie
* @date 2019年7月11日13:59:49
*/
@Data
public class UserPassVo {
private String oldPass;
private String newPass;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.Dept;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
public interface DeptRepository extends JpaRepository<Dept, Long>, JpaSpecificationExecutor<Dept> {
/**
* 根据 PID 查询
* @param id pid
* @return /
*/
List<Dept> findByPid(Long id);
/**
* 获取顶级部门
* @return /
*/
List<Dept> findByPidIsNull();
/**
* 根据角色ID 查询
* @param roleId 角色ID
* @return /
*/
@Query(value = "select d.* from sys_dept d, sys_roles_depts r where " +
"d.dept_id = r.dept_id and r.role_id = ?1", nativeQuery = true)
Set<Dept> findByRoleId(Long roleId);
/**
* 判断是否存在子节点
* @param pid /
* @return /
*/
int countByPid(Long pid);
/**
* 根据ID更新sub_count
* @param count /
* @param id /
*/
@Modifying
@Query(value = " update sys_dept set sub_count = ?1 where dept_id = ?2 ",nativeQuery = true)
void updateSubCntById(Integer count, Long id);
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.DictDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
public interface DictDetailRepository extends JpaRepository<DictDetail, Long>, JpaSpecificationExecutor<DictDetail> {
/**
* 根据字典名称查询
* @param name /
* @return /
*/
List<DictDetail> findByDictName(String name);
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.Dict;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
public interface DictRepository extends JpaRepository<Dict, Long>, JpaSpecificationExecutor<Dict> {
/**
* 删除
* @param ids /
*/
void deleteByIdIn(Set<Long> ids);
/**
* 查询
* @param ids /
* @return /
*/
List<Dict> findByIdIn(Set<Long> ids);
@Query("select dict from Dict dict where dict.name =:name")
Dict findByName(@Param("name") String name);
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.Job;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
public interface JobRepository extends JpaRepository<Job, Long>, JpaSpecificationExecutor<Job> {
/**
* 根据名称查询
* @param name 名称
* @return /
*/
Job findByName(String name);
/**
* 根据Id删除
* @param ids /
*/
void deleteAllByIdIn(Set<Long> ids);
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-12-17
*/
public interface MenuRepository extends JpaRepository<Menu, Long>, JpaSpecificationExecutor<Menu> {
/**
* 根据菜单标题查询
* @param title 菜单标题
* @return /
*/
Menu findByTitle(String title);
/**
* 根据组件名称查询
* @param name 组件名称
* @return /
*/
Menu findByComponentName(String name);
/**
* 根据菜单的 PID 查询
* @param pid /
* @return /
*/
List<Menu> findByPidOrderByMenuSort(long pid);
/**
* 查询顶级菜单
* @return /
*/
List<Menu> findByPidIsNullOrderByMenuSort();
/**
* 根据角色ID与菜单类型查询菜单
* @param roleIds roleIDs
* @param type 类型
* @return /
*/
@Query(value = "SELECT m.* FROM sys_menu m, sys_roles_menus r WHERE " +
"m.menu_id = r.menu_id AND r.role_id IN ?1 AND type != ?2 order by m.menu_sort asc",nativeQuery = true)
LinkedHashSet<Menu> findByRoleIdsAndTypeNot(Set<Long> roleIds, int type);
/**
* 获取节点数量
* @param id /
* @return /
*/
int countByPid(Long id);
/**
* 更新节点数目
* @param count /
* @param menuId /
*/
@Modifying
@Query(value = " update sys_menu set sub_count = ?1 where menu_id = ?2 ",nativeQuery = true)
void updateSubCntById(int count, Long menuId);
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-12-03
*/
public interface RoleRepository extends JpaRepository<Role, Long>, JpaSpecificationExecutor<Role> {
/**
* 根据名称查询
* @param name /
* @return /
*/
Role findByName(String name);
/**
* 删除多个角色
* @param ids /
*/
void deleteAllByIdIn(Set<Long> ids);
/**
* 根据用户ID查询
* @param id 用户ID
* @return /
*/
@Query(value = "SELECT r.* FROM sys_role r, sys_users_roles u WHERE " +
"r.role_id = u.role_id AND u.user_id = ?1",nativeQuery = true)
Set<Role> findByUserId(Long id);
/**
* 解绑角色菜单
* @param id 菜单ID
*/
@Modifying
@Query(value = "delete from sys_roles_menus where menu_id = ?1",nativeQuery = true)
void untiedMenu(Long id);
/**
* 根据部门查询
* @param deptIds /
* @return /
*/
@Query(value = "select count(1) from sys_role r, sys_roles_depts d where " +
"r.role_id = d.role_id and d.dept_id in ?1",nativeQuery = true)
int countByDepts(Set<Long> deptIds);
/**
* 根据菜单Id查询
* @param menuIds /
* @return /
*/
@Query(value = "SELECT r.* FROM sys_role r, sys_roles_menus m WHERE " +
"r.role_id = m.role_id AND m.menu_id in ?1",nativeQuery = true)
List<Role> findInMenuId(List<Long> menuIds);
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.repository;
import cn.ysk.cashier.system.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-11-22
*/
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
/**
* 根据用户名查询
* @param username 用户名
* @return /
*/
User findByUsername(String username);
/**
* 根据邮箱查询
* @param email 邮箱
* @return /
*/
User findByEmail(String email);
/**
* 根据手机号查询
* @param phone 手机号
* @return /
*/
User findByPhone(String phone);
/**
* 修改密码
* @param username 用户名
* @param pass 密码
* @param lastPasswordResetTime /
*/
@Modifying
@Query(value = "update sys_user set password = ?2 , pwd_reset_time = ?3 where username = ?1",nativeQuery = true)
void updatePass(String username, String pass, Date lastPasswordResetTime);
/**
* 修改邮箱
* @param username 用户名
* @param email 邮箱
*/
@Modifying
@Query(value = "update sys_user set email = ?2 where username = ?1",nativeQuery = true)
void updateEmail(String username, String email);
/**
* 根据角色查询用户
* @param roleId /
* @return /
*/
@Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r WHERE" +
" u.user_id = r.user_id AND r.role_id = ?1", nativeQuery = true)
List<User> findByRoleId(Long roleId);
/**
* 根据角色中的部门查询
* @param deptId /
* @return /
*/
@Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r, sys_roles_depts d WHERE " +
"u.user_id = r.user_id AND r.role_id = d.role_id AND d.dept_id = ?1 group by u.user_id", nativeQuery = true)
List<User> findByRoleDeptId(Long deptId);
/**
* 根据菜单查询
* @param id 菜单ID
* @return /
*/
@Query(value = "SELECT u.* FROM sys_user u, sys_users_roles ur, sys_roles_menus rm WHERE\n" +
"u.user_id = ur.user_id AND ur.role_id = rm.role_id AND rm.menu_id = ?1 group by u.user_id", nativeQuery = true)
List<User> findByMenuId(Long id);
/**
* 根据Id删除
* @param ids /
*/
void deleteAllByIdIn(Set<Long> ids);
/**
* 根据岗位查询
* @param ids /
* @return /
*/
@Query(value = "SELECT count(1) FROM sys_user u, sys_users_jobs j WHERE u.user_id = j.user_id AND j.job_id IN ?1", nativeQuery = true)
int countByJobs(Set<Long> ids);
/**
* 根据部门查询
* @param deptIds /
* @return /
*/
@Query(value = "SELECT count(1) FROM sys_user u WHERE u.dept_id IN ?1", nativeQuery = true)
int countByDepts(Set<Long> deptIds);
/**
* 根据角色查询
* @param ids /
* @return /
*/
@Query(value = "SELECT count(1) FROM sys_user u, sys_users_roles r WHERE " +
"u.user_id = r.user_id AND r.role_id in ?1", nativeQuery = true)
int countByRoles(Set<Long> ids);
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import cn.hutool.core.collection.CollectionUtil;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.system.service.dto.DeptDto;
import cn.ysk.cashier.system.service.dto.DeptQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.DeptService;
import cn.ysk.cashier.utils.PageUtil;
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.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:部门管理")
@RequestMapping("/api/dept")
public class DeptController {
private final DeptService deptService;
private static final String ENTITY_NAME = "dept";
@ApiOperation("导出部门数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('dept:list')")
public void exportDept(HttpServletResponse response, DeptQueryCriteria criteria) throws Exception {
deptService.download(deptService.queryAll(criteria, false), response);
}
@ApiOperation("查询部门")
@GetMapping
@PreAuthorize("@el.check('user:list','dept:list')")
public ResponseEntity<Object> queryDept(DeptQueryCriteria criteria) throws Exception {
List<DeptDto> deptDtos = deptService.queryAll(criteria, true);
return new ResponseEntity<>(PageUtil.toPage(deptDtos, deptDtos.size()),HttpStatus.OK);
}
@ApiOperation("查询部门:根据ID获取同级与上级数据")
@PostMapping("/superior")
@PreAuthorize("@el.check('user:list','dept:list')")
public ResponseEntity<Object> getDeptSuperior(@RequestBody List<Long> ids) {
Set<DeptDto> deptDtos = new LinkedHashSet<>();
for (Long id : ids) {
DeptDto deptDto = deptService.findById(id);
List<DeptDto> depts = deptService.getSuperior(deptDto, new ArrayList<>());
deptDtos.addAll(depts);
}
return new ResponseEntity<>(deptService.buildTree(new ArrayList<>(deptDtos)),HttpStatus.OK);
}
@Log("新增部门")
@ApiOperation("新增部门")
@PostMapping
@PreAuthorize("@el.check('dept:add')")
public ResponseEntity<Object> createDept(@Validated @RequestBody Dept resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
deptService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改部门")
@ApiOperation("修改部门")
@PutMapping
@PreAuthorize("@el.check('dept:edit')")
public ResponseEntity<Object> updateDept(@Validated(Dept.Update.class) @RequestBody Dept resources){
deptService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除部门")
@ApiOperation("删除部门")
@DeleteMapping
@PreAuthorize("@el.check('dept:del')")
public ResponseEntity<Object> deleteDept(@RequestBody Set<Long> ids){
Set<DeptDto> deptDtos = new HashSet<>();
for (Long id : ids) {
List<Dept> deptList = deptService.findByPid(id);
deptDtos.add(deptService.findById(id));
if(CollectionUtil.isNotEmpty(deptList)){
deptDtos = deptService.getDeleteDepts(deptList, deptDtos);
}
}
// 验证是否被角色或用户关联
deptService.verification(deptDtos);
deptService.delete(deptDtos);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import cn.ysk.cashier.system.domain.Dict;
import cn.ysk.cashier.system.service.dto.DictQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.DictService;
import org.springframework.data.domain.Pageable;
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.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:字典管理")
@RequestMapping("/api/dict")
public class DictController {
private final DictService dictService;
private static final String ENTITY_NAME = "dict";
@ApiOperation("导出字典数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('dict:list')")
public void exportDict(HttpServletResponse response, DictQueryCriteria criteria) throws IOException {
dictService.download(dictService.queryAll(criteria), response);
}
@ApiOperation("查询字典")
@GetMapping(value = "/all")
@PreAuthorize("@el.check('dict:list')")
public ResponseEntity<Object> queryAllDict(){
return new ResponseEntity<>(dictService.queryAll(new DictQueryCriteria()),HttpStatus.OK);
}
@ApiOperation("查询字典")
@GetMapping
@PreAuthorize("@el.check('dict:list')")
public ResponseEntity<Object> queryDict(DictQueryCriteria resources, Pageable pageable){
return new ResponseEntity<>(dictService.queryAll(resources,pageable),HttpStatus.OK);
}
@Log("新增字典")
@ApiOperation("新增字典")
@PostMapping
@PreAuthorize("@el.check('dict:add')")
public ResponseEntity<Object> createDict(@Validated @RequestBody Dict resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
dictService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改字典")
@ApiOperation("修改字典")
@PutMapping
@PreAuthorize("@el.check('dict:edit')")
public ResponseEntity<Object> updateDict(@Validated(Dict.Update.class) @RequestBody Dict resources){
dictService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除字典")
@ApiOperation("删除字典")
@DeleteMapping
@PreAuthorize("@el.check('dict:del')")
public ResponseEntity<Object> deleteDict(@RequestBody Set<Long> ids){
dictService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import cn.ysk.cashier.system.domain.DictDetail;
import cn.ysk.cashier.system.service.dto.DictDetailDto;
import cn.ysk.cashier.system.service.dto.DictDetailQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.DictDetailService;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
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.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:字典详情管理")
@RequestMapping("/api/dictDetail")
public class DictDetailController {
private final DictDetailService dictDetailService;
private static final String ENTITY_NAME = "dictDetail";
@ApiOperation("查询字典详情")
@GetMapping
public ResponseEntity<Object> queryDictDetail(DictDetailQueryCriteria criteria,
@PageableDefault(sort = {"dictSort"}, direction = Sort.Direction.ASC) Pageable pageable){
return new ResponseEntity<>(dictDetailService.queryAll(criteria,pageable),HttpStatus.OK);
}
@ApiOperation("通过dict查询字典详情")
@GetMapping("/{name}")
public ResponseEntity<Object> queryDictById(@PathVariable String name){
return new ResponseEntity<>(dictDetailService.queryName(name),HttpStatus.OK);
}
@ApiOperation("查询多个字典详情")
@GetMapping(value = "/map")
public ResponseEntity<Object> getDictDetailMaps(@RequestParam String dictName){
String[] names = dictName.split("[,]");
Map<String, List<DictDetailDto>> dictMap = new HashMap<>(16);
for (String name : names) {
dictMap.put(name, dictDetailService.getDictByName(name));
}
return new ResponseEntity<>(dictMap, HttpStatus.OK);
}
@Log("新增字典详情")
@ApiOperation("新增字典详情")
@PostMapping
@PreAuthorize("@el.check('dict:add')")
public ResponseEntity<Object> createDictDetail(@Validated @RequestBody DictDetail resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
dictDetailService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改字典详情")
@ApiOperation("修改字典详情")
@PutMapping
@PreAuthorize("@el.check('dict:edit')")
public ResponseEntity<Object> updateDictDetail(@Validated(DictDetail.Update.class) @RequestBody DictDetail resources){
dictDetailService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除字典详情")
@ApiOperation("删除字典详情")
@DeleteMapping(value = "/{id}")
@PreAuthorize("@el.check('dict:del')")
public ResponseEntity<Object> deleteDictDetail(@PathVariable Long id){
dictDetailService.delete(id);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import cn.ysk.cashier.system.domain.Job;
import cn.ysk.cashier.system.service.dto.JobQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.JobService;
import org.springframework.data.domain.Pageable;
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.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:岗位管理")
@RequestMapping("/api/job")
public class JobController {
private final JobService jobService;
private static final String ENTITY_NAME = "job";
@ApiOperation("导出岗位数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('job:list')")
public void exportJob(HttpServletResponse response, JobQueryCriteria criteria) throws IOException {
jobService.download(jobService.queryAll(criteria), response);
}
@ApiOperation("查询岗位")
@GetMapping
@PreAuthorize("@el.check('job:list','user:list')")
public ResponseEntity<Object> queryJob(JobQueryCriteria criteria, Pageable pageable){
return new ResponseEntity<>(jobService.queryAll(criteria, pageable),HttpStatus.OK);
}
@Log("新增岗位")
@ApiOperation("新增岗位")
@PostMapping
@PreAuthorize("@el.check('job:add')")
public ResponseEntity<Object> createJob(@Validated @RequestBody Job resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
jobService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改岗位")
@ApiOperation("修改岗位")
@PutMapping
@PreAuthorize("@el.check('job:edit')")
public ResponseEntity<Object> updateJob(@Validated(Job.Update.class) @RequestBody Job resources){
jobService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除岗位")
@ApiOperation("删除岗位")
@DeleteMapping
@PreAuthorize("@el.check('job:del')")
public ResponseEntity<Object> deleteJob(@RequestBody Set<Long> ids){
// 验证是否被用户关联
jobService.verification(ids);
jobService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import cn.ysk.cashier.annotation.Limit;
import cn.ysk.cashier.annotation.rest.AnonymousGetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author /
* 接口限流测试类
*/
@RestController
@RequestMapping("/api/limit")
@Api(tags = "系统:限流测试管理")
public class LimitController {
private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger();
/**
* 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次保存到redis的键名为 limit_test
*/
@AnonymousGetMapping
@ApiOperation("测试")
@Limit(key = "test", period = 60, count = 10, name = "testLimit", prefix = "limit")
public int testLimit() {
return ATOMIC_INTEGER.incrementAndGet();
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import cn.hutool.core.collection.CollectionUtil;
import cn.ysk.cashier.system.domain.Menu;
import cn.ysk.cashier.system.service.dto.MenuDto;
import cn.ysk.cashier.system.service.dto.MenuQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.MenuService;
import cn.ysk.cashier.system.service.mapstruct.MenuMapper;
import cn.ysk.cashier.utils.PageUtil;
import cn.ysk.cashier.utils.SecurityUtils;
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.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
* @date 2018-12-03
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:菜单管理")
@RequestMapping("/api/menus")
public class MenuController {
private final MenuService menuService;
private final MenuMapper menuMapper;
private static final String ENTITY_NAME = "menu";
@ApiOperation("导出菜单数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('menu:list')")
public void exportMenu(HttpServletResponse response, MenuQueryCriteria criteria) throws Exception {
menuService.download(menuService.queryAll(criteria, false), response);
}
@GetMapping(value = "/build")
@ApiOperation("获取前端所需菜单")
public ResponseEntity<Object> buildMenus(){
List<MenuDto> menuDtoList = menuService.findByUser(SecurityUtils.getCurrentUserId());
List<MenuDto> menuDtos = menuService.buildTree(menuDtoList);
return new ResponseEntity<>(menuService.buildMenus(menuDtos),HttpStatus.OK);
}
@ApiOperation("返回全部的菜单")
@GetMapping(value = "/lazy")
@PreAuthorize("@el.check('menu:list','roles:list')")
public ResponseEntity<Object> queryAllMenu(@RequestParam Long pid){
return new ResponseEntity<>(menuService.getMenus(pid),HttpStatus.OK);
}
@ApiOperation("根据菜单ID返回所有子节点ID包含自身ID")
@GetMapping(value = "/child")
@PreAuthorize("@el.check('menu:list','roles:list')")
public ResponseEntity<Object> childMenu(@RequestParam Long id){
Set<Menu> menuSet = new HashSet<>();
List<MenuDto> menuList = menuService.getMenus(id);
menuSet.add(menuService.findOne(id));
menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet);
Set<Long> ids = menuSet.stream().map(Menu::getId).collect(Collectors.toSet());
return new ResponseEntity<>(ids,HttpStatus.OK);
}
@GetMapping
@ApiOperation("查询菜单")
@PreAuthorize("@el.check('menu:list')")
public ResponseEntity<Object> queryMenu(MenuQueryCriteria criteria) throws Exception {
List<MenuDto> menuDtoList = menuService.queryAll(criteria, true);
return new ResponseEntity<>(PageUtil.toPage(menuDtoList, menuDtoList.size()),HttpStatus.OK);
}
@ApiOperation("查询菜单:根据ID获取同级与上级数据")
@PostMapping("/superior")
@PreAuthorize("@el.check('menu:list')")
public ResponseEntity<Object> getMenuSuperior(@RequestBody List<Long> ids) {
Set<MenuDto> menuDtos = new LinkedHashSet<>();
if(CollectionUtil.isNotEmpty(ids)){
for (Long id : ids) {
MenuDto menuDto = menuService.findById(id);
menuDtos.addAll(menuService.getSuperior(menuDto, new ArrayList<>()));
}
return new ResponseEntity<>(menuService.buildTree(new ArrayList<>(menuDtos)),HttpStatus.OK);
}
return new ResponseEntity<>(menuService.getMenus(null),HttpStatus.OK);
}
@Log("新增菜单")
@ApiOperation("新增菜单")
@PostMapping
@PreAuthorize("@el.check('menu:add')")
public ResponseEntity<Object> createMenu(@Validated @RequestBody Menu resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
menuService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改菜单")
@ApiOperation("修改菜单")
@PutMapping
@PreAuthorize("@el.check('menu:edit')")
public ResponseEntity<Object> updateMenu(@Validated(Menu.Update.class) @RequestBody Menu resources){
menuService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除菜单")
@ApiOperation("删除菜单")
@DeleteMapping
@PreAuthorize("@el.check('menu:del')")
public ResponseEntity<Object> deleteMenu(@RequestBody Set<Long> ids){
Set<Menu> menuSet = new HashSet<>();
for (Long id : ids) {
List<MenuDto> menuList = menuService.getMenus(id);
menuSet.add(menuService.findOne(id));
menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet);
}
menuService.delete(menuSet);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.system.service.MonitorService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* @author Zheng Jie
* @date 2020-05-02
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统-服务监控管理")
@RequestMapping("/api/monitor")
public class MonitorController {
private final MonitorService serverService;
@GetMapping
@ApiOperation("查询服务监控")
@PreAuthorize("@el.check('monitor:list')")
public ResponseEntity<Object> queryMonitor(){
return new ResponseEntity<>(serverService.getServers(),HttpStatus.OK);
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import cn.hutool.core.lang.Dict;
import cn.ysk.cashier.system.domain.Role;
import cn.ysk.cashier.system.service.dto.RoleDto;
import cn.ysk.cashier.system.service.dto.RoleQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.RoleService;
import cn.ysk.cashier.system.service.dto.RoleSmallDto;
import cn.ysk.cashier.utils.SecurityUtils;
import org.springframework.data.domain.Pageable;
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.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
* @date 2018-12-03
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:角色管理")
@RequestMapping("/api/roles")
public class RoleController {
private final RoleService roleService;
private static final String ENTITY_NAME = "role";
@ApiOperation("获取单个role")
@GetMapping(value = "/{id}")
@PreAuthorize("@el.check('roles:list')")
public ResponseEntity<Object> findRoleById(@PathVariable Long id){
return new ResponseEntity<>(roleService.findById(id), HttpStatus.OK);
}
@ApiOperation("导出角色数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('role:list')")
public void exportRole(HttpServletResponse response, RoleQueryCriteria criteria) throws IOException {
roleService.download(roleService.queryAll(criteria), response);
}
@ApiOperation("返回全部的角色")
@GetMapping(value = "/all")
@PreAuthorize("@el.check('roles:list','user:add','user:edit')")
public ResponseEntity<Object> queryAllRole(){
return new ResponseEntity<>(roleService.queryAll(),HttpStatus.OK);
}
@ApiOperation("查询角色")
@GetMapping
@PreAuthorize("@el.check('roles:list')")
public ResponseEntity<Object> queryRole(RoleQueryCriteria criteria, Pageable pageable){
return new ResponseEntity<>(roleService.queryAll(criteria,pageable),HttpStatus.OK);
}
@ApiOperation("获取用户级别")
@GetMapping(value = "/level")
public ResponseEntity<Object> getRoleLevel(){
return new ResponseEntity<>(Dict.create().set("level", getLevels(null)),HttpStatus.OK);
}
@Log("新增角色")
@ApiOperation("新增角色")
@PostMapping
@PreAuthorize("@el.check('roles:add')")
public ResponseEntity<Object> createRole(@Validated @RequestBody Role resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
getLevels(resources.getLevel());
roleService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改角色")
@ApiOperation("修改角色")
@PutMapping
@PreAuthorize("@el.check('roles:edit')")
public ResponseEntity<Object> updateRole(@Validated(Role.Update.class) @RequestBody Role resources){
getLevels(resources.getLevel());
roleService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("修改角色菜单")
@ApiOperation("修改角色菜单")
@PutMapping(value = "/menu")
@PreAuthorize("@el.check('roles:edit')")
public ResponseEntity<Object> updateRoleMenu(@RequestBody Role resources){
RoleDto role = roleService.findById(resources.getId());
getLevels(role.getLevel());
roleService.updateMenu(resources,role);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除角色")
@ApiOperation("删除角色")
@DeleteMapping
@PreAuthorize("@el.check('roles:del')")
public ResponseEntity<Object> deleteRole(@RequestBody Set<Long> ids){
for (Long id : ids) {
RoleDto role = roleService.findById(id);
getLevels(role.getLevel());
}
// 验证是否被用户关联
roleService.verification(ids);
roleService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 获取用户的角色级别
* @return /
*/
private int getLevels(Integer level){
List<Integer> levels = roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList());
int min = Collections.min(levels);
if(level != null){
if(level < min){
throw new BadRequestException("权限不足,你的角色级别:" + min + ",低于操作的角色级别:" + level);
}
}
return min;
}
}

View File

@@ -0,0 +1,203 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import cn.hutool.core.collection.CollectionUtil;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.domain.vo.UserPassVo;
import cn.ysk.cashier.system.service.dto.UserDto;
import cn.ysk.cashier.system.service.dto.UserQueryCriteria;
import cn.ysk.cashier.utils.PageUtil;
import cn.ysk.cashier.utils.RsaUtils;
import cn.ysk.cashier.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.config.RsaProperties;
import cn.ysk.cashier.system.service.DataService;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.DeptService;
import cn.ysk.cashier.system.service.RoleService;
import cn.ysk.cashier.system.service.dto.RoleSmallDto;
import cn.ysk.cashier.system.service.VerifyService;
import cn.ysk.cashier.system.service.UserService;
import cn.ysk.cashier.utils.enums.CodeEnum;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Api(tags = "系统:用户管理")
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final PasswordEncoder passwordEncoder;
private final UserService userService;
private final DataService dataService;
private final DeptService deptService;
private final RoleService roleService;
private final VerifyService verificationCodeService;
@ApiOperation("导出用户数据")
@GetMapping(value = "/download")
@PreAuthorize("@el.check('user:list')")
public void exportUser(HttpServletResponse response, UserQueryCriteria criteria) throws IOException {
userService.download(userService.queryAll(criteria), response);
}
@ApiOperation("查询用户")
@GetMapping
@PreAuthorize("@el.check('user:list')")
public ResponseEntity<Object> queryUser(UserQueryCriteria criteria, Pageable pageable){
if (!ObjectUtils.isEmpty(criteria.getDeptId())) {
criteria.getDeptIds().add(criteria.getDeptId());
// 先查找是否存在子节点
List<Dept> data = deptService.findByPid(criteria.getDeptId());
// 然后把子节点的ID都加入到集合中
criteria.getDeptIds().addAll(deptService.getDeptChildren(data));
}
// 数据权限
List<Long> dataScopes = dataService.getDeptIds(userService.findByName(SecurityUtils.getCurrentUsername()));
// criteria.getDeptIds() 不为空并且数据权限不为空则取交集
if (!CollectionUtils.isEmpty(criteria.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)){
// 取交集
criteria.getDeptIds().retainAll(dataScopes);
if(!CollectionUtil.isEmpty(criteria.getDeptIds())){
return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK);
}
} else {
// 否则取并集
criteria.getDeptIds().addAll(dataScopes);
return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK);
}
return new ResponseEntity<>(PageUtil.toPage(null,0),HttpStatus.OK);
}
@Log("新增用户")
@ApiOperation("新增用户")
@PostMapping
@PreAuthorize("@el.check('user:add')")
public ResponseEntity<Object> createUser(@Validated @RequestBody User resources){
checkLevel(resources);
// 默认密码 123456
resources.setPassword(passwordEncoder.encode("123456"));
userService.create(resources);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@Log("修改用户")
@ApiOperation("修改用户")
@PutMapping
@PreAuthorize("@el.check('user:edit')")
public ResponseEntity<Object> updateUser(@Validated(User.Update.class) @RequestBody User resources) throws Exception {
checkLevel(resources);
userService.update(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("修改用户:个人中心")
@ApiOperation("修改用户:个人中心")
@PutMapping(value = "center")
public ResponseEntity<Object> centerUser(@Validated(User.Update.class) @RequestBody User resources){
if(!resources.getId().equals(SecurityUtils.getCurrentUserId())){
throw new BadRequestException("不能修改他人资料");
}
userService.updateCenter(resources);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除用户")
@ApiOperation("删除用户")
@DeleteMapping
@PreAuthorize("@el.check('user:del')")
public ResponseEntity<Object> deleteUser(@RequestBody Set<Long> ids){
for (Long id : ids) {
Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
Integer optLevel = Collections.min(roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足,不能删除:" + userService.findById(id).getUsername());
}
}
userService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
@ApiOperation("修改密码")
@PostMapping(value = "/updatePass")
public ResponseEntity<Object> updateUserPass(@RequestBody UserPassVo passVo) throws Exception {
String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getOldPass());
String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getNewPass());
UserDto user = userService.findByName(SecurityUtils.getCurrentUsername());
if(!passwordEncoder.matches(oldPass, user.getPassword())){
throw new BadRequestException("修改失败,旧密码错误");
}
if(passwordEncoder.matches(newPass, user.getPassword())){
throw new BadRequestException("新密码不能与旧密码相同");
}
userService.updatePass(user.getUsername(),passwordEncoder.encode(newPass));
return new ResponseEntity<>(HttpStatus.OK);
}
@ApiOperation("修改头像")
@PostMapping(value = "/updateAvatar")
public ResponseEntity<Object> updateUserAvatar(@RequestParam MultipartFile avatar){
return new ResponseEntity<>(userService.updateAvatar(avatar), HttpStatus.OK);
}
@Log("修改邮箱")
@ApiOperation("修改邮箱")
@PostMapping(value = "/updateEmail/{code}")
public ResponseEntity<Object> updateUserEmail(@PathVariable String code,@RequestBody User user) throws Exception {
String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,user.getPassword());
UserDto userDto = userService.findByName(SecurityUtils.getCurrentUsername());
if(!passwordEncoder.matches(password, userDto.getPassword())){
throw new BadRequestException("密码错误");
}
verificationCodeService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + user.getEmail(), code);
userService.updateEmail(userDto.getUsername(),user.getEmail());
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
* @param resources /
*/
private void checkLevel(User resources) {
Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
Integer optLevel = roleService.findByRoles(resources.getRoles());
if (currentLevel > optLevel) {
throw new BadRequestException("角色权限不足");
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.domain.vo.EmailVo;
import cn.ysk.cashier.service.EmailService;
import cn.ysk.cashier.system.service.VerifyService;
import cn.ysk.cashier.utils.enums.CodeBiEnum;
import cn.ysk.cashier.utils.enums.CodeEnum;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
/**
* @author Zheng Jie
* @date 2018-12-26
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/code")
@Api(tags = "系统:验证码管理")
public class VerifyController {
private final VerifyService verificationCodeService;
private final EmailService emailService;
@PostMapping(value = "/resetEmail")
@ApiOperation("重置邮箱,发送验证码")
public ResponseEntity<Object> resetEmail(@RequestParam String email){
EmailVo emailVo = verificationCodeService.sendEmail(email, CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey());
emailService.send(emailVo,emailService.find());
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping(value = "/email/resetPass")
@ApiOperation("重置密码,发送验证码")
public ResponseEntity<Object> resetPass(@RequestParam String email){
EmailVo emailVo = verificationCodeService.sendEmail(email, CodeEnum.EMAIL_RESET_PWD_CODE.getKey());
emailService.send(emailVo,emailService.find());
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping(value = "/validated")
@ApiOperation("验证码验证")
public ResponseEntity<Object> validated(@RequestParam String email, @RequestParam String code, @RequestParam Integer codeBi){
CodeBiEnum biEnum = CodeBiEnum.find(codeBi);
switch (Objects.requireNonNull(biEnum)){
case ONE:
verificationCodeService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + email ,code);
break;
case TWO:
verificationCodeService.validated(CodeEnum.EMAIL_RESET_PWD_CODE.getKey() + email ,code);
break;
default:
break;
}
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.service.dto.UserDto;
import java.util.List;
/**
* 数据权限服务类
* @author Zheng Jie
* @date 2020-05-07
*/
public interface DataService {
/**
* 获取数据权限
* @param user /
* @return /
*/
List<Long> getDeptIds(UserDto user);
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.system.service.dto.DeptDto;
import cn.ysk.cashier.system.service.dto.DeptQueryCriteria;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
public interface DeptService {
/**
* 查询所有数据
* @param criteria 条件
* @param isQuery /
* @throws Exception /
* @return /
*/
List<DeptDto> queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception;
/**
* 根据ID查询
* @param id /
* @return /
*/
DeptDto findById(Long id);
/**
* 创建
* @param resources /
*/
void create(Dept resources);
/**
* 编辑
* @param resources /
*/
void update(Dept resources);
/**
* 删除
* @param deptDtos /
*
*/
void delete(Set<DeptDto> deptDtos);
/**
* 根据PID查询
* @param pid /
* @return /
*/
List<Dept> findByPid(long pid);
/**
* 根据角色ID查询
* @param id /
* @return /
*/
Set<Dept> findByRoleId(Long id);
/**
* 导出数据
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<DeptDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 获取待删除的部门
* @param deptList /
* @param deptDtos /
* @return /
*/
Set<DeptDto> getDeleteDepts(List<Dept> deptList, Set<DeptDto> deptDtos);
/**
* 根据ID获取同级与上级数据
* @param deptDto /
* @param depts /
* @return /
*/
List<DeptDto> getSuperior(DeptDto deptDto, List<Dept> depts);
/**
* 构建树形数据
* @param deptDtos /
* @return /
*/
Object buildTree(List<DeptDto> deptDtos);
/**
* 获取
* @param deptList
* @return
*/
List<Long> getDeptChildren(List<Dept> deptList);
/**
* 验证是否被角色或用户关联
* @param deptDtos /
*/
void verification(Set<DeptDto> deptDtos);
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.domain.DictDetail;
import cn.ysk.cashier.system.service.dto.DictDetailDto;
import cn.ysk.cashier.system.service.dto.DictDetailQueryCriteria;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
public interface DictDetailService {
/**
* 创建
* @param resources /
*/
void create(DictDetail resources);
/**
* 编辑
* @param resources /
*/
void update(DictDetail resources);
/**
* 删除
* @param id /
*/
void delete(Long id);
List<DictDetail> queryName(String name);
/**
* 分页查询
* @param criteria 条件
* @param pageable 分页参数
* @return /
*/
Map<String,Object> queryAll(DictDetailQueryCriteria criteria, Pageable pageable);
/**
* 根据字典名称获取字典详情
* @param name 字典名称
* @return /
*/
List<DictDetailDto> getDictByName(String name);
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.domain.Dict;
import cn.ysk.cashier.system.service.dto.DictDto;
import cn.ysk.cashier.system.service.dto.DictQueryCriteria;
import org.springframework.data.domain.Pageable;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
public interface DictService {
/**
* 分页查询
* @param criteria 条件
* @param pageable 分页参数
* @return /
*/
Map<String,Object> queryAll(DictQueryCriteria criteria, Pageable pageable);
/**
* 查询全部数据
* @param dict /
* @return /
*/
List<DictDto> queryAll(DictQueryCriteria dict);
/**
* 创建
* @param resources /
* @return /
*/
void create(Dict resources);
/**
* 编辑
* @param resources /
*/
void update(Dict resources);
/**
* 删除
* @param ids /
*/
void delete(Set<Long> ids);
/**
* 导出数据
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<DictDto> queryAll, HttpServletResponse response) throws IOException;
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.domain.Job;
import cn.ysk.cashier.system.service.dto.JobDto;
import cn.ysk.cashier.system.service.dto.JobQueryCriteria;
import org.springframework.data.domain.Pageable;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
public interface JobService {
/**
* 根据ID查询
* @param id /
* @return /
*/
JobDto findById(Long id);
/**
* 创建
* @param resources /
* @return /
*/
void create(Job resources);
/**
* 编辑
* @param resources /
*/
void update(Job resources);
/**
* 删除
* @param ids /
*/
void delete(Set<Long> ids);
/**
* 分页查询
* @param criteria 条件
* @param pageable 分页参数
* @return /
*/
Map<String,Object> queryAll(JobQueryCriteria criteria, Pageable pageable);
/**
* 查询全部数据
* @param criteria /
* @return /
*/
List<JobDto> queryAll(JobQueryCriteria criteria);
/**
* 导出数据
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<JobDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 验证是否被用户关联
* @param ids /
*/
void verification(Set<Long> ids);
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.domain.Menu;
import cn.ysk.cashier.system.service.dto.MenuDto;
import cn.ysk.cashier.system.service.dto.MenuQueryCriteria;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-12-17
*/
public interface MenuService {
/**
* 查询全部数据
* @param criteria 条件
* @param isQuery /
* @throws Exception /
* @return /
*/
List<MenuDto> queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception;
/**
* 根据ID查询
* @param id /
* @return /
*/
MenuDto findById(long id);
/**
* 创建
* @param resources /
*/
void create(Menu resources);
/**
* 编辑
* @param resources /
*/
void update(Menu resources);
/**
* 获取所有子节点包含自身ID
* @param menuList /
* @param menuSet /
* @return /
*/
Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet);
/**
* 构建菜单树
* @param menuDtos 原始数据
* @return /
*/
List<MenuDto> buildTree(List<MenuDto> menuDtos);
/**
* 构建菜单树
* @param menuDtos /
* @return /
*/
Object buildMenus(List<MenuDto> menuDtos);
/**
* 根据ID查询
* @param id /
* @return /
*/
Menu findOne(Long id);
/**
* 删除
* @param menuSet /
*/
void delete(Set<Menu> menuSet);
/**
* 导出
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<MenuDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 懒加载菜单数据
* @param pid /
* @return /
*/
List<MenuDto> getMenus(Long pid);
/**
* 根据ID获取同级与上级数据
* @param menuDto /
* @param objects /
* @return /
*/
List<MenuDto> getSuperior(MenuDto menuDto, List<Menu> objects);
/**
* 根据当前用户获取菜单
* @param currentUserId /
* @return /
*/
List<MenuDto> findByUser(Long currentUserId);
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import java.util.Map;
/**
* @author Zheng Jie
* @date 2020-05-02
*/
public interface MonitorService {
/**
* 查询数据分页
* @return Map<String,Object>
*/
Map<String,Object> getServers();
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.domain.Role;
import cn.ysk.cashier.system.service.dto.RoleDto;
import cn.ysk.cashier.system.service.dto.RoleQueryCriteria;
import cn.ysk.cashier.system.service.dto.UserDto;
import cn.ysk.cashier.config.security.service.dto.AuthorityDto;
import cn.ysk.cashier.system.service.dto.RoleSmallDto;
import org.springframework.data.domain.Pageable;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-12-03
*/
public interface RoleService {
/**
* 查询全部数据
* @return /
*/
List<RoleDto> queryAll();
/**
* 根据ID查询
* @param id /
* @return /
*/
RoleDto findById(long id);
/**
* 创建
* @param resources /
*/
void create(Role resources);
/**
* 编辑
* @param resources /
*/
void update(Role resources);
/**
* 删除
* @param ids /
*/
void delete(Set<Long> ids);
/**
* 根据用户ID查询
* @param id 用户ID
* @return /
*/
List<RoleSmallDto> findByUsersId(Long id);
/**
* 根据角色查询角色级别
* @param roles /
* @return /
*/
Integer findByRoles(Set<Role> roles);
/**
* 修改绑定的菜单
* @param resources /
* @param roleDTO /
*/
void updateMenu(Role resources, RoleDto roleDTO);
/**
* 解绑菜单
* @param id /
*/
void untiedMenu(Long id);
/**
* 待条件分页查询
* @param criteria 条件
* @param pageable 分页参数
* @return /
*/
Object queryAll(RoleQueryCriteria criteria, Pageable pageable);
/**
* 查询全部
* @param criteria 条件
* @return /
*/
List<RoleDto> queryAll(RoleQueryCriteria criteria);
/**
* 导出数据
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<RoleDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 获取用户权限信息
* @param user 用户信息
* @return 权限信息
*/
List<AuthorityDto> mapToGrantedAuthorities(UserDto user);
/**
* 验证是否被用户关联
* @param ids /
*/
void verification(Set<Long> ids);
/**
* 根据菜单Id查询
* @param menuIds /
* @return /
*/
List<Role> findInMenuId(List<Long> menuIds);
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.service.dto.UserDto;
import cn.ysk.cashier.system.service.dto.UserQueryCriteria;
import cn.ysk.cashier.system.service.dto.UserLoginDto;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
public interface UserService {
/**
* 根据ID查询
* @param id ID
* @return /
*/
UserDto findById(long id);
/**
* 新增用户
* @param resources /
*/
void create(User resources);
/**
* 编辑用户
* @param resources /
* @throws Exception /
*/
void update(User resources) throws Exception;
/**
* 删除用户
* @param ids /
*/
void delete(Set<Long> ids);
/**
* 根据用户名查询
* @param userName /
* @return /
*/
UserDto findByName(String userName);
/**
* 根据用户名查询
* @param userName /
* @return /
*/
UserLoginDto getLoginData(String userName);
/**
* 修改密码
* @param username 用户名
* @param encryptPassword 密码
*/
void updatePass(String username, String encryptPassword);
/**
* 修改头像
* @param file 文件
* @return /
*/
Map<String, String> updateAvatar(MultipartFile file);
/**
* 修改邮箱
* @param username 用户名
* @param email 邮箱
*/
void updateEmail(String username, String email);
/**
* 查询全部
* @param criteria 条件
* @param pageable 分页参数
* @return /
*/
Object queryAll(UserQueryCriteria criteria, Pageable pageable);
/**
* 查询全部不分页
* @param criteria 条件
* @return /
*/
List<UserDto> queryAll(UserQueryCriteria criteria);
/**
* 导出数据
* @param queryAll 待导出的数据
* @param response /
* @throws IOException /
*/
void download(List<UserDto> queryAll, HttpServletResponse response) throws IOException;
/**
* 用户自助修改资料
* @param resources /
*/
void updateCenter(User resources);
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service;
import cn.ysk.cashier.domain.vo.EmailVo;
/**
* @author Zheng Jie
* @date 2018-12-26
*/
public interface VerifyService {
/**
* 发送验证码
* @param email /
* @param key /
* @return /
*/
EmailVo sendEmail(String email, String key);
/**
* 验证
* @param code /
* @param key /
*/
void validated(String key, String code);
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseDTO;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
@Getter
@Setter
public class DeptDto extends BaseDTO implements Serializable {
private Long id;
private String name;
private Boolean enabled;
private Integer deptSort;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<DeptDto> children;
private Long pid;
private Integer subCount;
public Boolean getHasChildren() {
return subCount > 0;
}
public Boolean getLeaf() {
return subCount <= 0;
}
public String getLabel() {
return name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DeptDto deptDto = (DeptDto) o;
return Objects.equals(id, deptDto.id) &&
Objects.equals(name, deptDto.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import cn.ysk.cashier.annotation.DataPermission;
import cn.ysk.cashier.annotation.Query;
import java.sql.Timestamp;
import java.util.List;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
@Data
@DataPermission(fieldName = "id")
public class DeptQueryCriteria{
@Query(type = Query.Type.INNER_LIKE)
private String name;
@Query
private Boolean enabled;
@Query
private Long pid;
@Query(type = Query.Type.IS_NULL, propName = "pid")
private Boolean pidIsNull;
@Query(type = Query.Type.BETWEEN)
private List<Timestamp> createTime;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2019-6-10 16:32:18
*/
@Data
public class DeptSmallDto implements Serializable {
private Long id;
private String name;
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseDTO;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Getter
@Setter
public class DictDetailDto extends BaseDTO implements Serializable {
private Long id;
private DictSmallDto dict;
private String label;
private String value;
private Integer dictSort;
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import cn.ysk.cashier.annotation.Query;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Data
public class DictDetailQueryCriteria {
@Query(type = Query.Type.INNER_LIKE)
private String label;
@Query(propName = "name",joinName = "dict")
private String dictName;
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseDTO;
import java.io.Serializable;
import java.util.List;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Getter
@Setter
public class DictDto extends BaseDTO implements Serializable {
private Long id;
private List<DictDetailDto> dictDetails;
private String name;
private String description;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import cn.ysk.cashier.annotation.Query;
/**
* @author Zheng Jie
* 公共查询类
*/
@Data
public class DictQueryCriteria {
@Query(blurry = "name,description")
private String blurry;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Getter
@Setter
public class DictSmallDto implements Serializable {
private Long id;
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import cn.ysk.cashier.base.BaseDTO;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
@Getter
@Setter
@NoArgsConstructor
public class JobDto extends BaseDTO implements Serializable {
private Long id;
private Integer jobSort;
private String name;
private Boolean enabled;
public JobDto(String name, Boolean enabled) {
this.name = name;
this.enabled = enabled;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
import cn.ysk.cashier.annotation.Query;
import java.sql.Timestamp;
import java.util.List;
/**
* @author Zheng Jie
* @date 2019-6-4 14:49:34
*/
@Data
@NoArgsConstructor
public class JobQueryCriteria {
@Query(type = Query.Type.INNER_LIKE)
private String name;
@Query
private Boolean enabled;
@Query(type = Query.Type.BETWEEN)
private List<Timestamp> createTime;
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2019-6-10 16:32:18
*/
@Data
@NoArgsConstructor
public class JobSmallDto implements Serializable {
private Long id;
private String name;
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseDTO;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
/**
* @author Zheng Jie
* @date 2018-12-17
*/
@Getter
@Setter
public class MenuDto extends BaseDTO implements Serializable {
private Long id;
private List<MenuDto> children;
private Integer type;
private String permission;
private String title;
private Integer menuSort;
private String path;
private String component;
private Long pid;
private Integer subCount;
private Boolean iFrame;
private Boolean cache;
private Boolean hidden;
private String componentName;
private String icon;
private String activeMenu;
public Boolean getHasChildren() {
return subCount > 0;
}
public Boolean getLeaf() {
return subCount <= 0;
}
public String getLabel() {
return title;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MenuDto menuDto = (MenuDto) o;
return Objects.equals(id, menuDto.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import cn.ysk.cashier.annotation.Query;
import java.sql.Timestamp;
import java.util.List;
/**
* @author Zheng Jie
* 公共查询类
*/
@Data
public class MenuQueryCriteria {
@Query(blurry = "title,component,permission")
private String blurry;
@Query(type = Query.Type.BETWEEN)
private List<Timestamp> createTime;
@Query(type = Query.Type.IS_NULL, propName = "pid")
private Boolean pidIsNull;
@Query
private Long pid;
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseDTO;
import java.io.Serializable;
import java.util.Objects;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Getter
@Setter
public class RoleDto extends BaseDTO implements Serializable {
private Long id;
private Set<MenuDto> menus;
private Set<DeptDto> depts;
private String name;
private String dataScope;
private Integer level;
private String description;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RoleDto roleDto = (RoleDto) o;
return Objects.equals(id, roleDto.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import cn.ysk.cashier.annotation.Query;
import java.sql.Timestamp;
import java.util.List;
/**
* @author Zheng Jie
* 公共查询类
*/
@Data
public class RoleQueryCriteria {
@Query(blurry = "name,description")
private String blurry;
@Query(type = Query.Type.BETWEEN)
private List<Timestamp> createTime;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Data
public class RoleSmallDto implements Serializable {
private Long id;
private String name;
private Integer level;
private String dataScope;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Getter;
import lombok.Setter;
import cn.ysk.cashier.base.BaseDTO;
import java.io.Serializable;
import java.util.Date;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Getter
@Setter
public class UserDto extends BaseDTO implements Serializable {
private Long id;
private Set<RoleSmallDto> roles;
private Set<JobSmallDto> jobs;
private DeptSmallDto dept;
private Long deptId;
private String username;
private String nickName;
private String email;
private String phone;
private String gender;
private String avatarName;
private String avatarPath;
@JSONField(serialize = false)
private String password;
private Boolean enabled;
@JSONField(serialize = false)
private Boolean isAdmin = false;
private Date pwdResetTime;
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
/**
* @author Zheng Jie
* @description 用户缓存时使用
* @date 2022-05-26
**/
public class UserLoginDto extends UserDto {
private String password;
private Boolean isAdmin;
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.dto;
import lombok.Data;
import cn.ysk.cashier.annotation.Query;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Data
public class UserQueryCriteria implements Serializable {
@Query
private Long id;
@Query(propName = "id", type = Query.Type.IN, joinName = "dept")
private Set<Long> deptIds = new HashSet<>();
@Query(blurry = "email,username,nickName")
private String blurry;
@Query
private Boolean enabled;
private Long deptId;
@Query(type = Query.Type.BETWEEN)
private List<Timestamp> createTime;
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.system.service.DeptService;
import cn.ysk.cashier.system.service.RoleService;
import cn.ysk.cashier.system.service.dto.UserDto;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.system.service.DataService;
import cn.ysk.cashier.system.service.dto.RoleSmallDto;
import cn.ysk.cashier.utils.enums.DataScopeEnum;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author Zheng Jie
* @website https://eladmin.vip
* @description 数据权限服务实现
* @date 2020-05-07
**/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "data")
public class DataServiceImpl implements DataService {
private final RoleService roleService;
private final DeptService deptService;
/**
* 用户角色和用户部门改变时需清理缓存
* @param user /
* @return /
*/
@Override
@Cacheable(key = "'user:' + #p0.id")
public List<Long> getDeptIds(UserDto user) {
// 用于存储部门id
Set<Long> deptIds = new HashSet<>();
// 查询用户角色
List<RoleSmallDto> roleSet = roleService.findByUsersId(user.getId());
// 获取对应的部门ID
for (RoleSmallDto role : roleSet) {
DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope());
switch (Objects.requireNonNull(dataScopeEnum)) {
case THIS_LEVEL:
deptIds.add(user.getDept().getId());
break;
case CUSTOMIZE:
deptIds.addAll(getCustomize(deptIds, role));
break;
default:
return new ArrayList<>(deptIds);
}
}
return new ArrayList<>(deptIds);
}
/**
* 获取自定义的数据权限
* @param deptIds 部门ID
* @param role 角色
* @return 数据权限ID
*/
public Set<Long> getCustomize(Set<Long> deptIds, RoleSmallDto role){
Set<Dept> depts = deptService.findByRoleId(role.getId());
for (Dept dept : depts) {
deptIds.add(dept.getId());
List<Dept> deptChildren = deptService.findByPid(dept.getId());
if (deptChildren != null && deptChildren.size() != 0) {
deptIds.addAll(deptService.getDeptChildren(deptChildren));
}
}
return deptIds;
}
}

View File

@@ -0,0 +1,283 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.repository.DeptRepository;
import cn.ysk.cashier.system.repository.RoleRepository;
import cn.ysk.cashier.system.repository.UserRepository;
import cn.ysk.cashier.system.service.DeptService;
import cn.ysk.cashier.system.service.dto.DeptDto;
import cn.ysk.cashier.system.service.dto.DeptQueryCriteria;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.system.service.mapstruct.DeptMapper;
import cn.ysk.cashier.utils.enums.DataScopeEnum;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dept")
public class DeptServiceImpl implements DeptService {
private final DeptRepository deptRepository;
private final DeptMapper deptMapper;
private final UserRepository userRepository;
private final RedisUtils redisUtils;
private final RoleRepository roleRepository;
@Override
public List<DeptDto> queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception {
Sort sort = Sort.by(Sort.Direction.ASC, "deptSort");
String dataScopeType = SecurityUtils.getDataScopeType();
if (isQuery) {
if(dataScopeType.equals(DataScopeEnum.ALL.getValue())){
criteria.setPidIsNull(true);
}
List<Field> fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>());
List<String> fieldNames = new ArrayList<String>(){{ add("pidIsNull");add("enabled");}};
for (Field field : fields) {
//设置对象的访问权限保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(criteria);
if(fieldNames.contains(field.getName())){
continue;
}
if (ObjectUtil.isNotNull(val)) {
criteria.setPidIsNull(null);
break;
}
}
}
List<DeptDto> list = deptMapper.toDto(deptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort));
// 如果为空,就代表为自定义权限或者本级权限,就需要去重,不理解可以注释掉,看查询结果
if(StringUtils.isBlank(dataScopeType)){
return deduplication(list);
}
return list;
}
@Override
@Cacheable(key = "'id:' + #p0")
public DeptDto findById(Long id) {
Dept dept = deptRepository.findById(id).orElseGet(Dept::new);
ValidationUtil.isNull(dept.getId(),"Dept","id",id);
return deptMapper.toDto(dept);
}
@Override
public List<Dept> findByPid(long pid) {
return deptRepository.findByPid(pid);
}
@Override
public Set<Dept> findByRoleId(Long id) {
return deptRepository.findByRoleId(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Dept resources) {
deptRepository.save(resources);
// 计算子节点数目
resources.setSubCount(0);
// 清理缓存
updateSubCnt(resources.getPid());
// 清理自定义角色权限的datascope缓存
delCaches(resources.getPid());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Dept resources) {
// 旧的部门
Long oldPid = findById(resources.getId()).getPid();
Long newPid = resources.getPid();
if(resources.getPid() != null && resources.getId().equals(resources.getPid())) {
throw new BadRequestException("上级不能为自己");
}
Dept dept = deptRepository.findById(resources.getId()).orElseGet(Dept::new);
ValidationUtil.isNull( dept.getId(),"Dept","id",resources.getId());
resources.setId(dept.getId());
deptRepository.save(resources);
// 更新父节点中子节点数目
updateSubCnt(oldPid);
updateSubCnt(newPid);
// 清理缓存
delCaches(resources.getId());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<DeptDto> deptDtos) {
for (DeptDto deptDto : deptDtos) {
// 清理缓存
delCaches(deptDto.getId());
deptRepository.deleteById(deptDto.getId());
updateSubCnt(deptDto.getPid());
}
}
@Override
public void download(List<DeptDto> deptDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (DeptDto deptDTO : deptDtos) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("部门名称", deptDTO.getName());
map.put("部门状态", deptDTO.getEnabled() ? "启用" : "停用");
map.put("创建日期", deptDTO.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
@Override
public Set<DeptDto> getDeleteDepts(List<Dept> menuList, Set<DeptDto> deptDtos) {
for (Dept dept : menuList) {
deptDtos.add(deptMapper.toDto(dept));
List<Dept> depts = deptRepository.findByPid(dept.getId());
if(depts!=null && depts.size()!=0){
getDeleteDepts(depts, deptDtos);
}
}
return deptDtos;
}
@Override
public List<Long> getDeptChildren(List<Dept> deptList) {
List<Long> list = new ArrayList<>();
deptList.forEach(dept -> {
if (dept!=null && dept.getEnabled()) {
List<Dept> depts = deptRepository.findByPid(dept.getId());
if (depts.size() != 0) {
list.addAll(getDeptChildren(depts));
}
list.add(dept.getId());
}
}
);
return list;
}
@Override
public List<DeptDto> getSuperior(DeptDto deptDto, List<Dept> depts) {
if(deptDto.getPid() == null){
depts.addAll(deptRepository.findByPidIsNull());
return deptMapper.toDto(depts);
}
depts.addAll(deptRepository.findByPid(deptDto.getPid()));
return getSuperior(findById(deptDto.getPid()), depts);
}
@Override
public Object buildTree(List<DeptDto> deptDtos) {
Set<DeptDto> trees = new LinkedHashSet<>();
Set<DeptDto> depts= new LinkedHashSet<>();
List<String> deptNames = deptDtos.stream().map(DeptDto::getName).collect(Collectors.toList());
boolean isChild;
for (DeptDto deptDTO : deptDtos) {
isChild = false;
if (deptDTO.getPid() == null) {
trees.add(deptDTO);
}
for (DeptDto it : deptDtos) {
if (it.getPid() != null && deptDTO.getId().equals(it.getPid())) {
isChild = true;
if (deptDTO.getChildren() == null) {
deptDTO.setChildren(new ArrayList<>());
}
deptDTO.getChildren().add(it);
}
}
if(isChild) {
depts.add(deptDTO);
} else if(deptDTO.getPid() != null && !deptNames.contains(findById(deptDTO.getPid()).getName())) {
depts.add(deptDTO);
}
}
if (CollectionUtil.isEmpty(trees)) {
trees = depts;
}
Map<String,Object> map = new HashMap<>(2);
map.put("totalElements",deptDtos.size());
map.put("content",CollectionUtil.isEmpty(trees)? deptDtos :trees);
return map;
}
@Override
public void verification(Set<DeptDto> deptDtos) {
Set<Long> deptIds = deptDtos.stream().map(DeptDto::getId).collect(Collectors.toSet());
if(userRepository.countByDepts(deptIds) > 0){
throw new BadRequestException("所选部门存在用户关联,请解除后再试!");
}
if(roleRepository.countByDepts(deptIds) > 0){
throw new BadRequestException("所选部门存在角色关联,请解除后再试!");
}
}
private void updateSubCnt(Long deptId){
if(deptId != null){
int count = deptRepository.countByPid(deptId);
deptRepository.updateSubCntById(count, deptId);
}
}
private List<DeptDto> deduplication(List<DeptDto> list) {
List<DeptDto> deptDtos = new ArrayList<>();
for (DeptDto deptDto : list) {
boolean flag = true;
for (DeptDto dto : list) {
if (dto.getId().equals(deptDto.getPid())) {
flag = false;
break;
}
}
if (flag){
deptDtos.add(deptDto);
}
}
return deptDtos;
}
/**
* 清理缓存
* @param id /
*/
public void delCaches(Long id){
List<User> users = userRepository.findByRoleDeptId(id);
// 删除数据权限
redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet()));
redisUtils.del(CacheKey.DEPT_ID + id);
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.ysk.cashier.system.domain.Dict;
import cn.ysk.cashier.system.domain.DictDetail;
import cn.ysk.cashier.system.repository.DictDetailRepository;
import cn.ysk.cashier.system.repository.DictRepository;
import cn.ysk.cashier.system.service.DictDetailService;
import cn.ysk.cashier.system.service.dto.DictDetailDto;
import cn.ysk.cashier.system.service.dto.DictDetailQueryCriteria;
import cn.ysk.cashier.system.service.mapstruct.DictDetailMapper;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.exception.BadRequestException;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dict")
public class DictDetailServiceImpl implements DictDetailService {
private final DictRepository dictRepository;
private final DictDetailRepository dictDetailRepository;
private final DictDetailMapper dictDetailMapper;
private final RedisUtils redisUtils;
@Override
public Map<String,Object> queryAll(DictDetailQueryCriteria criteria, Pageable pageable) {
Page<DictDetail> page = dictDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(dictDetailMapper::toDto));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(DictDetail resources) {
dictDetailRepository.save(resources);
// 清理缓存
delCaches(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(DictDetail resources) {
DictDetail dictDetail = dictDetailRepository.findById(resources.getId()).orElseGet(DictDetail::new);
ValidationUtil.isNull( dictDetail.getId(),"DictDetail","id",resources.getId());
resources.setId(dictDetail.getId());
dictDetailRepository.save(resources);
// 清理缓存
delCaches(resources);
}
@Override
@Cacheable(key = "'name:' + #p0")
public List<DictDetailDto> getDictByName(String name) {
return dictDetailMapper.toDto(dictDetailRepository.findByDictName(name));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
DictDetail dictDetail = dictDetailRepository.findById(id).orElseGet(DictDetail::new);
// 清理缓存
delCaches(dictDetail);
dictDetailRepository.deleteById(id);
}
@Override
public List<DictDetail> queryName(String name) {
Dict byName = dictRepository.findByName(name);
if (byName.getId() == null){
throw new BadRequestException("字典值有误");
}
return byName.getDictDetails();
}
public void delCaches(DictDetail dictDetail){
Dict dict = dictRepository.findById(dictDetail.getDict().getId()).orElseGet(Dict::new);
redisUtils.del(CacheKey.DICT_NAME + dict.getName());
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.ysk.cashier.system.domain.Dict;
import cn.ysk.cashier.system.repository.DictRepository;
import cn.ysk.cashier.system.service.DictService;
import cn.ysk.cashier.system.service.dto.DictDetailDto;
import cn.ysk.cashier.system.service.dto.DictDto;
import cn.ysk.cashier.system.service.dto.DictQueryCriteria;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.system.service.mapstruct.DictMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dict")
public class DictServiceImpl implements DictService {
private final DictRepository dictRepository;
private final DictMapper dictMapper;
private final RedisUtils redisUtils;
@Override
public Map<String, Object> queryAll(DictQueryCriteria dict, Pageable pageable){
Page<Dict> page = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb), pageable);
return PageUtil.toPage(page.map(dictMapper::toDto));
}
@Override
public List<DictDto> queryAll(DictQueryCriteria dict) {
List<Dict> list = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb));
return dictMapper.toDto(list);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Dict resources) {
dictRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Dict resources) {
// 清理缓存
delCaches(resources);
Dict dict = dictRepository.findById(resources.getId()).orElseGet(Dict::new);
ValidationUtil.isNull( dict.getId(),"Dict","id",resources.getId());
dict.setName(resources.getName());
dict.setDescription(resources.getDescription());
dictRepository.save(dict);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Long> ids) {
// 清理缓存
List<Dict> dicts = dictRepository.findByIdIn(ids);
for (Dict dict : dicts) {
delCaches(dict);
}
dictRepository.deleteByIdIn(ids);
}
@Override
public void download(List<DictDto> dictDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (DictDto dictDTO : dictDtos) {
if(CollectionUtil.isNotEmpty(dictDTO.getDictDetails())){
for (DictDetailDto dictDetail : dictDTO.getDictDetails()) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("字典名称", dictDTO.getName());
map.put("字典描述", dictDTO.getDescription());
map.put("字典标签", dictDetail.getLabel());
map.put("字典值", dictDetail.getValue());
map.put("创建日期", dictDetail.getCreateTime());
list.add(map);
}
} else {
Map<String,Object> map = new LinkedHashMap<>();
map.put("字典名称", dictDTO.getName());
map.put("字典描述", dictDTO.getDescription());
map.put("字典标签", null);
map.put("字典值", null);
map.put("创建日期", dictDTO.getCreateTime());
list.add(map);
}
}
FileUtil.downloadExcel(list, response);
}
public void delCaches(Dict dict){
redisUtils.del(CacheKey.DICT_NAME + dict.getName());
}
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.ysk.cashier.system.service.dto.JobQueryCriteria;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.exception.EntityExistException;
import cn.ysk.cashier.system.domain.Job;
import cn.ysk.cashier.system.repository.UserRepository;
import cn.ysk.cashier.system.repository.JobRepository;
import cn.ysk.cashier.system.service.JobService;
import cn.ysk.cashier.system.service.dto.JobDto;
import cn.ysk.cashier.system.service.mapstruct.JobMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "job")
public class JobServiceImpl implements JobService {
private final JobRepository jobRepository;
private final JobMapper jobMapper;
private final RedisUtils redisUtils;
private final UserRepository userRepository;
@Override
public Map<String,Object> queryAll(JobQueryCriteria criteria, Pageable pageable) {
Page<Job> page = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(jobMapper::toDto).getContent(),page.getTotalElements());
}
@Override
public List<JobDto> queryAll(JobQueryCriteria criteria) {
List<Job> list = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder));
return jobMapper.toDto(list);
}
@Override
@Cacheable(key = "'id:' + #p0")
public JobDto findById(Long id) {
Job job = jobRepository.findById(id).orElseGet(Job::new);
ValidationUtil.isNull(job.getId(),"Job","id",id);
return jobMapper.toDto(job);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Job resources) {
Job job = jobRepository.findByName(resources.getName());
if(job != null){
throw new EntityExistException(Job.class,"name",resources.getName());
}
jobRepository.save(resources);
}
@Override
@CacheEvict(key = "'id:' + #p0.id")
@Transactional(rollbackFor = Exception.class)
public void update(Job resources) {
Job job = jobRepository.findById(resources.getId()).orElseGet(Job::new);
Job old = jobRepository.findByName(resources.getName());
if(old != null && !old.getId().equals(resources.getId())){
throw new EntityExistException(Job.class,"name",resources.getName());
}
ValidationUtil.isNull( job.getId(),"Job","id",resources.getId());
resources.setId(job.getId());
jobRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Long> ids) {
jobRepository.deleteAllByIdIn(ids);
// 删除缓存
redisUtils.delByKeys(CacheKey.JOB_ID, ids);
}
@Override
public void download(List<JobDto> jobDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (JobDto jobDTO : jobDtos) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("岗位名称", jobDTO.getName());
map.put("岗位状态", jobDTO.getEnabled() ? "启用" : "停用");
map.put("创建日期", jobDTO.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
@Override
public void verification(Set<Long> ids) {
if(userRepository.countByJobs(ids) > 0){
throw new BadRequestException("所选的岗位中存在用户关联,请解除关联再试!");
}
}
}

View File

@@ -0,0 +1,360 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.ysk.cashier.system.domain.Menu;
import cn.ysk.cashier.system.domain.Role;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.domain.vo.MenuVo;
import cn.ysk.cashier.system.repository.MenuRepository;
import cn.ysk.cashier.system.repository.UserRepository;
import cn.ysk.cashier.system.service.MenuService;
import cn.ysk.cashier.system.service.RoleService;
import cn.ysk.cashier.system.service.dto.MenuDto;
import cn.ysk.cashier.system.service.dto.MenuQueryCriteria;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.system.domain.vo.MenuMetaVo;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.exception.EntityExistException;
import cn.ysk.cashier.system.service.dto.RoleSmallDto;
import cn.ysk.cashier.system.service.mapstruct.MenuMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "menu")
public class MenuServiceImpl implements MenuService {
private final MenuRepository menuRepository;
private final UserRepository userRepository;
private final MenuMapper menuMapper;
private final RoleService roleService;
private final RedisUtils redisUtils;
private static final String HTTP_PRE = "http://";
private static final String HTTPS_PRE = "https://";
private static final String YES_STR = "";
private static final String NO_STR = "";
private static final String BAD_REQUEST = "外链必须以http://或者https://开头";
@Override
public List<MenuDto> queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception {
Sort sort = Sort.by(Sort.Direction.ASC, "menuSort");
if(Boolean.TRUE.equals(isQuery)){
criteria.setPidIsNull(true);
List<Field> fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>());
for (Field field : fields) {
//设置对象的访问权限保证对private的属性的访问
field.setAccessible(true);
Object val = field.get(criteria);
if("pidIsNull".equals(field.getName())){
continue;
}
if (ObjectUtil.isNotNull(val)) {
criteria.setPidIsNull(null);
break;
}
}
}
return menuMapper.toDto(menuRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort));
}
@Override
@Cacheable(key = "'id:' + #p0")
public MenuDto findById(long id) {
Menu menu = menuRepository.findById(id).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Menu","id",id);
return menuMapper.toDto(menu);
}
/**
* 用户角色改变时需清理缓存
* @param currentUserId /
* @return /
*/
@Override
@Cacheable(key = "'user:' + #p0")
public List<MenuDto> findByUser(Long currentUserId) {
List<RoleSmallDto> roles = roleService.findByUsersId(currentUserId);
Set<Long> roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet());
LinkedHashSet<Menu> menus = menuRepository.findByRoleIdsAndTypeNot(roleIds, 2);
return menus.stream().map(menuMapper::toDto).collect(Collectors.toList());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Menu resources) {
if(menuRepository.findByTitle(resources.getTitle()) != null){
throw new EntityExistException(Menu.class,"title",resources.getTitle());
}
if(StringUtils.isNotBlank(resources.getComponentName())){
if(menuRepository.findByComponentName(resources.getComponentName()) != null){
throw new EntityExistException(Menu.class,"componentName",resources.getComponentName());
}
}
if (Long.valueOf(0L).equals(resources.getPid())) {
resources.setPid(null);
}
if(resources.getIFrame()){
if (!(resources.getPath().toLowerCase().startsWith(HTTP_PRE)||resources.getPath().toLowerCase().startsWith(HTTPS_PRE))) {
throw new BadRequestException(BAD_REQUEST);
}
}
menuRepository.save(resources);
// 计算子节点数目
resources.setSubCount(0);
// 更新父节点菜单数目
updateSubCnt(resources.getPid());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Menu resources) {
if(resources.getId().equals(resources.getPid())) {
throw new BadRequestException("上级不能为自己");
}
Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId());
if(resources.getIFrame()){
if (!(resources.getPath().toLowerCase().startsWith(HTTP_PRE)||resources.getPath().toLowerCase().startsWith(HTTPS_PRE))) {
throw new BadRequestException(BAD_REQUEST);
}
}
Menu menu1 = menuRepository.findByTitle(resources.getTitle());
if(menu1 != null && !menu1.getId().equals(menu.getId())){
throw new EntityExistException(Menu.class,"title",resources.getTitle());
}
if(resources.getPid().equals(0L)){
resources.setPid(null);
}
// 记录的父节点ID
Long oldPid = menu.getPid();
Long newPid = resources.getPid();
if(StringUtils.isNotBlank(resources.getComponentName())){
menu1 = menuRepository.findByComponentName(resources.getComponentName());
if(menu1 != null && !menu1.getId().equals(menu.getId())){
throw new EntityExistException(Menu.class,"componentName",resources.getComponentName());
}
}
menu.setTitle(resources.getTitle());
menu.setComponent(resources.getComponent());
menu.setPath(resources.getPath());
menu.setIcon(resources.getIcon());
menu.setIFrame(resources.getIFrame());
menu.setPid(resources.getPid());
menu.setMenuSort(resources.getMenuSort());
menu.setCache(resources.getCache());
menu.setHidden(resources.getHidden());
menu.setComponentName(resources.getComponentName());
menu.setPermission(resources.getPermission());
menu.setType(resources.getType());
menu.setActiveMenu(resources.getActiveMenu());
menuRepository.save(menu);
// 计算父级菜单节点数目
updateSubCnt(oldPid);
updateSubCnt(newPid);
// 清理缓存
delCaches(resources.getId());
}
@Override
public Set<Menu> getChildMenus(List<Menu> menuList, Set<Menu> menuSet) {
for (Menu menu : menuList) {
menuSet.add(menu);
List<Menu> menus = menuRepository.findByPidOrderByMenuSort(menu.getId());
if(menus!=null && menus.size()!=0){
getChildMenus(menus, menuSet);
}
}
return menuSet;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Menu> menuSet) {
for (Menu menu : menuSet) {
// 清理缓存
delCaches(menu.getId());
roleService.untiedMenu(menu.getId());
menuRepository.deleteById(menu.getId());
updateSubCnt(menu.getPid());
}
}
@Override
public List<MenuDto> getMenus(Long pid) {
List<Menu> menus;
if(pid != null && !pid.equals(0L)){
menus = menuRepository.findByPidOrderByMenuSort(pid);
} else {
menus = menuRepository.findByPidIsNullOrderByMenuSort();
}
return menuMapper.toDto(menus);
}
@Override
public List<MenuDto> getSuperior(MenuDto menuDto, List<Menu> menus) {
if(menuDto.getPid() == null){
menus.addAll(menuRepository.findByPidIsNullOrderByMenuSort());
return menuMapper.toDto(menus);
}
menus.addAll(menuRepository.findByPidOrderByMenuSort(menuDto.getPid()));
return getSuperior(findById(menuDto.getPid()), menus);
}
@Override
public List<MenuDto> buildTree(List<MenuDto> menuDtos) {
List<MenuDto> trees = new ArrayList<>();
Set<Long> ids = new HashSet<>();
for (MenuDto menuDTO : menuDtos) {
if (menuDTO.getPid() == null) {
trees.add(menuDTO);
}
for (MenuDto it : menuDtos) {
if (menuDTO.getId().equals(it.getPid())) {
if (menuDTO.getChildren() == null) {
menuDTO.setChildren(new ArrayList<>());
}
menuDTO.getChildren().add(it);
ids.add(it.getId());
}
}
}
if(trees.size() == 0){
trees = menuDtos.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList());
}
return trees;
}
@Override
public List<MenuVo> buildMenus(List<MenuDto> menuDtos) {
List<MenuVo> list = new LinkedList<>();
menuDtos.forEach(menuDTO -> {
if (menuDTO!=null){
List<MenuDto> menuDtoList = menuDTO.getChildren();
MenuVo menuVo = new MenuVo();
menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getTitle());
// 一级目录需要加斜杠,不然会报警告
menuVo.setPath(menuDTO.getPid() == null ? "/" + menuDTO.getPath() :menuDTO.getPath());
menuVo.setHidden(menuDTO.getHidden());
// 如果不是外链
if(!menuDTO.getIFrame()){
if(menuDTO.getPid() == null){
menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent());
// 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单
}else if(menuDTO.getType() == 0){
menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"ParentView":menuDTO.getComponent());
}else if(StringUtils.isNoneBlank(menuDTO.getComponent())){
menuVo.setComponent(menuDTO.getComponent());
}
}
menuVo.setMeta(new MenuMetaVo(menuDTO.getTitle(),menuDTO.getIcon(),!menuDTO.getCache(),menuDTO.getActiveMenu()));
if(CollectionUtil.isNotEmpty(menuDtoList)){
menuVo.setAlwaysShow(true);
menuVo.setRedirect("noredirect");
menuVo.setChildren(buildMenus(menuDtoList));
// 处理是一级菜单并且没有子菜单的情况
} else if(menuDTO.getPid() == null){
MenuVo menuVo1 = new MenuVo();
menuVo1.setMeta(menuVo.getMeta());
// 非外链
if(!menuDTO.getIFrame()){
menuVo1.setPath("index");
menuVo1.setName(menuVo.getName());
menuVo1.setComponent(menuVo.getComponent());
} else {
menuVo1.setPath(menuDTO.getPath());
}
menuVo.setName(null);
menuVo.setMeta(null);
menuVo.setComponent("Layout");
List<MenuVo> list1 = new ArrayList<>();
list1.add(menuVo1);
menuVo.setChildren(list1);
}
list.add(menuVo);
}
}
);
return list;
}
@Override
public Menu findOne(Long id) {
Menu menu = menuRepository.findById(id).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Menu","id",id);
return menu;
}
@Override
public void download(List<MenuDto> menuDtos, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (MenuDto menuDTO : menuDtos) {
Map<String,Object> map = new LinkedHashMap<>();
map.put("菜单标题", menuDTO.getTitle());
map.put("菜单类型", menuDTO.getType() == null ? "目录" : menuDTO.getType() == 1 ? "菜单" : "按钮");
map.put("权限标识", menuDTO.getPermission());
map.put("外链菜单", menuDTO.getIFrame() ? YES_STR : NO_STR);
map.put("菜单可见", menuDTO.getHidden() ? NO_STR : YES_STR);
map.put("是否缓存", menuDTO.getCache() ? YES_STR : NO_STR);
map.put("创建日期", menuDTO.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
private void updateSubCnt(Long menuId){
if(menuId != null){
int count = menuRepository.countByPid(menuId);
menuRepository.updateSubCntById(count, menuId);
}
}
/**
* 清理缓存
* @param id 菜单ID
*/
public void delCaches(Long id){
List<User> users = userRepository.findByMenuId(id);
redisUtils.del(CacheKey.MENU_ID + id);
redisUtils.delByKeys(CacheKey.MENU_USER, users.stream().map(User::getId).collect(Collectors.toSet()));
// 清除 Role 缓存
List<Role> roles = roleService.findInMenuId(new ArrayList<Long>(){{
add(id);
}});
redisUtils.delByKeys(CacheKey.ROLE_ID, roles.stream().map(Role::getId).collect(Collectors.toSet()));
}
}

View File

@@ -0,0 +1,192 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.hutool.core.date.BetweenFormatter.Level;
import cn.hutool.core.date.DateUtil;
import cn.ysk.cashier.system.service.MonitorService;
import cn.ysk.cashier.utils.ElAdminConstant;
import cn.ysk.cashier.utils.FileUtil;
import cn.ysk.cashier.utils.StringUtils;
import org.springframework.stereotype.Service;
import oshi.SystemInfo;
import oshi.hardware.*;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil;
import oshi.util.Util;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.*;
/**
* @author Zheng Jie
* @date 2020-05-02
*/
@Service
public class MonitorServiceImpl implements MonitorService {
private final DecimalFormat df = new DecimalFormat("0.00");
@Override
public Map<String,Object> getServers(){
Map<String, Object> resultMap = new LinkedHashMap<>(8);
try {
SystemInfo si = new SystemInfo();
OperatingSystem os = si.getOperatingSystem();
HardwareAbstractionLayer hal = si.getHardware();
// 系统信息
resultMap.put("sys", getSystemInfo(os));
// cpu 信息
resultMap.put("cpu", getCpuInfo(hal.getProcessor()));
// 内存信息
resultMap.put("memory", getMemoryInfo(hal.getMemory()));
// 交换区信息
resultMap.put("swap", getSwapInfo(hal.getMemory()));
// 磁盘
resultMap.put("disk", getDiskInfo(os));
resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss"));
} catch (Exception e) {
e.printStackTrace();
}
return resultMap;
}
/**
* 获取磁盘信息
* @return /
*/
private Map<String,Object> getDiskInfo(OperatingSystem os) {
Map<String,Object> diskInfo = new LinkedHashMap<>();
FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores();
String osName = System.getProperty("os.name");
long available = 0, total = 0;
for (OSFileStore fs : fsArray){
// windows 需要将所有磁盘分区累加linux 和 mac 直接累加会出现磁盘重复的问题,待修复
if(osName.toLowerCase().startsWith(ElAdminConstant.WIN)) {
available += fs.getUsableSpace();
total += fs.getTotalSpace();
} else {
available = fs.getUsableSpace();
total = fs.getTotalSpace();
break;
}
}
long used = total - available;
diskInfo.put("total", total > 0 ? FileUtil.getSize(total) : "?");
diskInfo.put("available", FileUtil.getSize(available));
diskInfo.put("used", FileUtil.getSize(used));
if(total != 0){
diskInfo.put("usageRate", df.format(used/(double)total * 100));
} else {
diskInfo.put("usageRate", 0);
}
return diskInfo;
}
/**
* 获取交换区信息
* @param memory /
* @return /
*/
private Map<String,Object> getSwapInfo(GlobalMemory memory) {
Map<String,Object> swapInfo = new LinkedHashMap<>();
VirtualMemory virtualMemory = memory.getVirtualMemory();
long total = virtualMemory.getSwapTotal();
long used = virtualMemory.getSwapUsed();
swapInfo.put("total", FormatUtil.formatBytes(total));
swapInfo.put("used", FormatUtil.formatBytes(used));
swapInfo.put("available", FormatUtil.formatBytes(total - used));
if(used == 0){
swapInfo.put("usageRate", 0);
} else {
swapInfo.put("usageRate", df.format(used/(double)total * 100));
}
return swapInfo;
}
/**
* 获取内存信息
* @param memory /
* @return /
*/
private Map<String,Object> getMemoryInfo(GlobalMemory memory) {
Map<String,Object> memoryInfo = new LinkedHashMap<>();
memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal()));
memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable()));
memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable()));
memoryInfo.put("usageRate", df.format((memory.getTotal() - memory.getAvailable())/(double)memory.getTotal() * 100));
return memoryInfo;
}
/**
* 获取Cpu相关信息
* @param processor /
* @return /
*/
private Map<String,Object> getCpuInfo(CentralProcessor processor) {
Map<String,Object> cpuInfo = new LinkedHashMap<>();
cpuInfo.put("name", processor.getProcessorIdentifier().getName());
cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU");
cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心");
cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount());
cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU");
// CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks();
// 默认等待300毫秒...
long time = 300;
Util.sleep(time);
long[] ticks = processor.getSystemCpuLoadTicks();
while (Arrays.toString(prevTicks).equals(Arrays.toString(ticks)) && time < 1000){
time += 25;
Util.sleep(25);
ticks = processor.getSystemCpuLoadTicks();
}
long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal;
cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu));
cpuInfo.put("idle", df.format(100d * idle / totalCpu));
return cpuInfo;
}
/**
* 获取系统相关信息,系统、运行天数、系统IP
* @param os /
* @return /
*/
private Map<String,Object> getSystemInfo(OperatingSystem os){
Map<String,Object> systemInfo = new LinkedHashMap<>();
// jvm 运行时间
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
Date date = new Date(time);
// 计算项目运行时间
String formatBetween = DateUtil.formatBetween(date, new Date(), Level.HOUR);
// 系统信息
systemInfo.put("os", os.toString());
systemInfo.put("day", formatBetween);
systemInfo.put("ip", StringUtils.getLocalIp());
return systemInfo;
}
}

View File

@@ -0,0 +1,224 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.ysk.cashier.system.domain.Menu;
import cn.ysk.cashier.system.domain.Role;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.repository.RoleRepository;
import cn.ysk.cashier.system.repository.UserRepository;
import cn.ysk.cashier.system.service.RoleService;
import cn.ysk.cashier.system.service.dto.RoleDto;
import cn.ysk.cashier.system.service.dto.RoleQueryCriteria;
import cn.ysk.cashier.system.service.dto.UserDto;
import cn.ysk.cashier.system.service.mapstruct.RoleSmallMapper;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.config.security.service.UserCacheManager;
import cn.ysk.cashier.config.security.service.dto.AuthorityDto;
import cn.ysk.cashier.exception.EntityExistException;
import cn.ysk.cashier.system.service.dto.RoleSmallDto;
import cn.ysk.cashier.system.service.mapstruct.RoleMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
* @date 2018-12-03
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "role")
public class RoleServiceImpl implements RoleService {
private final RoleRepository roleRepository;
private final RoleMapper roleMapper;
private final RoleSmallMapper roleSmallMapper;
private final RedisUtils redisUtils;
private final UserRepository userRepository;
private final UserCacheManager userCacheManager;
@Override
public List<RoleDto> queryAll() {
Sort sort = Sort.by(Sort.Direction.ASC, "level");
return roleMapper.toDto(roleRepository.findAll(sort));
}
@Override
public List<RoleDto> queryAll(RoleQueryCriteria criteria) {
return roleMapper.toDto(roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
}
@Override
public Object queryAll(RoleQueryCriteria criteria, Pageable pageable) {
Page<Role> page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
return PageUtil.toPage(page.map(roleMapper::toDto));
}
@Override
@Cacheable(key = "'id:' + #p0")
@Transactional(rollbackFor = Exception.class)
public RoleDto findById(long id) {
Role role = roleRepository.findById(id).orElseGet(Role::new);
ValidationUtil.isNull(role.getId(), "Role", "id", id);
return roleMapper.toDto(role);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Role resources) {
if (roleRepository.findByName(resources.getName()) != null) {
throw new EntityExistException(Role.class, "username", resources.getName());
}
roleRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Role resources) {
Role role = roleRepository.findById(resources.getId()).orElseGet(Role::new);
ValidationUtil.isNull(role.getId(), "Role", "id", resources.getId());
Role role1 = roleRepository.findByName(resources.getName());
if (role1 != null && !role1.getId().equals(role.getId())) {
throw new EntityExistException(Role.class, "username", resources.getName());
}
role.setName(resources.getName());
role.setDescription(resources.getDescription());
role.setDataScope(resources.getDataScope());
role.setDepts(resources.getDepts());
role.setLevel(resources.getLevel());
roleRepository.save(role);
// 更新相关缓存
delCaches(role.getId(), null);
}
@Override
public void updateMenu(Role resources, RoleDto roleDTO) {
Role role = roleMapper.toEntity(roleDTO);
List<User> users = userRepository.findByRoleId(role.getId());
// 更新菜单
role.setMenus(resources.getMenus());
delCaches(resources.getId(), users);
roleRepository.save(role);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void untiedMenu(Long menuId) {
// 更新菜单
roleRepository.untiedMenu(menuId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Long> ids) {
for (Long id : ids) {
// 更新相关缓存
delCaches(id, null);
}
roleRepository.deleteAllByIdIn(ids);
}
@Override
public List<RoleSmallDto> findByUsersId(Long id) {
return roleSmallMapper.toDto(new ArrayList<>(roleRepository.findByUserId(id)));
}
@Override
public Integer findByRoles(Set<Role> roles) {
if (roles.size() == 0) {
return Integer.MAX_VALUE;
}
Set<RoleDto> roleDtos = new HashSet<>();
for (Role role : roles) {
roleDtos.add(findById(role.getId()));
}
return Collections.min(roleDtos.stream().map(RoleDto::getLevel).collect(Collectors.toList()));
}
@Override
@Cacheable(key = "'auth:' + #p0.id")
public List<AuthorityDto> mapToGrantedAuthorities(UserDto user) {
Set<String> permissions = new HashSet<>();
// 如果是管理员直接返回
if (user.getIsAdmin()) {
permissions.add("admin");
return permissions.stream().map(AuthorityDto::new)
.collect(Collectors.toList());
}
Set<Role> roles = roleRepository.findByUserId(user.getId());
permissions = roles.stream().flatMap(role -> role.getMenus().stream())
.map(Menu::getPermission)
.filter(StringUtils::isNotBlank).collect(Collectors.toSet());
return permissions.stream().map(AuthorityDto::new)
.collect(Collectors.toList());
}
@Override
public void download(List<RoleDto> roles, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (RoleDto role : roles) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("角色名称", role.getName());
map.put("角色级别", role.getLevel());
map.put("描述", role.getDescription());
map.put("创建日期", role.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
@Override
public void verification(Set<Long> ids) {
if (userRepository.countByRoles(ids) > 0) {
throw new BadRequestException("所选角色存在用户关联,请解除关联再试!");
}
}
@Override
public List<Role> findInMenuId(List<Long> menuIds) {
return roleRepository.findInMenuId(menuIds);
}
/**
* 清理缓存
* @param id /
*/
public void delCaches(Long id, List<User> users) {
users = CollectionUtil.isEmpty(users) ? userRepository.findByRoleId(id) : users;
if (CollectionUtil.isNotEmpty(users)) {
users.forEach(item -> userCacheManager.cleanUserCache(item.getUsername()));
Set<Long> userIds = users.stream().map(User::getId).collect(Collectors.toSet());
redisUtils.delByKeys(CacheKey.DATA_USER, userIds);
redisUtils.delByKeys(CacheKey.MENU_USER, userIds);
redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds);
}
redisUtils.del(CacheKey.ROLE_ID + id);
}
}

View File

@@ -0,0 +1,278 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.repository.UserRepository;
import cn.ysk.cashier.system.service.UserService;
import cn.ysk.cashier.system.service.dto.UserDto;
import cn.ysk.cashier.system.service.dto.UserQueryCriteria;
import cn.ysk.cashier.system.service.mapstruct.UserLoginMapper;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.config.FileProperties;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.config.security.service.OnlineUserService;
import cn.ysk.cashier.config.security.service.UserCacheManager;
import cn.ysk.cashier.repository.shop.TbMerchantAccountRepository;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import cn.ysk.cashier.exception.EntityExistException;
import cn.ysk.cashier.exception.EntityNotFoundException;
import cn.ysk.cashier.system.service.dto.*;
import cn.ysk.cashier.system.service.mapstruct.UserMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
private final FileProperties properties;
private final RedisUtils redisUtils;
private final UserCacheManager userCacheManager;
private final OnlineUserService onlineUserService;
private final UserLoginMapper userLoginMapper;
private final TbMerchantAccountRepository merchantAccountRepository;
private final TbShopInfoRepository shopInfoRepository;
@Override
public Object queryAll(UserQueryCriteria criteria, Pageable pageable) {
Page<User> page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
return PageUtil.toPage(page.map(userMapper::toDto));
}
@Override
public List<UserDto> queryAll(UserQueryCriteria criteria) {
List<User> users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder));
return userMapper.toDto(users);
}
@Override
@Cacheable(key = "'id:' + #p0")
@Transactional(rollbackFor = Exception.class)
public UserDto findById(long id) {
User user = userRepository.findById(id).orElseGet(User::new);
ValidationUtil.isNull(user.getId(), "User", "id", id);
return userMapper.toDto(user);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(User resources) {
if (userRepository.findByUsername(resources.getUsername()) != null) {
throw new EntityExistException(User.class, "username", resources.getUsername());
}
if (userRepository.findByEmail(resources.getEmail()) != null) {
throw new EntityExistException(User.class, "email", resources.getEmail());
}
if (userRepository.findByPhone(resources.getPhone()) != null) {
throw new EntityExistException(User.class, "phone", resources.getPhone());
}
userRepository.save(resources);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(User resources) throws Exception {
User user = userRepository.findById(resources.getId()).orElseGet(User::new);
ValidationUtil.isNull(user.getId(), "User", "id", resources.getId());
User user1 = userRepository.findByUsername(resources.getUsername());
User user2 = userRepository.findByEmail(resources.getEmail());
User user3 = userRepository.findByPhone(resources.getPhone());
if (user1 != null && !user.getId().equals(user1.getId())) {
throw new EntityExistException(User.class, "username", resources.getUsername());
}
if (user2 != null && !user.getId().equals(user2.getId())) {
throw new EntityExistException(User.class, "email", resources.getEmail());
}
if (user3 != null && !user.getId().equals(user3.getId())) {
throw new EntityExistException(User.class, "phone", resources.getPhone());
}
// 如果用户的角色改变
if (!resources.getRoles().equals(user.getRoles())) {
redisUtils.del(CacheKey.DATA_USER + resources.getId());
redisUtils.del(CacheKey.MENU_USER + resources.getId());
redisUtils.del(CacheKey.ROLE_AUTH + resources.getId());
}
// 修改部门会影响 数据权限
if (!Objects.equals(resources.getDept(),user.getDept())) {
redisUtils.del(CacheKey.DATA_USER + resources.getId());
}
// 如果用户被禁用,则清除用户登录信息
if(!resources.getEnabled()){
onlineUserService.kickOutForUsername(resources.getUsername());
}
user.setUsername(resources.getUsername());
user.setEmail(resources.getEmail());
user.setEnabled(resources.getEnabled());
user.setRoles(resources.getRoles());
user.setDept(resources.getDept());
user.setJobs(resources.getJobs());
user.setPhone(resources.getPhone());
user.setNickName(resources.getNickName());
user.setGender(resources.getGender());
userRepository.save(user);
// 清除缓存
delCaches(user.getId(), user.getUsername());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateCenter(User resources) {
User user = userRepository.findById(resources.getId()).orElseGet(User::new);
User user1 = userRepository.findByPhone(resources.getPhone());
if (user1 != null && !user.getId().equals(user1.getId())) {
throw new EntityExistException(User.class, "phone", resources.getPhone());
}
user.setNickName(resources.getNickName());
user.setPhone(resources.getPhone());
user.setGender(resources.getGender());
userRepository.save(user);
// 清理缓存
delCaches(user.getId(), user.getUsername());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<Long> ids) {
for (Long id : ids) {
// 清理缓存
UserDto user = findById(id);
delCaches(user.getId(), user.getUsername());
}
userRepository.deleteAllByIdIn(ids);
}
@Override
public UserDto findByName(String userName) {
User user = userRepository.findByUsername(userName);
if (user == null) {
throw new EntityNotFoundException(User.class, "name", userName);
} else {
return userMapper.toDto(user);
}
}
@Override
public UserLoginDto getLoginData(String userName) {
User user = userRepository.findByUsername(userName);
if (user == null) {
throw new EntityNotFoundException(User.class, "name", userName);
} else {
return userLoginMapper.toDto(user);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePass(String username, String pass) {
userRepository.updatePass(username, pass, new Date());
flushCache(username);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, String> updateAvatar(MultipartFile multipartFile) {
// 文件大小验证
FileUtil.checkSize(properties.getAvatarMaxSize(), multipartFile.getSize());
// 验证文件上传的格式
String image = "gif jpg png jpeg";
String fileType = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
if(fileType != null && !image.contains(fileType)){
throw new BadRequestException("文件格式错误!, 仅支持 " + image +" 格式");
}
User user = userRepository.findByUsername(SecurityUtils.getCurrentUsername());
String oldPath = user.getAvatarPath();
File file = FileUtil.upload(multipartFile, properties.getPath().getAvatar());
user.setAvatarPath(Objects.requireNonNull(file).getPath());
user.setAvatarName(file.getName());
userRepository.save(user);
if (StringUtils.isNotBlank(oldPath)) {
FileUtil.del(oldPath);
}
@NotBlank String username = user.getUsername();
flushCache(username);
return new HashMap<String, String>(1) {{
put("avatar", file.getName());
}};
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateEmail(String username, String email) {
userRepository.updateEmail(username, email);
flushCache(username);
}
@Override
public void download(List<UserDto> queryAll, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (UserDto userDTO : queryAll) {
List<String> roles = userDTO.getRoles().stream().map(RoleSmallDto::getName).collect(Collectors.toList());
Map<String, Object> map = new LinkedHashMap<>();
map.put("用户名", userDTO.getUsername());
map.put("角色", roles);
map.put("部门", userDTO.getDept().getName());
map.put("岗位", userDTO.getJobs().stream().map(JobSmallDto::getName).collect(Collectors.toList()));
map.put("邮箱", userDTO.getEmail());
map.put("状态", userDTO.getEnabled() ? "启用" : "禁用");
map.put("手机号码", userDTO.getPhone());
map.put("修改密码的时间", userDTO.getPwdResetTime());
map.put("创建日期", userDTO.getCreateTime());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
/**
* 清理缓存
*
* @param id /
*/
public void delCaches(Long id, String username) {
redisUtils.del(CacheKey.USER_ID + id);
flushCache(username);
}
/**
* 清理 登陆时 用户缓存信息
*
* @param username /
*/
private void flushCache(String username) {
userCacheManager.cleanUserCache(username);
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.impl;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import cn.ysk.cashier.system.service.VerifyService;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.domain.vo.EmailVo;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
/**
* @author Zheng Jie
* @date 2018-12-26
*/
@Service
@RequiredArgsConstructor
public class VerifyServiceImpl implements VerifyService {
@Value("${code.expiration}")
private Long expiration;
private final RedisUtils redisUtils;
@Override
@Transactional(rollbackFor = Exception.class)
public EmailVo sendEmail(String email, String key) {
EmailVo emailVo;
String content;
String redisKey = key + email;
// 如果不存在有效的验证码,就创建一个新的
TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH));
Template template = engine.getTemplate("email/email.ftl");
Object oldCode = redisUtils.get(redisKey);
if(oldCode == null){
String code = RandomUtil.randomNumbers (6);
// 存入缓存
if(!redisUtils.set(redisKey, code, expiration)){
throw new BadRequestException("服务异常,请联系网站负责人");
}
content = template.render(Dict.create().set("code",code));
emailVo = new EmailVo(Collections.singletonList(email),"ELADMIN后台管理系统",content);
// 存在就再次发送原来的验证码
} else {
content = template.render(Dict.create().set("code",oldCode));
emailVo = new EmailVo(Collections.singletonList(email),"ELADMIN后台管理系统",content);
}
return emailVo;
}
@Override
public void validated(String key, String code) {
Object value = redisUtils.get(key);
if(value == null || !value.toString().equals(code)){
throw new BadRequestException("无效验证码");
} else {
redisUtils.del(key);
}
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.system.service.dto.DeptDto;
import cn.ysk.cashier.base.BaseMapper;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface DeptMapper extends BaseMapper<DeptDto, Dept> {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.base.BaseMapper;
import cn.ysk.cashier.system.service.dto.DeptSmallDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-03-25
*/
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface DeptSmallMapper extends BaseMapper<DeptSmallDto, Dept> {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.DictDetail;
import cn.ysk.cashier.system.service.dto.DictDetailDto;
import cn.ysk.cashier.base.BaseMapper;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Mapper(componentModel = "spring", uses = {DictSmallMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface DictDetailMapper extends BaseMapper<DictDetailDto, DictDetail> {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Dict;
import cn.ysk.cashier.system.service.dto.DictDto;
import cn.ysk.cashier.base.BaseMapper;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface DictMapper extends BaseMapper<DictDto, Dict> {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Dict;
import cn.ysk.cashier.base.BaseMapper;
import cn.ysk.cashier.system.service.dto.DictSmallDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-04-10
*/
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface DictSmallMapper extends BaseMapper<DictSmallDto, Dict> {
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Job;
import cn.ysk.cashier.system.service.dto.JobDto;
import cn.ysk.cashier.base.BaseMapper;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
@Mapper(componentModel = "spring",uses = {DeptMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface JobMapper extends BaseMapper<JobDto, Job> {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Job;
import cn.ysk.cashier.base.BaseMapper;
import cn.ysk.cashier.system.service.dto.JobSmallDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-03-29
*/
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface JobSmallMapper extends BaseMapper<JobSmallDto, Job> {
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Menu;
import cn.ysk.cashier.system.service.dto.MenuDto;
import cn.ysk.cashier.base.BaseMapper;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2018-12-17
*/
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MenuMapper extends BaseMapper<MenuDto, Menu> {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Role;
import cn.ysk.cashier.system.service.dto.RoleDto;
import cn.ysk.cashier.base.BaseMapper;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Mapper(componentModel = "spring", uses = {MenuMapper.class, DeptMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface RoleMapper extends BaseMapper<RoleDto, Role> {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.Role;
import cn.ysk.cashier.base.BaseMapper;
import cn.ysk.cashier.system.service.dto.RoleSmallDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2019-5-23
*/
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface RoleSmallMapper extends BaseMapper<RoleSmallDto, Role> {
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.base.BaseMapper;
import cn.ysk.cashier.system.service.dto.UserLoginDto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Mapper(componentModel = "spring",uses = {RoleMapper.class, DeptMapper.class, JobMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserLoginMapper extends BaseMapper<UserLoginDto, User> {
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.system.service.mapstruct;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.service.dto.UserDto;
import cn.ysk.cashier.base.BaseMapper;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Mapper(componentModel = "spring",uses = {RoleMapper.class, DeptMapper.class, JobMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserMapper extends BaseMapper<UserDto, User> {
}