first commit.

This commit is contained in:
2022-12-07 18:14:38 +08:00
commit e916d067f3
183 changed files with 9649 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>plusone-system</artifactId>
<groupId>xyz.zhouxy</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>plusone-system-infrastructure</artifactId>
<dependencies>
<dependency>
<groupId>xyz.zhouxy</groupId>
<artifactId>plusone-basic-infrastructure</artifactId>
</dependency>
<dependency>
<groupId>xyz.zhouxy</groupId>
<artifactId>plusone-system-domain</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,218 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Objects;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.util.AssertResult;
/**
* AccountRepository 实现类
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
@Repository
public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long> implements AccountRepository {
private final AccountRoleRefDAO accountRoleDAO;
public AccountRepositoryImpl(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
super(namedParameterJdbcTemplate);
this.accountRoleDAO = new AccountRoleRefDAO(namedParameterJdbcTemplate);
}
@Override
protected final void doDelete(@Nonnull Account entity) {
int i = this.jdbc.update("""
UPDATE sys_account SET deleted = id, "version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""",
new MapSqlParameterSource()
.addValue("id", entity.getId().orElseThrow())
.addValue("version", entity.getVersion()));
AssertResult.update(i, 1);
}
@Override
protected final Account doFindById(@Nonnull Long id) {
return queryForObject("""
SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
created_by, updated_by, "version"
FROM sys_account
WHERE id = :id AND deleted = 0
""",
new MapSqlParameterSource("id", id));
}
@Override
public Account findByEmail(Email email) {
return queryForObject("""
SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
created_by, updated_by, "version"
FROM sys_account
WHERE email = :email AND deleted = 0
""",
new MapSqlParameterSource("email", email.value()));
}
@Override
public Account findByMobilePhone(MobilePhone mobilePhone) {
return queryForObject("""
SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
created_by, updated_by, "version"
FROM sys_account
WHERE mobile_phone = :mobilePhone AND deleted = 0
""",
new MapSqlParameterSource("mobilePhone", mobilePhone.value()));
}
@Override
public Account findByUsername(Username username) {
return queryForObject("""
SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
created_by, updated_by, "version"
FROM sys_account
WHERE username = :username AND deleted = 0
""",
new MapSqlParameterSource("username", username.value()));
}
@Override
public boolean exists(Long id) {
return queryExists("SELECT 1 FROM sys_account WHERE id = :id AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("id", id));
}
@Override
public boolean existsUsername(Username username) {
return queryExists("SELECT 1 FROM sys_account WHERE username = :username AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("username", username.value()));
}
@Override
public boolean existsEmail(Email email) {
return queryExists("SELECT 1 FROM sys_account WHERE email = :email AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("email", email.value()));
}
@Override
public boolean existsMobilePhone(MobilePhone mobilePhone) {
return queryExists("SELECT 1 FROM sys_account WHERE mobile_phone = :mobile_phone AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("mobile_phone", mobilePhone.value()));
}
@Override
public Collection<Account> findByRoleId(Long roleId) {
return queryForList("""
SELECT
a.id, a.email, a.mobile_phone, a.username, a."password", a.salt,
a.avatar, a.sex, a.nickname, a.status,
a.created_by, a.updated_by, a."version"
FROM sys_account a
LEFT JOIN sys_account_role ar ON a.id = ar.account_id
WHERE ar.role_id = :roleId AND a.deleted = 0
""",
new MapSqlParameterSource("roleId", roleId));
}
@Override
protected final Account doInsert(@Nonnull Account entity) {
String sql = """
INSERT INTO sys_account
(id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status, created_by, create_time)
VALUES
(:id, :email, :mobilePhone, :username, :password, :salt, :avatar, :sex, :nickname, :status, :createdBy, :createTime)
""";
long id = IdUtil.getSnowflakeNextId();
SqlParameterSource params = generateParamSource(id, entity);
int i = jdbc.update(sql, params);
AssertResult.update(i, 1);
this.accountRoleDAO.insertAccountRoleRefs(id, entity.getRoleIds());
return entity;
}
@Override
protected final Account doUpdate(@Nonnull Account entity) {
String sql = """
UPDATE sys_account
SET "email" = :email,
"mobile_phone" = :mobilePhone,
"username" = :username,
"password" = :password,
"salt" = :salt,
"avatar" = :avatar,
"sex" = :sex,
"nickname" = :nickname,
"status" = :status,
"updated_by" = :updatedBy,
"update_time" = :updateTime,
"version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""";
SqlParameterSource params = generateParamSource(entity);
int i = this.jdbc.update(sql, params);
AssertResult.update(i, 1);
this.accountRoleDAO.saveAccountRoleRefs(entity);
return entity;
}
@Override
protected final Account mapRow(ResultSet rs) throws SQLException {
long accountId = rs.getLong("id");
AccountInfo accountInfo = AccountInfo.of(
rs.getString("nickname"),
rs.getString("avatar"),
Sex.of(rs.getInt("sex")));
return new Account(
accountId,
rs.getString("username"),
rs.getString("email"),
rs.getString("mobile_phone"),
Password.of(rs.getString("password"), rs.getString("salt")),
AccountStatus.of(rs.getInt("status")),
accountInfo,
this.accountRoleDAO.selectRoleIdsByAccountId(accountId),
rs.getLong("created_by"),
rs.getLong("updated_by"),
rs.getLong("version"));
}
@Override
protected final SqlParameterSource generateParamSource(Long id, @Nonnull Account entity) {
LocalDateTime now = LocalDateTime.now();
AccountInfo accountInfo = entity.getAccountInfo();
return new MapSqlParameterSource()
.addValue("id", id)
.addValue("email", Objects.nonNull(entity.getEmail()) ? entity.getEmail().value() : null)
.addValue("mobilePhone",
Objects.nonNull(entity.getMobilePhone()) ? entity.getMobilePhone().value() : null)
.addValue("username", entity.getUsername().value())
.addValue("password", entity.getPassword().value())
.addValue("salt", entity.getPassword().getSalt())
.addValue("avatar", accountInfo.getAvatar().toString())
.addValue("sex", accountInfo.getSex().getValue())
.addValue("nickname",
Objects.nonNull(accountInfo.getNickname()) ? accountInfo.getNickname().value() : null)
.addValue("status", entity.getStatus().getValue())
.addValue("createdBy", entity.getCreatedBy())
.addValue("createTime", now)
.addValue("updatedBy", entity.getUpdatedBy())
.addValue("updateTime", now)
.addValue("version", entity.getVersion());
}
}

View File

@@ -0,0 +1,53 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class AccountRoleRefDAO {
private final NamedParameterJdbcTemplate jdbc;
AccountRoleRefDAO(NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc;
}
Set<Long> selectRoleIdsByAccountId(Long accountId) {
List<Long> roleRefs = this.jdbc.queryForList("""
SELECT r.id FROM sys_role r RIGHT JOIN sys_account_role ar ON r.id = ar.role_id
WHERE r.deleted = 0 AND ar.account_id = :accountId;
""",
new MapSqlParameterSource("accountId", accountId),
Long.TYPE);
return new HashSet<>(roleRefs);
}
void clearAccountRoleRefs(Account entity) {
var param = new MapSqlParameterSource("accountId", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_account_role WHERE account_id = :accountId", param);
}
void insertAccountRoleRefs(Long accountId, Set<Long> roleRefs) {
String sql = "INSERT INTO sys_account_role (account_id, role_id) VALUES (:accountId, :roleId)";
MapSqlParameterSource[] batchArgs = roleRefs
.stream()
.map((Long roleId) -> new MapSqlParameterSource()
.addValue("accountId", accountId)
.addValue("roleId", roleId))
.toArray(MapSqlParameterSource[]::new);
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(roleRefs.size(), NumberUtil.sum(i));
}
void saveAccountRoleRefs(Account entity) {
Long accountId = entity.getId().orElseThrow();
Set<Long> roleRefs = entity.getRoleIds();
clearAccountRoleRefs(entity);
insertAccountRoleRefs(accountId, roleRefs);
}
}

View File

@@ -0,0 +1,118 @@
package xyz.zhouxy.plusone.system.domain.model.dict;
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.List;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.util.AssertResult;
/**
* DictRepository 实现类
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
@Repository
public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implements DictRepository {
private final DictValueDAO dictValueDAO;
public DictRepositoryImpl(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
super(namedParameterJdbcTemplate);
this.dictValueDAO = new DictValueDAO(namedParameterJdbcTemplate);
}
@Override
public Dict doFindById(@Nonnull Long id) {
return queryForObject("SELECT id, dict_type, dict_label, \"version\" WHERE id = :id AND deleted = 0",
new MapSqlParameterSource("id", id));
}
@Override
protected final Dict doInsert(@Nonnull Dict entity) {
long id = IdUtil.getSnowflakeNextId();
int i = this.jdbc.update("""
INSERT INTO sys_dict_type (dict_type, dict_label, create_time, created_by)
VALUES (:dictType, :dictLabel, :createTime, :createdBy)
""",
generateParamSource(id, entity));
AssertResult.update(i, 1);
this.dictValueDAO.insertDictValues(id, entity);
return find(id);
}
@Override
protected final Dict doUpdate(@Nonnull Dict entity) {
int i = this.jdbc.update("""
UPDATE sys_dict_type
SET dict_type = :dictType,
dict_label = :dictLabel,
update_time = :updateTime,
updated_by = :updatedBy,
"version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""",
generateParamSource(entity));
AssertResult.update(i, 1);
this.dictValueDAO.updateDictValues(entity);
return find(entity.getId().orElseThrow());
}
@Override
protected final void doDelete(@Nonnull Dict entity) {
int i = this.jdbc.update("""
UPDATE sys_dict_type SET deleted = id, "version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""",
generateParamSource(entity));
AssertResult.update(i, 1);
}
@Override
public boolean exists(Long id) {
return queryExists("SELECT 1 FROM sys_dict_type WHERE id = :id AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("id", id));
}
@Override
public List<Dict> findAll() {
return queryForList("SELECT id, dict_type, dict_label, \"version\" WHERE deleted = 0");
}
@Override
protected final Dict mapRow(ResultSet rs) throws SQLException {
long id = rs.getLong("id");
return new Dict(
id,
rs.getString("dict_type"),
rs.getString("dict_label"),
this.dictValueDAO.selectDictValuesByDictId(id),
rs.getLong("version"));
}
@Override
protected final SqlParameterSource generateParamSource(Long id, @Nonnull Dict entity) {
LocalDateTime now = LocalDateTime.now();
long loginId = adminAuthLogic.getLoginIdAsLong();
return new MapSqlParameterSource()
.addValue("dictType", entity.getDictType())
.addValue("dictLabel", entity.getLabel())
.addValue("createTime", now)
.addValue("createdBy", loginId)
.addValue("updateTime", now)
.addValue("updatedBy", loginId)
.addValue("id", id)
.addValue("version", entity.getVersion());
}
}

View File

@@ -0,0 +1,51 @@
package xyz.zhouxy.plusone.system.domain.model.dict;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.util.CollectionUtils;
import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class DictValueDAO {
private final NamedParameterJdbcTemplate jdbc;
DictValueDAO(NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc;
}
void updateDictValues(Dict entity) {
MapSqlParameterSource deleteParam = new MapSqlParameterSource("dictType", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_dict_value WHERE dict_type = :dictType", deleteParam);
int i = insertDictValues(entity.getId().orElseThrow(), entity);
AssertResult.update(i, entity.count());
}
int insertDictValues(Long dictId, Dict entity) {
if (Objects.isNull(dictId) || Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getValues())) {
return 0;
}
int[] i = this.jdbc.batchUpdate(
"INSERT INTO sys_dict_value (dict_type, dict_key, label) VALUES (:dictType, :dictKey, :label)",
entity.getValues().stream()
.map(dictValue -> new MapSqlParameterSource()
.addValue("dictType", dictId)
.addValue("dictKey", dictValue.getKey())
.addValue("label", dictValue.getLabel()))
.toArray(SqlParameterSource[]::new));
return NumberUtil.sum(i);
}
Set<DictValue> selectDictValuesByDictId(long id) {
return this.jdbc.queryForStream("""
SELECT dict_key, label FROM sys_dict_value WHERE dict_type = :dictType
""", new MapSqlParameterSource("dictType", id),
(rs, rowNum) -> DictValue.of(rs.getInt("dict_key"), rs.getString("label")))
.collect(Collectors.toSet());
}
}

View File

@@ -0,0 +1,123 @@
package xyz.zhouxy.plusone.system.domain.model.menu;
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.jdbc.JdbcEntityDaoSupport;
/**
* {@link Action} 的数据访问对象
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
* @date 2022-10-31 12:31:49
*/
class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
ActionDAO(@Nonnull NamedParameterJdbcTemplate jdbc) {
super(jdbc);
}
void saveActions(Long menuId, List<Action> actions) {
// 删除要删除的权限
Collection<Long> ids = actions.stream()
.filter(action -> action.getId().isPresent())
.map(action -> action.getId().orElseThrow())
.collect(Collectors.toSet());
if (!ids.isEmpty()) {
this.jdbc.update(
"UPDATE sys_action SET deleted = id WHERE resource = :resource AND id NOT IN (:ids) AND deleted = 0",
new MapSqlParameterSource()
.addValue("resource", menuId)
.addValue("ids", ids));
}
// 更新存在的数据
this.jdbc.batchUpdate("""
UPDATE sys_action
SET resource = :resource,
identifier = :identifier,
label = :label,
update_time = :updateTime,
updated_by = :updatedBy
WHERE id = :id AND deleted = 0
""",
actions.stream()
.filter(action -> action.getId().isPresent())
.map(action -> generateParamSource(menuId, action))
.toArray(MapSqlParameterSource[]::new));
// 插入新添加的数据
this.jdbc.batchUpdate("""
INSERT INTO sys_action
(id, resource, identifier, "label", create_time, created_by)
VALUES
(:id, :resource, :identifier, :label, :createTime, :createdBy)
""",
actions.stream()
.filter(action -> action.getId().isEmpty())
.map(action -> generateParamSource(menuId, IdUtil.getSnowflakeNextId(), action))
.toArray(MapSqlParameterSource[]::new));
}
List<Action> selectActionsByMenuId(long menuId) {
return queryForList("""
SELECT a.id, m.resource, a.identifier, a.label
FROM sys_action a
JOIN (SELECT id, resource FROM sys_menu WHERE id = :menuId AND deleted = 0) m ON a.resource = m.id
WHERE a.deleted = 0
""", new MapSqlParameterSource("menuId", menuId));
}
Collection<Action> selectActionsByIdIn(Collection<Long> actionIds) {
if (Objects.isNull(actionIds) || actionIds.isEmpty()) {
return Collections.emptyList();
}
return queryForList("""
SELECT a.id, m.resource, a.identifier, a.label
FROM sys_action a
LEFT JOIN sys_menu m ON a.resource = m.id
WHERE a.id IN (:actionIds) AND a.deleted = 0
""", new MapSqlParameterSource("actionIds", actionIds));
}
private SqlParameterSource generateParamSource(Long menuId, Action action) {
return generateParamSource(menuId, action.getId().orElseThrow(), action);
}
private SqlParameterSource generateParamSource(Long menuId, Long actionId, Action action) {
long loginId = adminAuthLogic.getLoginIdAsLong();
LocalDateTime now = LocalDateTime.now();
return new MapSqlParameterSource("id", actionId)
.addValue("resource", menuId)
.addValue("identifier", action.getIdentifier())
.addValue("label", action.getLabel())
.addValue("createTime", now)
.addValue("createdBy", loginId)
.addValue("updateTime", now)
.addValue("updatedBy", loginId);
}
@Override
protected Action mapRow(ResultSet rs) throws SQLException {
return Action.of(
rs.getLong("id"),
rs.getString("resource"),
rs.getString("identifier"),
rs.getString("label"));
}
}

View File

@@ -0,0 +1,200 @@
package xyz.zhouxy.plusone.system.domain.model.menu;
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType;
import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.EnumUtil;
/**
* MenuRepository 实现类
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
@Repository
public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implements MenuRepository {
private final ActionDAO actionDAO;
MenuRepositoryImpl(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
super(namedParameterJdbcTemplate);
this.actionDAO = new ActionDAO(namedParameterJdbcTemplate);
}
@Override
protected final Menu doFindById(@Nonnull Long id) {
return queryForObject("""
SELECT
id, parent_id, "type", "name", "path", title, icon, hidden, order_number, status, remarks,
component, "cache", resource, "version"
FROM sys_menu
WHERE id = :id AND deleted = 0
""",
new MapSqlParameterSource("id", id));
}
@Override
protected final Menu doInsert(@Nonnull Menu entity) {
long id = IdUtil.getSnowflakeNextId();
String sql = """
INSERT INTO sys_menu (
id, parent_id, "type", name, "path", title, icon, hidden, order_number, status, remarks,
component, "cache", resource, create_time, created_by)
VALUES
(:id, :parentId, :type, :name, :path, :title, :icon, :hidden, :orderNumber, :status, :remarks,
:component, :cache, :resource, :createTime, :createdBy)
""";
MapSqlParameterSource paramSource = generateParamSource(id, entity);
int i = this.jdbc.update(sql, paramSource);
AssertResult.update(i, 1);
this.actionDAO.saveActions(id, entity.getActions());
return entity;
}
@Override
protected final Menu doUpdate(@Nonnull Menu entity) {
String sql = """
UPDATE sys_menu
SET "parent_id" = :parentId,
"type" = :type,
"name" = :name,
"path" = :path,
"title" = :title,
"icon" = :icon,
"hidden" = :hidden,
"order_number" = :orderNumber,
"status" = :status,
"remarks" = :remarks,
"component" = :component,
"cache" = :cache,
"resource" = :resource,
"update_time" = :updateTime,
"updated_by" = :updatedBy,
"version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""";
// 更新菜单
int i = this.jdbc.update(sql, generateParamSource(entity));
AssertResult.update(i, 1);
// 保存权限
Long id = entity.getId().orElseThrow();
this.actionDAO.saveActions(id, entity.getActions());
return entity;
}
@Override
protected final void doDelete(@Nonnull Menu entity) {
int i = this.jdbc.update("""
UPDATE sys_menu SET deleted = id, "version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""",
new MapSqlParameterSource("id", entity.getId().orElseThrow())
.addValue("version", entity.getVersion()));
AssertResult.update(i, 1);
}
@Override
public boolean exists(Long id) {
return queryExists("SELECT 1 FROM sys_menu WHERE id = :id AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("id", id));
}
@Override
public Collection<Menu> findByIdIn(Collection<Long> ids) {
if (Objects.isNull(ids) || ids.isEmpty()) {
return Collections.emptyList();
}
return queryForList("""
SELECT
id, parent_id, "type", "name", "path", title, icon, hidden, order_number, status, remarks,
component, "cache", resource, "version"
FROM sys_menu
WHERE id IN (:ids) AND deleted = 0
""",
new MapSqlParameterSource("ids", ids));
}
@Override
public Collection<Action> findPermissionsByIdIn(Collection<Long> permissionIds) {
return this.actionDAO.selectActionsByIdIn(permissionIds);
}
@Override
public Collection<Menu> queryByRoleId(Long roleId) {
return queryForList("""
SELECT
m.id, m.parent_id, m."type", m."name", m."path", m.title, m.icon, m.hidden, m.order_number,
m.status, m.remarks, m.component, m."cache", m.resource, m."version"
FROM sys_menu AS m
LEFT JOIN sys_role_menu AS rm ON m.id = rm.menu_id
WHERE rm.role_id = :roleId AND r.deleted = 0
""",
new MapSqlParameterSource("roleId", roleId));
}
@Override
protected final Menu mapRow(ResultSet rs) throws SQLException {
long menuId = rs.getLong("id");
return new Menu(
EnumUtil.valueOf(MenuType.class, rs.getInt("type")),
menuId,
rs.getLong("parent_id"),
rs.getString("name"),
rs.getString("path"),
rs.getString("title"),
rs.getString("icon"),
rs.getBoolean("hidden"),
rs.getInt("order_number"),
EntityStatus.of(rs.getInt("status")),
rs.getString("remarks"),
rs.getString("component"),
rs.getBoolean("cache"),
rs.getString("resource"),
this.actionDAO.selectActionsByMenuId(menuId),
rs.getLong("version"));
}
@Override
protected final MapSqlParameterSource generateParamSource(Long id, @Nonnull Menu entity) {
LocalDateTime now = LocalDateTime.now();
long loginId = adminAuthLogic.getLoginIdAsLong();
return new MapSqlParameterSource()
.addValue("id", id)
.addValue("parentId", entity.getParentId())
.addValue("type", entity.getType().value())
.addValue("name", entity.getName())
.addValue("path", entity.getPath())
.addValue("title", entity.getTitle())
.addValue("icon", entity.getIcon())
.addValue("hidden", entity.isHidden())
.addValue("orderNumber", entity.getOrderNumber())
.addValue("status", entity.getStatus().getValue())
.addValue("remarks", entity.getRemarks())
.addValue("component", entity.getComponent())
.addValue("cache", entity.getCache())
.addValue("resource", entity.getResource())
.addValue("createTime", now)
.addValue("createdBy", loginId)
.addValue("updateTime", now)
.addValue("updatedBy", loginId)
.addValue("version", entity.getVersion());
}
}

View File

@@ -0,0 +1,45 @@
package xyz.zhouxy.plusone.system.domain.model.role;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class RoleMenuRefDAO {
private final NamedParameterJdbcTemplate jdbc;
public RoleMenuRefDAO(NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc;
}
Set<MenuRef> selectMenuRefsByRoleId(long roleId) {
return this.jdbc.queryForList("SELECT menu_id FROM sys_role_menu WHERE role_id = :roleId",
new MapSqlParameterSource("roleId", roleId),
Long.TYPE)
.stream()
.map(MenuRef::of)
.collect(Collectors.toSet());
}
void clearRoleMenuRefs(Role entity) {
MapSqlParameterSource param = new MapSqlParameterSource("roleId", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_role_menu WHERE role_id = :roleId", param);
}
void saveRoleMenuRefs(Long roleId, Role entity) {
String sql = "INSERT INTO sys_role_menu(role_id, menu_id) VALUES (:roleId, :menuId)";
MapSqlParameterSource[] batchArgs = entity.getMenus()
.stream()
.map(menuRef -> new MapSqlParameterSource()
.addValue("roleId", roleId)
.addValue("menuId", menuRef.menuId()))
.toArray(MapSqlParameterSource[]::new);
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(entity.getMenus().size(), NumberUtil.sum(i));
}
}

View File

@@ -0,0 +1,45 @@
package xyz.zhouxy.plusone.system.domain.model.role;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class RolePermissionRefDAO {
private final NamedParameterJdbcTemplate jdbc;
public RolePermissionRefDAO(NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc;
}
Set<ActionRef> selectPermissionRefsByRoleId(long roleId) {
return this.jdbc.queryForList("SELECT permission_id FROM sys_role_permission WHERE role_id = :roleId",
new MapSqlParameterSource("roleId", roleId),
Long.TYPE)
.stream()
.map(ActionRef::of)
.collect(Collectors.toSet());
}
void clearRolePermissionRefs(Role entity) {
MapSqlParameterSource param = new MapSqlParameterSource("roleId", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_role_permission WHERE role_id = :roleId", param);
}
void saveRolePermissionRefs(Long roleId, Role entity) {
String sql = "INSERT INTO sys_role_permission(role_id, permission_id) VALUES (:roleId, :permissionId)";
SqlParameterSource[] batchArgs = entity.getPermissions()
.stream()
.map(menuRef -> new MapSqlParameterSource()
.addValue("roleId", roleId)
.addValue("permissionId", menuRef.actionId()))
.toArray(MapSqlParameterSource[]::new);
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(entity.getMenus().size(), NumberUtil.sum(i));
}
}

View File

@@ -0,0 +1,142 @@
package xyz.zhouxy.plusone.system.domain.model.role;
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Collection;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.util.AssertResult;
/**
* RoleRepository 实现类
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
@Repository
public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implements RoleRepository {
private final RoleMenuRefDAO roleMenuRefDAO;
private final RolePermissionRefDAO rolePermissionRefDAO;
RoleRepositoryImpl(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
super(namedParameterJdbcTemplate);
this.roleMenuRefDAO = new RoleMenuRefDAO(namedParameterJdbcTemplate);
this.rolePermissionRefDAO = new RolePermissionRefDAO(namedParameterJdbcTemplate);
}
@Override
protected final Role doFindById(@Nonnull Long id) {
return queryForObject("""
SELECT "id","name","identifier","status","remarks","version"
FROM "sys_role"
WHERE id = :id AND deleted = 0
""", new MapSqlParameterSource("id", id));
}
@Override
protected final void doDelete(@Nonnull Role entity) {
int i = this.jdbc.update("""
UPDATE sys_account SET deleted = id, "version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""",
new MapSqlParameterSource("id", entity.getId().orElseThrow())
.addValue("version", entity.getVersion()));
AssertResult.update(i, 1);
}
@Override
public boolean exists(Long id) {
return queryExists("SELECT 1 FROM sys_role WHERE id = :id AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("id", id));
}
@Override
protected final Role doInsert(@Nonnull Role entity) {
long id = IdUtil.getSnowflakeNextId();
int i = this.jdbc.update("""
INSERT INTO sys_role
(id, "name", identifier, status, remarks, create_time, created_by)
VALUES
(:id, :name, :identifier, :status, :remarks, :createTime, :createdBy)
""", generateParamSource(id, entity));
AssertResult.update(i, 1);
this.roleMenuRefDAO.saveRoleMenuRefs(id, entity);
this.rolePermissionRefDAO.saveRolePermissionRefs(id, entity);
return entity;
}
@Override
protected final Role doUpdate(@Nonnull Role entity) {
int i = this.jdbc.update("""
UPDATE sys_role
SET "name" = :name,
"identifier" = :identifier,
"status" = :status,
"remarks" = :remarks,
"update_time" = :updateTime,
"updated_by" = :updatedBy,
"version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version
""", generateParamSource(entity));
AssertResult.update(i, 1);
Long id = entity.getId().orElseThrow();
this.roleMenuRefDAO.clearRoleMenuRefs(entity);
this.roleMenuRefDAO.saveRoleMenuRefs(id, entity);
this.rolePermissionRefDAO.clearRolePermissionRefs(entity);
this.rolePermissionRefDAO.saveRolePermissionRefs(id, entity);
return entity;
}
@Override
public Collection<Role> findByAccountId(Long accountId) {
return queryForList("""
SELECT r."id", r."name", r."identifier", r."status", r."remarks", r."version"
FROM sys_role AS r
LEFT JOIN sys_account_role AS ar ON r.id = ar.role_id
WHERE ar.account_id = :accountId AND r.deleted = 0
""", new MapSqlParameterSource("accountId", accountId));
}
@Override
protected final Role mapRow(ResultSet rs) throws SQLException {
long roleId = rs.getLong("id");
return new Role(
roleId,
rs.getString("name"),
rs.getString("identifier"),
EntityStatus.of(rs.getInt("status")),
rs.getString("remarks"),
this.roleMenuRefDAO.selectMenuRefsByRoleId(roleId),
this.rolePermissionRefDAO.selectPermissionRefsByRoleId(roleId),
rs.getLong("version"));
}
@Override
protected final MapSqlParameterSource generateParamSource(Long id, @Nonnull Role entity) {
LocalDateTime now = LocalDateTime.now();
long loginId = adminAuthLogic.getLoginIdAsLong();
return new MapSqlParameterSource()
.addValue("id", id)
.addValue("name", entity.getName())
.addValue("identifier", entity.getIdentifier())
.addValue("status", entity.getStatus().getValue())
.addValue("remarks", entity.getRemarks())
.addValue("createTime", now)
.addValue("createdBy", loginId)
.addValue("updateTime", now)
.addValue("updatedBy", loginId)
.addValue("version", entity.getVersion());
}
}