feat: change remark to discussion

This commit is contained in:
vran 2022-03-12 23:34:42 +08:00
parent f026d406a2
commit 84db78fdcd
16 changed files with 214 additions and 113 deletions

View File

@ -3,10 +3,10 @@ package com.databasir.api;
import com.databasir.api.config.security.DatabasirUserDetails;
import com.databasir.common.JsonData;
import com.databasir.core.domain.log.annotation.Operation;
import com.databasir.core.domain.remark.data.RemarkCreateRequest;
import com.databasir.core.domain.remark.data.RemarkListCondition;
import com.databasir.core.domain.remark.data.RemarkResponse;
import com.databasir.core.domain.remark.service.DocumentRemarkService;
import com.databasir.core.domain.remark.data.DiscussionCreateRequest;
import com.databasir.core.domain.remark.data.DiscussionListCondition;
import com.databasir.core.domain.remark.data.DiscussionResponse;
import com.databasir.core.domain.remark.service.DocumentDiscussionService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -22,46 +22,46 @@ import javax.validation.Valid;
@RestController
@Validated
@RequiredArgsConstructor
public class DocumentRemarkController {
public class DocumentDiscussionController {
private final DocumentRemarkService documentRemarkService;
private final DocumentDiscussionService documentDiscussionService;
@GetMapping(Routes.DocumentRemark.LIST)
public JsonData<Page<RemarkResponse>> listByProjectId(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@PageableDefault(sort = "id",
direction = Sort.Direction.DESC)
Pageable request,
RemarkListCondition condition) {
var data = documentRemarkService.list(groupId, projectId, request, condition);
@GetMapping(Routes.DocumentDiscussion.LIST)
public JsonData<Page<DiscussionResponse>> listByProjectId(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@PageableDefault(sort = "id",
direction = Sort.Direction.DESC)
Pageable request,
DiscussionListCondition condition) {
var data = documentDiscussionService.list(groupId, projectId, request, condition);
return JsonData.ok(data);
}
@DeleteMapping(Routes.DocumentRemark.DELETE)
@DeleteMapping(Routes.DocumentDiscussion.DELETE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER', 'GROUP_OWNER?groupId='+#groupId)")
@Operation(module = Operation.Modules.PROJECT,
name = "删除评论",
involvedProjectId = "#projectId")
public JsonData<Void> delete(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@PathVariable Integer remarkId) {
documentRemarkService.deleteById(groupId, projectId, remarkId);
@PathVariable Integer discussionId) {
documentDiscussionService.deleteById(groupId, projectId, discussionId);
return JsonData.ok();
}
@PostMapping(Routes.DocumentRemark.CREATE)
@PostMapping(Routes.DocumentDiscussion.CREATE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER', 'GROUP_OWNER?groupId='+#groupId, 'GROUP_MEMBER?groupId='+#groupId)")
@Operation(module = Operation.Modules.PROJECT,
name = "新增评论",
involvedProjectId = "#projectId")
public JsonData<Void> create(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@RequestBody @Valid RemarkCreateRequest request) {
@RequestBody @Valid DiscussionCreateRequest request) {
DatabasirUserDetails principal = (DatabasirUserDetails) SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal();
Integer userId = principal.getUserPojo().getId();
documentRemarkService.create(groupId, projectId, userId, request);
documentDiscussionService.create(groupId, projectId, userId, request);
return JsonData.ok();
}
}

View File

@ -85,13 +85,15 @@ public interface Routes {
String EXPORT = BASE + "/projects/{projectId}/document_files";
}
interface DocumentRemark {
interface DocumentDiscussion {
String LIST = BASE + "/groups/{groupId}/projects/{projectId}/remarks";
String DISCUSSION_BASE = BASE + "/groups/{groupId}/projects/{projectId}/discussions";
String CREATE = BASE + "/groups/{groupId}/projects/{projectId}/remarks";
String LIST = DISCUSSION_BASE;
String DELETE = BASE + "/groups/{groupId}/projects/{projectId}/remarks/{remarkId}";
String CREATE = DISCUSSION_BASE;
String DELETE = DISCUSSION_BASE + "/{discussionId}";
}
interface Setting {

View File

@ -8,6 +8,8 @@ import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Mapper(componentModel = "spring", uses = JsonConverter.class, unmappedTargetPolicy = ReportingPolicy.WARN)
public interface DocumentResponseConverter {
@ -20,6 +22,32 @@ public interface DocumentResponseConverter {
List<TableIndexDocumentPojo> indexes,
List<TableTriggerDocumentPojo> triggers);
@Mapping(target = "columns", source = "columns")
@Mapping(target = "indexes", source = "indexes")
@Mapping(target = "triggers", source = "triggers")
@SuppressWarnings("checkstyle:all")
DatabaseDocumentResponse.TableDocumentResponse of(TableDocumentPojo tableDocument,
Integer discussionCount,
List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> columns,
List<TableIndexDocumentPojo> indexes,
List<TableTriggerDocumentPojo> triggers);
DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse of(TableColumnDocumentPojo pojo,
Integer discussionCount);
default List<DatabaseDocumentResponse.TableDocumentResponse.ColumnDocumentResponse> of(
List<TableColumnDocumentPojo> columns,
String tableName,
Map<String, Integer> discussionCountMapByJoinName) {
return columns.stream()
.map(column -> {
Integer count = discussionCountMapByJoinName.get(tableName + "." + column.getName());
return of(column, count);
})
.collect(Collectors.toList());
}
@Mapping(target = "columnNames", source = "columnNameArray")
DatabaseDocumentResponse.TableDocumentResponse.IndexDocumentResponse of(TableIndexDocumentPojo indexDocument);

View File

@ -9,6 +9,8 @@ import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Mapper(componentModel = "spring", uses = JsonConverter.class, unmappedTargetPolicy = ReportingPolicy.WARN)
public interface DocumentSimpleResponseConverter {
@ -17,5 +19,17 @@ public interface DocumentSimpleResponseConverter {
@Mapping(target = "createAt", source = "databaseDocument.createAt")
@Mapping(target = "documentVersion", source = "databaseDocument.version")
DatabaseDocumentSimpleResponse of(DatabaseDocumentPojo databaseDocument,
List<TableDocumentPojo> tables);
List<DatabaseDocumentSimpleResponse.TableData> tables);
DatabaseDocumentSimpleResponse.TableData of(TableDocumentPojo tables, Integer discussionCount);
default List<DatabaseDocumentSimpleResponse.TableData> of(List<TableDocumentPojo> tables,
Map<String, Integer> discussionCountMapByTableName) {
return tables.stream()
.map(table -> {
Integer count = discussionCountMapByTableName.get(table.getName());
return of(table, count);
})
.collect(Collectors.toList());
}
}

View File

@ -46,6 +46,8 @@ public class DatabaseDocumentResponse {
private String comment;
private Integer discussionCount;
@Builder.Default
private List<ColumnDocumentResponse> columns = new ArrayList<>();
@ -82,6 +84,8 @@ public class DatabaseDocumentResponse {
private String defaultValue;
private Integer discussionCount;
private LocalDateTime createAt;
}

View File

@ -35,5 +35,7 @@ public class DatabaseDocumentSimpleResponse {
private String type;
private String comment;
private Integer discussionCount;
}
}

View File

@ -15,8 +15,10 @@ import com.databasir.core.meta.data.DatabaseMeta;
import com.databasir.core.render.markdown.MarkdownBuilder;
import com.databasir.dao.impl.*;
import com.databasir.dao.tables.pojos.*;
import com.databasir.dao.value.DocumentDiscussionCountPojo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jooq.tools.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@ -55,6 +57,8 @@ public class DocumentService {
private final TableTriggerDocumentDao tableTriggerDocumentDao;
private final DocumentDiscussionDao documentDiscussionDao;
private final DocumentPojoConverter documentPojoConverter;
private final DocumentResponseConverter documentResponseConverter;
@ -129,21 +133,22 @@ public class DocumentService {
}
public Optional<DatabaseDocumentSimpleResponse> getSimpleOneByProjectId(Integer projectId, Long version) {
Optional<DatabaseDocumentPojo> documentOption;
if (version == null) {
return databaseDocumentDao.selectNotArchivedByProjectId(projectId)
.map(document -> {
Integer id = document.getId();
var tables = tableDocumentDao.selectByDatabaseDocumentId(id);
return documentSimpleResponseConverter.of(document, tables);
});
documentOption = databaseDocumentDao.selectNotArchivedByProjectId(projectId);
} else {
return databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, version)
.map(document -> {
Integer id = document.getId();
var tables = tableDocumentDao.selectByDatabaseDocumentId(id);
return documentSimpleResponseConverter.of(document, tables);
});
documentOption = databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, version);
}
return documentOption.map(document -> {
Integer id = document.getId();
var tables = tableDocumentDao.selectByDatabaseDocumentId(id);
var discussionCountMapByTableName =
documentDiscussionDao.selectTableDiscussionCount(projectId)
.stream()
.collect(Collectors.toMap(d -> d.getTableName(), d -> d.getCount(), (a, b) -> a));
var tableMetas = documentSimpleResponseConverter.of(tables, discussionCountMapByTableName);
return documentSimpleResponseConverter.of(document, tableMetas);
});
}
public Optional<DatabaseDocumentResponse> getOneByProjectId(Integer projectId, Long version) {
@ -207,19 +212,30 @@ public class DocumentService {
tableIndexDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
var triggers =
tableTriggerDocumentDao.selectByDatabaseDocumentIdAndIdIn(databaseDocumentId, tableIds);
var discussions = documentDiscussionDao.selectAllDiscussionCount(projectId);
Map<Integer, List<TableColumnDocumentPojo>> columnsGroupByTableMetaId = columns.stream()
.collect(Collectors.groupingBy(TableColumnDocumentPojo::getTableDocumentId));
Map<Integer, List<TableIndexDocumentPojo>> indexesGroupByTableMetaId = indexes.stream()
.collect(Collectors.groupingBy(TableIndexDocumentPojo::getTableDocumentId));
Map<Integer, List<TableTriggerDocumentPojo>> triggersGroupByTableMetaId = triggers.stream()
.collect(Collectors.groupingBy(TableTriggerDocumentPojo::getTableDocumentId));
Map<String, Integer> discussionCountMapByJoinName = discussions.stream()
.collect(Collectors.toMap(
d -> String.join(".",
d.getTableName(),
StringUtils.defaultIfBlank(d.getColumnName(), "")),
DocumentDiscussionCountPojo::getCount,
(a, b) -> a));
return tables.stream()
.map(table -> {
Integer tableId = table.getId();
var subColumns = columnsGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
var subIndexes = indexesGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
var subTriggers = triggersGroupByTableMetaId.getOrDefault(tableId, Collections.emptyList());
return documentResponseConverter.of(table, subColumns, subIndexes, subTriggers);
var discussionCount = discussionCountMapByJoinName.get(table.getName());
var columnResponseList =
documentResponseConverter.of(subColumns, table.getName(), discussionCountMapByJoinName);
return documentResponseConverter.of(table, discussionCount, columnResponseList, subIndexes, subTriggers);
})
.collect(Collectors.toList());
}

View File

@ -0,0 +1,17 @@
package com.databasir.core.domain.remark.converter;
import com.databasir.core.domain.remark.data.DiscussionResponse;
import com.databasir.dao.tables.pojos.DocumentRemarkPojo;
import com.databasir.dao.tables.pojos.UserPojo;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(componentModel = "spring")
public interface DiscussionResponseConverter {
@Mapping(target = "id", source = "remark.id")
@Mapping(target = "createAt", source = "remark.createAt")
@Mapping(target = "content", source = "remark.remark")
DiscussionResponse of(DocumentRemarkPojo remark,
UserPojo discussBy);
}

View File

@ -1,19 +0,0 @@
package com.databasir.core.domain.remark.converter;
import com.databasir.core.domain.remark.data.RemarkResponse;
import com.databasir.dao.tables.pojos.DocumentRemarkPojo;
import com.databasir.dao.tables.pojos.UserPojo;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(componentModel = "spring")
public interface RemarkResponseConverter {
@Mapping(target = "remarkBy.userId", source = "remarkBy.id")
@Mapping(target = "remarkBy.nickname", source = "remarkBy.nickname")
@Mapping(target = "remarkBy.email", source = "remarkBy.email")
@Mapping(target = "id", source = "remark.id")
@Mapping(target = "createAt", source = "remark.createAt")
RemarkResponse of(DocumentRemarkPojo remark,
UserPojo remarkBy);
}

View File

@ -6,10 +6,10 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class RemarkCreateRequest {
public class DiscussionCreateRequest {
@NotBlank
private String remark;
private String content;
@NotNull
private String tableName;

View File

@ -10,7 +10,7 @@ import java.util.ArrayList;
import java.util.List;
@Data
public class RemarkListCondition {
public class DiscussionListCondition {
@NotBlank
private String tableName;

View File

@ -5,20 +5,20 @@ import lombok.Data;
import java.time.LocalDateTime;
@Data
public class RemarkResponse {
public class DiscussionResponse {
private Integer id;
private Integer projectId;
private String remark;
private String content;
private RemarkUser remarkBy;
private DiscussByUser discussBy;
private LocalDateTime createAt;
@Data
public static class RemarkUser {
public static class DiscussByUser {
private Integer userId;

View File

@ -1,11 +1,11 @@
package com.databasir.core.domain.remark.service;
import com.databasir.common.exception.Forbidden;
import com.databasir.core.domain.remark.converter.RemarkResponseConverter;
import com.databasir.core.domain.remark.data.RemarkCreateRequest;
import com.databasir.core.domain.remark.data.RemarkListCondition;
import com.databasir.core.domain.remark.data.RemarkResponse;
import com.databasir.dao.impl.DocumentRemarkDao;
import com.databasir.core.domain.remark.converter.DiscussionResponseConverter;
import com.databasir.core.domain.remark.data.DiscussionCreateRequest;
import com.databasir.core.domain.remark.data.DiscussionListCondition;
import com.databasir.core.domain.remark.data.DiscussionResponse;
import com.databasir.dao.impl.DocumentDiscussionDao;
import com.databasir.dao.impl.ProjectDao;
import com.databasir.dao.impl.UserDao;
import com.databasir.dao.tables.pojos.DocumentRemarkPojo;
@ -22,32 +22,32 @@ import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class DocumentRemarkService {
public class DocumentDiscussionService {
private final DocumentRemarkDao documentRemarkDao;
private final DocumentDiscussionDao documentDiscussionDao;
private final ProjectDao projectDao;
private final UserDao userDao;
private final RemarkResponseConverter remarkResponseConverter;
private final DiscussionResponseConverter discussionResponseConverter;
public void deleteById(Integer groupId,
Integer projectId,
Integer remarkId) {
Integer discussionId) {
if (projectDao.exists(groupId, projectId)) {
documentRemarkDao.deleteById(remarkId);
documentDiscussionDao.deleteById(discussionId);
} else {
throw new Forbidden();
}
}
public Page<RemarkResponse> list(Integer groupId,
Integer projectId,
Pageable pageable,
RemarkListCondition condition) {
public Page<DiscussionResponse> list(Integer groupId,
Integer projectId,
Pageable pageable,
DiscussionListCondition condition) {
if (projectDao.exists(groupId, projectId)) {
Page<DocumentRemarkPojo> data = documentRemarkDao.selectByPage(pageable, condition.toCondition(projectId));
Page<DocumentRemarkPojo> data = documentDiscussionDao.selectByPage(pageable, condition.toCondition(projectId));
Set<Integer> userIdList = data.getContent()
.stream()
.map(DocumentRemarkPojo::getUserId)
@ -58,22 +58,22 @@ public class DocumentRemarkService {
return data
.map(remarkPojo -> {
UserPojo userPojo = userMapById.get(remarkPojo.getUserId());
return remarkResponseConverter.of(remarkPojo, userPojo);
return discussionResponseConverter.of(remarkPojo, userPojo);
});
} else {
throw new Forbidden();
}
}
public void create(Integer groupId, Integer projectId, Integer userId, RemarkCreateRequest request) {
public void create(Integer groupId, Integer projectId, Integer userId, DiscussionCreateRequest request) {
if (projectDao.exists(groupId, projectId)) {
DocumentRemarkPojo pojo = new DocumentRemarkPojo();
pojo.setUserId(userId);
pojo.setProjectId(projectId);
pojo.setRemark(request.getRemark());
pojo.setRemark(request.getContent());
pojo.setTableName(request.getTableName());
pojo.setColumnName(request.getColumnName());
documentRemarkDao.insertAndReturnId(pojo);
documentDiscussionDao.insertAndReturnId(pojo);
} else {
throw new Forbidden();
}

View File

@ -0,0 +1,52 @@
package com.databasir.dao.impl;
import com.databasir.dao.tables.pojos.DocumentRemarkPojo;
import com.databasir.dao.value.DocumentDiscussionCountPojo;
import lombok.Getter;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import static com.databasir.dao.Tables.DOCUMENT_REMARK;
@Repository
public class DocumentDiscussionDao extends BaseDao<DocumentRemarkPojo> {
@Autowired
@Getter
private DSLContext dslContext;
public DocumentDiscussionDao() {
super(DOCUMENT_REMARK, DocumentRemarkPojo.class);
}
public Optional<DocumentRemarkPojo> selectByProjectIdAndId(Integer projectId, Integer id) {
return this.getDslContext()
.selectFrom(DOCUMENT_REMARK).where(DOCUMENT_REMARK.PROJECT_ID.eq(projectId)
.and(DOCUMENT_REMARK.ID.eq(id)))
.fetchOptionalInto(DocumentRemarkPojo.class);
}
public List<DocumentDiscussionCountPojo> selectTableDiscussionCount(Integer projectId) {
return this.selectDiscussionCount(DOCUMENT_REMARK.PROJECT_ID.eq(projectId)
.and(DOCUMENT_REMARK.COLUMN_NAME.isNull()));
}
public List<DocumentDiscussionCountPojo> selectAllDiscussionCount(Integer projectId) {
return this.selectDiscussionCount(DOCUMENT_REMARK.PROJECT_ID.eq(projectId));
}
public List<DocumentDiscussionCountPojo> selectDiscussionCount(Condition condition) {
return this.getDslContext()
.select(DSL.count(), DOCUMENT_REMARK.TABLE_NAME, DOCUMENT_REMARK.COLUMN_NAME)
.from(DOCUMENT_REMARK)
.where(condition)
.groupBy(DOCUMENT_REMARK.TABLE_NAME, DOCUMENT_REMARK.COLUMN_NAME)
.fetchInto(DocumentDiscussionCountPojo.class);
}
}

View File

@ -1,30 +0,0 @@
package com.databasir.dao.impl;
import com.databasir.dao.tables.pojos.DocumentRemarkPojo;
import lombok.Getter;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Optional;
import static com.databasir.dao.Tables.DOCUMENT_REMARK;
@Repository
public class DocumentRemarkDao extends BaseDao<DocumentRemarkPojo> {
@Autowired
@Getter
private DSLContext dslContext;
public DocumentRemarkDao() {
super(DOCUMENT_REMARK, DocumentRemarkPojo.class);
}
public Optional<DocumentRemarkPojo> selectByProjectIdAndId(Integer projectId, Integer id) {
return this.getDslContext()
.selectFrom(DOCUMENT_REMARK).where(DOCUMENT_REMARK.PROJECT_ID.eq(projectId)
.and(DOCUMENT_REMARK.ID.eq(id)))
.fetchOptionalInto(DocumentRemarkPojo.class);
}
}

View File

@ -0,0 +1,15 @@
package com.databasir.dao.value;
import lombok.Data;
@Data
public class DocumentDiscussionCountPojo {
private Integer projectId;
private String tableName;
private String columnName;
private Integer count;
}