mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix(workspace): harden workspace create and delete
This commit is contained in:
parent
b2f9976f44
commit
0a57cb3358
@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import vip.mate.exception.MateClawException;
|
||||
import vip.mate.i18n.I18nService;
|
||||
import vip.mate.wiki.service.WikiKnowledgeBaseService;
|
||||
import vip.mate.workspace.conversation.model.ConversationEntity;
|
||||
import vip.mate.workspace.conversation.repository.ConversationMapper;
|
||||
import vip.mate.workspace.core.model.WorkspaceAccessVO;
|
||||
@ -39,6 +40,7 @@ public class WorkspaceService {
|
||||
private final WorkspaceMapper workspaceMapper;
|
||||
private final WorkspaceMemberMapper memberMapper;
|
||||
private final ConversationMapper conversationMapper;
|
||||
private final WikiKnowledgeBaseService wikiKnowledgeBaseService;
|
||||
private final I18nService i18n;
|
||||
|
||||
/** 默认工作区 slug */
|
||||
@ -134,8 +136,34 @@ public class WorkspaceService {
|
||||
.eq(WorkspaceEntity::getSlug, slug));
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a URL-safe, unique slug from a workspace name. Non-alphanumeric
|
||||
* runs collapse to a single hyphen; a name with no ASCII alphanumerics
|
||||
* (e.g. a purely Chinese name) falls back to a generic base. A numeric
|
||||
* suffix is appended until the slug is free.
|
||||
*/
|
||||
private String generateUniqueSlug(String name) {
|
||||
String base = (name == null ? "" : name.toLowerCase())
|
||||
.replaceAll("[^a-z0-9]+", "-")
|
||||
.replaceAll("^-|-$", "");
|
||||
if (base.isBlank()) {
|
||||
base = "workspace";
|
||||
}
|
||||
String slug = base;
|
||||
int n = 1;
|
||||
while (getBySlug(slug) != null) {
|
||||
slug = base + "-" + (++n);
|
||||
}
|
||||
return slug;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public WorkspaceEntity create(WorkspaceEntity entity, Long creatorUserId) {
|
||||
// Auto-derive a slug from the name when the caller did not supply one,
|
||||
// so workspace creation never fails on the NOT NULL slug column.
|
||||
if (entity.getSlug() == null || entity.getSlug().isBlank()) {
|
||||
entity.setSlug(generateUniqueSlug(entity.getName()));
|
||||
}
|
||||
// 验证 slug 唯一
|
||||
if (getBySlug(entity.getSlug()) != null) {
|
||||
throw new MateClawException("err.workspace.slug_exists", "工作区标识已存在: " + entity.getSlug());
|
||||
@ -206,6 +234,14 @@ public class WorkspaceService {
|
||||
if (DEFAULT_SLUG.equals(existing.getSlug())) {
|
||||
throw new MateClawException("err.workspace.cannot_delete_default", "不能删除默认工作区");
|
||||
}
|
||||
// Refuse to delete a workspace that still owns wiki knowledge bases —
|
||||
// dropping the workspace row would orphan them. The caller must delete
|
||||
// the knowledge bases first.
|
||||
int kbCount = wikiKnowledgeBaseService.listByWorkspace(id).size();
|
||||
if (kbCount > 0) {
|
||||
throw new MateClawException("err.workspace.not_empty", 409,
|
||||
"工作区下还有 " + kbCount + " 个知识库,请先删除知识库再删除工作区");
|
||||
}
|
||||
workspaceMapper.deleteById(id);
|
||||
log.info("Deleted workspace: {} (id={})", existing.getName(), id);
|
||||
}
|
||||
|
||||
@ -173,6 +173,7 @@ err.workspace.not_member=\u7528\u6237\u4e0d\u662f\u8be5\u5de5\u4f5c\u533a\u7684\
|
||||
err.workspace.cannot_modify_owner=\u4e0d\u80fd\u4fee\u6539\u5de5\u4f5c\u533a\u62e5\u6709\u8005\u7684\u89d2\u8272
|
||||
err.workspace.cannot_remove_owner=\u4e0d\u80fd\u79fb\u9664\u5de5\u4f5c\u533a\u62e5\u6709\u8005
|
||||
err.workspace.insufficient_permission=\u6743\u9650\u4e0d\u8db3
|
||||
err.workspace.not_empty=\u5de5\u4f5c\u533a\u4e0b\u8fd8\u6709\u77e5\u8bc6\u5e93\uff0c\u8bf7\u5148\u5220\u9664\u77e5\u8bc6\u5e93\u540e\u518d\u5220\u9664\u5de5\u4f5c\u533a
|
||||
err.channel.not_found=\u6e20\u9053\u4e0d\u5b58\u5728
|
||||
err.channel.name_required=\u6e20\u9053\u540d\u79f0\u4e0d\u80fd\u4e3a\u7a7a
|
||||
err.channel.type_required=\u6e20\u9053\u7c7b\u578b\u4e0d\u80fd\u4e3a\u7a7a
|
||||
|
||||
@ -180,6 +180,7 @@ err.workspace.not_member=User is not a member of this workspace
|
||||
err.workspace.cannot_modify_owner=Cannot modify workspace owner role
|
||||
err.workspace.cannot_remove_owner=Cannot remove workspace owner
|
||||
err.workspace.insufficient_permission=Insufficient permission
|
||||
err.workspace.not_empty=Workspace still contains knowledge bases; delete them first
|
||||
# channel
|
||||
err.channel.not_found=Channel not found
|
||||
err.channel.name_required=Channel name cannot be empty
|
||||
|
||||
Loading…
Reference in New Issue
Block a user