继续完善权限管理子系统数据模型
This commit is contained in:
parent
8f80745fb0
commit
ea2ce3d1d4
35
pom.xml
35
pom.xml
@ -72,6 +72,41 @@
|
|||||||
<version>1.11</version>
|
<version>1.11</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>5.2.3.RELEASE</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.5.2</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-test-autoconfigure</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hsqldb</groupId>
|
||||||
|
<artifactId>hsqldb</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.codesdream.ase.controller;
|
package com.codesdream.ase.controller;
|
||||||
|
|
||||||
import com.codesdream.ase.model.pernission.User;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.codesdream.ase.model.pernission;
|
package com.codesdream.ase.model.permission;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "functional_permit_container")
|
@Table(name = "functional_permit_container")
|
||||||
@ -11,22 +13,37 @@ public class FunctionalPermissionContainer {
|
|||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
// 功能性权限容器名
|
// 功能性权限容器名
|
||||||
// @Column(nullable = false, unique = true)
|
@Column(nullable = false, unique = true)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
// 功能性权限容器解释
|
// 功能性权限容器解释
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
// 功能性容器对应范围性容器
|
||||||
|
@ManyToOne(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)
|
||||||
|
private ScopePermissionContainer scopePermissionContainer;
|
||||||
|
|
||||||
|
@ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
||||||
|
private Set<Tag> tags;
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private List<String> urls;
|
private List<String> urls;
|
||||||
|
|
||||||
// @Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
// @Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private boolean deleted;
|
private boolean deleted;
|
||||||
|
|
||||||
|
public FunctionalPermissionContainer(String name, String description) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
|
||||||
|
this.tags = new HashSet<Tag>();
|
||||||
|
this.scopePermissionContainer = null;
|
||||||
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package com.codesdream.ase.model.pernission;
|
package com.codesdream.ase.model.permission;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.util.List;
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "scope_permit_container")
|
@Table(name = "scope_permit_container")
|
||||||
@ -15,15 +15,15 @@ public class ScopePermissionContainer {
|
|||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@OneToMany(cascade=CascadeType.MERGE,fetch=FetchType.LAZY,mappedBy="scopePermissionContainer")
|
||||||
|
private Set<FunctionalPermissionContainer> functionalPermissionContainers;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private boolean deleted;
|
private boolean deleted;
|
||||||
|
|
||||||
@ElementCollection
|
|
||||||
private List<Tag> tags;
|
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -63,12 +63,4 @@ public class ScopePermissionContainer {
|
|||||||
public void setDeleted(boolean deleted) {
|
public void setDeleted(boolean deleted) {
|
||||||
this.deleted = deleted;
|
this.deleted = deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Tag> getTags() {
|
|
||||||
return tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTags(List<Tag> tags) {
|
|
||||||
this.tags = tags;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package com.codesdream.ase.model.pernission;
|
package com.codesdream.ase.model.permission;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.util.Objects;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签
|
* 标签
|
||||||
@ -20,6 +22,10 @@ public class Tag {
|
|||||||
// 标签解释
|
// 标签解释
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
// 标签关联用户
|
||||||
|
@ManyToMany(mappedBy = "tags", cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
||||||
|
private Set<User> users;
|
||||||
|
|
||||||
// 启用标志
|
// 启用标志
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
@ -28,16 +34,26 @@ public class Tag {
|
|||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private boolean deleted;
|
private boolean deleted;
|
||||||
|
|
||||||
|
// 标签对应权限容器
|
||||||
|
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, mappedBy = "tags")
|
||||||
|
private Set<FunctionalPermissionContainer> functionalPermissionContainers;
|
||||||
|
|
||||||
public Tag(String name, String description) {
|
public Tag(String name, String description) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.deleted = false;
|
this.deleted = false;
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
|
|
||||||
|
this.users = new HashSet<User>();
|
||||||
|
this.functionalPermissionContainers = new HashSet<FunctionalPermissionContainer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tag() {
|
public Tag() {
|
||||||
this.deleted = false;
|
this.deleted = false;
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
|
|
||||||
|
this.users = new HashSet<User>();
|
||||||
|
this.functionalPermissionContainers = new HashSet<FunctionalPermissionContainer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
@ -79,4 +95,20 @@ public class Tag {
|
|||||||
public void setDeleted(boolean deleted) {
|
public void setDeleted(boolean deleted) {
|
||||||
this.deleted = deleted;
|
this.deleted = deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<User> getUsers() {
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsers(Set<User> users) {
|
||||||
|
this.users = users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FunctionalPermissionContainer> getFunctionalPermissionContainers() {
|
||||||
|
return functionalPermissionContainers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFunctionalPermissionContainers(Set<FunctionalPermissionContainer> functionalPermissionContainers) {
|
||||||
|
this.functionalPermissionContainers = functionalPermissionContainers;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.codesdream.ase.model.pernission;
|
package com.codesdream.ase.model.permission;
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
@ -7,7 +7,8 @@ import org.springframework.security.core.userdetails.UserDetails;
|
|||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "user")
|
@Table(name = "user")
|
||||||
@ -16,17 +17,49 @@ public class User implements UserDetails {
|
|||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private int id;
|
private int id;
|
||||||
// 用户名
|
// 用户名
|
||||||
|
@Column(unique = true, nullable = false)
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
// 密码(必须以哈希值sha256储存)
|
// 密码(必须以哈希值sha256储存)
|
||||||
|
@Column(nullable = false)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
// 手机号
|
||||||
|
@Column(nullable = true)
|
||||||
|
private String phone_number;
|
||||||
|
|
||||||
|
// 用户关联标签
|
||||||
|
@ManyToMany(cascade = CascadeType.PERSIST)
|
||||||
|
@JoinTable(name = "user_tag",
|
||||||
|
joinColumns = {
|
||||||
|
@JoinColumn(name = "user_id", referencedColumnName = "id")
|
||||||
|
},
|
||||||
|
inverseJoinColumns = {
|
||||||
|
@JoinColumn(name = "tag_id", referencedColumnName = "id")
|
||||||
|
})
|
||||||
|
private Set<Tag> tags;
|
||||||
|
|
||||||
|
// 是否启用
|
||||||
|
@Column(nullable = false)
|
||||||
|
private boolean enabled;
|
||||||
|
// 是否删除
|
||||||
|
@Column(nullable = false)
|
||||||
|
private boolean deleted;
|
||||||
|
|
||||||
public User(String username, String password) {
|
public User(String username, String password) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
|
this.enabled = true;
|
||||||
|
this.deleted = false;
|
||||||
|
this.tags = new HashSet<Tag>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public User() {
|
public User() {
|
||||||
|
this.username = null;
|
||||||
|
this.password = null;
|
||||||
|
this.enabled = true;
|
||||||
|
this.deleted = false;
|
||||||
|
this.tags = new HashSet<Tag>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -51,7 +84,7 @@ public class User implements UserDetails {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return false;
|
return this.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username) {
|
public void setUsername(String username) {
|
||||||
@ -73,4 +106,24 @@ public class User implements UserDetails {
|
|||||||
public void setPassword(String password) {
|
public void setPassword(String password) {
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Tag> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTags(Set<Tag> tags) {
|
||||||
|
this.tags = tags;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.codesdream.ase.repository;
|
||||||
|
|
||||||
|
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
|
||||||
|
import com.codesdream.ase.model.permission.Tag;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface TagRepository extends CrudRepository<Tag, Integer> {
|
||||||
|
Optional<Tag> findByName(String name);
|
||||||
|
}
|
@ -1,10 +1,14 @@
|
|||||||
package com.codesdream.ase.repository;
|
package com.codesdream.ase.repository;
|
||||||
|
|
||||||
import com.codesdream.ase.model.pernission.User;
|
import com.codesdream.ase.model.permission.Tag;
|
||||||
|
import com.codesdream.ase.model.permission.User;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public interface UserRepository extends CrudRepository<User, Long> {
|
@Repository
|
||||||
|
public interface UserRepository extends CrudRepository<User, Integer> {
|
||||||
Optional<User> findByUsername(String username);
|
Optional<User> findByUsername(String username);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.codesdream.ase.service;
|
package com.codesdream.ase.service;
|
||||||
|
|
||||||
import com.codesdream.ase.model.pernission.User;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.codesdream.ase.service;
|
package com.codesdream.ase.service;
|
||||||
|
|
||||||
import com.codesdream.ase.model.pernission.User;
|
import com.codesdream.ase.model.permission.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -9,7 +9,7 @@ import java.util.Optional;
|
|||||||
public interface IUserService {
|
public interface IUserService {
|
||||||
List<User> findAll();
|
List<User> findAll();
|
||||||
|
|
||||||
Optional<User> findUserById(long id);
|
Optional<User> findUserById(int id);
|
||||||
Optional<User> findUserByUsername(String username);
|
Optional<User> findUserByUsername(String username);
|
||||||
User save(User user);
|
User save(User user);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.codesdream.ase.service;
|
package com.codesdream.ase.service;
|
||||||
|
|
||||||
import com.codesdream.ase.model.pernission.User;
|
import com.codesdream.ase.component.ASEPasswordEncoder;
|
||||||
|
import com.codesdream.ase.model.permission.User;
|
||||||
import com.codesdream.ase.repository.UserRepository;
|
import com.codesdream.ase.repository.UserRepository;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -13,13 +14,16 @@ public class UserService implements IUserService {
|
|||||||
@Resource
|
@Resource
|
||||||
UserRepository userRepository;
|
UserRepository userRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ASEPasswordEncoder asePasswordEncoder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<User> findAll() {
|
public List<User> findAll() {
|
||||||
return (List<User>) userRepository.findAll();
|
return (List<User>) userRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<User> findUserById(long id) {
|
public Optional<User> findUserById(int id) {
|
||||||
return userRepository.findById(id);
|
return userRepository.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +34,9 @@ public class UserService implements IUserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User save(User user) {
|
public User save(User user) {
|
||||||
|
user.setPassword(asePasswordEncoder.encode(user.getPassword()));
|
||||||
|
user.setEnabled(true);
|
||||||
|
user.setDeleted(false);
|
||||||
return userRepository.save(user);
|
return userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
76
src/main/java/com/codesdream/ase/test/UserTest.java
Normal file
76
src/main/java/com/codesdream/ase/test/UserTest.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package com.codesdream.ase.test;
|
||||||
|
|
||||||
|
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
|
||||||
|
import com.codesdream.ase.model.permission.Tag;
|
||||||
|
import com.codesdream.ase.model.permission.User;
|
||||||
|
import com.codesdream.ase.repository.UserRepository;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户基本表单元测试
|
||||||
|
* 用于测试数据库与DAO层交互是否通畅
|
||||||
|
*/
|
||||||
|
@DataJpaTest
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
public class UserTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TestEntityManager entityManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基本存储与查询测试
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void UserBaseTest_1(){
|
||||||
|
User user = new User("Tim", "123456");
|
||||||
|
userRepository.save(user);
|
||||||
|
assertTrue(userRepository.findByUsername("Tim").isPresent());
|
||||||
|
assertFalse(userRepository.findByUsername("Tom").isPresent());
|
||||||
|
user = userRepository.findByUsername("Tim").get();
|
||||||
|
|
||||||
|
assertEquals(user.getUsername(), "Tim");
|
||||||
|
assertEquals(user.getPassword(), "123456");
|
||||||
|
assertTrue(user.isEnabled());
|
||||||
|
assertFalse(user.isDeleted());
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void UserBaseTest_2(){
|
||||||
|
// 用户
|
||||||
|
User user = new User("Pat", "123456");
|
||||||
|
// 标签
|
||||||
|
Tag tag = new Tag("学生","普通学生");
|
||||||
|
// 功能性权限容器
|
||||||
|
FunctionalPermissionContainer functionalPermissionContainer =
|
||||||
|
new FunctionalPermissionContainer("基本用户权限", "基本的用户权限");
|
||||||
|
|
||||||
|
// 添加为标签功能性权限容器
|
||||||
|
HashSet<FunctionalPermissionContainer> functionalPermissionContainers = new HashSet<>();
|
||||||
|
functionalPermissionContainers.add(functionalPermissionContainer);
|
||||||
|
tag.setFunctionalPermissionContainers(functionalPermissionContainers);
|
||||||
|
|
||||||
|
// 为用户添加标签
|
||||||
|
HashSet<Tag> tags = new HashSet<>();
|
||||||
|
tags.add(tag);
|
||||||
|
user.setTags(tags);
|
||||||
|
|
||||||
|
userRepository.save(user);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="height: 15%"></div>
|
|
||||||
<div th:include="layout::custom-template"></div>
|
<div th:include="layout::custom-template"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user