mirror of
https://github.com/dataelement/bisheng.git
synced 2026-08-30 17:58:00 +08:00
feat: update approval and knowledge flows
This commit is contained in:
+1
-5
@@ -179,13 +179,9 @@ steps:
|
||||
|
||||
cd /opt/code/bisheng
|
||||
|
||||
echo "======= reset local changes ======="
|
||||
|
||||
git reset --hard HEAD
|
||||
|
||||
echo "======= pull latest code ======="
|
||||
|
||||
git pull origin feat/2.5.0-sg
|
||||
git pull
|
||||
|
||||
echo "======= restart backend ======="
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from bisheng.knowledge.domain.models.knowledge_file import (
|
||||
KnowledgeFileDao,
|
||||
KnowledgeFileStatus,
|
||||
)
|
||||
from bisheng.knowledge.domain.models.knowledge_space_scope import KnowledgeSpaceLevelEnum
|
||||
from bisheng.knowledge.domain.models.knowledge_space_scope import KnowledgeSpaceLevelEnum, KnowledgeSpaceScopeDao
|
||||
|
||||
KNOWLEDGE_SPACE_CREATE_SCENARIO = 'knowledge_space_create_request'
|
||||
FILE_PUBLISH_SCENARIO = 'knowledge_space_file_publish_request'
|
||||
@@ -197,6 +197,10 @@ class KnowledgeSpaceFilePublishApprovalHandler:
|
||||
return file
|
||||
return None
|
||||
|
||||
async def _space_level(self, space_id: int) -> KnowledgeSpaceLevelEnum:
|
||||
scope = await KnowledgeSpaceScopeDao.aget_by_space_id(space_id)
|
||||
return scope.level if scope else KnowledgeSpaceLevelEnum.PERSONAL
|
||||
|
||||
async def on_approved(self, instance_id: int, payload_snapshot: dict) -> dict:
|
||||
from bisheng.knowledge.domain.services.knowledge_space_service import KnowledgeSpaceService
|
||||
|
||||
@@ -235,6 +239,12 @@ class KnowledgeSpaceFilePublishApprovalHandler:
|
||||
raise ValueError('target space not found')
|
||||
if not source_file or source_file.knowledge_id != source_space_id:
|
||||
raise ValueError('source file not found')
|
||||
source_level = await self._space_level(source_space_id)
|
||||
target_level = await self._space_level(target_space_id)
|
||||
if source_level not in {KnowledgeSpaceLevelEnum.TEAM, KnowledgeSpaceLevelEnum.PERSONAL}:
|
||||
raise ValueError('source space must be team or personal')
|
||||
if target_level not in {KnowledgeSpaceLevelEnum.PUBLIC, KnowledgeSpaceLevelEnum.DEPARTMENT}:
|
||||
raise ValueError('target space must be public or department')
|
||||
if source_file.status != KnowledgeFileStatus.SUCCESS.value:
|
||||
raise ValueError('source file is not parsed successfully')
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ from bisheng.approval.domain.services.shougang_approval_handler import (
|
||||
KnowledgeSpaceFilePublishApprovalHandler,
|
||||
)
|
||||
from bisheng.database.models.department import DepartmentDao, UserDepartmentDao
|
||||
from bisheng.knowledge.domain.models.knowledge import KnowledgeDao, KnowledgeTypeEnum
|
||||
from bisheng.knowledge.domain.models.knowledge import AuthTypeEnum, KnowledgeDao, KnowledgeTypeEnum
|
||||
from bisheng.knowledge.domain.models.knowledge_file import (
|
||||
FileType,
|
||||
KnowledgeFileDao,
|
||||
@@ -69,6 +69,23 @@ class ShougangApprovalService:
|
||||
return True
|
||||
return bool(await DepartmentDao.aget_user_admin_departments(login_user.user_id))
|
||||
|
||||
@staticmethod
|
||||
def _enum_value(value) -> Any:
|
||||
return value.value if hasattr(value, 'value') else value
|
||||
|
||||
@classmethod
|
||||
def _is_private_personal_space_create(cls, params: dict) -> bool:
|
||||
return (
|
||||
cls._enum_value(params.get('space_level')) == KnowledgeSpaceLevelEnum.PERSONAL.value
|
||||
and cls._enum_value(params.get('auth_type')) == AuthTypeEnum.PRIVATE.value
|
||||
and not bool(params.get('is_released'))
|
||||
)
|
||||
|
||||
async def _requires_create_approval(self, *, login_user, params: dict) -> bool:
|
||||
if self._is_private_personal_space_create(params):
|
||||
return False
|
||||
return not await self._is_create_approval_exempt(login_user)
|
||||
|
||||
async def _task_approver_user_ids(self, task_ids: list[int]) -> list[int]:
|
||||
approver_user_ids: list[int] = []
|
||||
seen: set[int] = set()
|
||||
@@ -144,7 +161,7 @@ class ShougangApprovalService:
|
||||
params = self._space_create_params(req)
|
||||
await space_service.validate_knowledge_space_create(**params)
|
||||
return ShougangKnowledgeSpaceCreateValidateResp(
|
||||
approval_required=not await self._is_create_approval_exempt(login_user)
|
||||
approval_required=await self._requires_create_approval(login_user=login_user, params=params)
|
||||
)
|
||||
|
||||
async def submit_knowledge_space_create(
|
||||
@@ -157,7 +174,7 @@ class ShougangApprovalService:
|
||||
params = self._space_create_params(req)
|
||||
await space_service.validate_knowledge_space_create(**params)
|
||||
|
||||
if await self._is_create_approval_exempt(login_user):
|
||||
if not await self._requires_create_approval(login_user=login_user, params=params):
|
||||
created = await space_service.create_knowledge_space(**params)
|
||||
get_info = getattr(space_service, 'get_space_info', None)
|
||||
space_info = await get_info(created.id) if get_info else created
|
||||
@@ -189,6 +206,11 @@ class ShougangApprovalService:
|
||||
'applicant_user_id': login_user.user_id,
|
||||
'applicant_user_name': login_user.user_name,
|
||||
'applicant_department_id': applicant_department_id,
|
||||
'space_level': params.get('space_level'),
|
||||
'auth_type': params.get('auth_type'),
|
||||
'is_released': params.get('is_released'),
|
||||
'department_id': params.get('department_id'),
|
||||
'user_group_id': params.get('user_group_id'),
|
||||
'create_params': params,
|
||||
},
|
||||
)
|
||||
@@ -238,9 +260,16 @@ class ShougangApprovalService:
|
||||
if target_level not in {KnowledgeSpaceLevelEnum.PUBLIC, KnowledgeSpaceLevelEnum.DEPARTMENT}:
|
||||
raise HTTPException(status_code=400, detail='目标知识空间必须是公共或业务域知识库')
|
||||
if space_service is not None:
|
||||
await space_service._require_permission_id('knowledge_space', target_space_id, 'upload_file')
|
||||
await space_service._require_permission_id('knowledge_space', target_space_id, 'view_space')
|
||||
return target_space
|
||||
|
||||
async def _space_level_for_payload(self, space) -> str:
|
||||
level = getattr(space, 'space_level', None)
|
||||
if level is None:
|
||||
scope = await KnowledgeSpaceScopeDao.aget_by_space_id(int(space.id))
|
||||
level = scope.level if scope else KnowledgeSpaceLevelEnum.PERSONAL
|
||||
return self._enum_value(level)
|
||||
|
||||
async def list_file_publish_target_spaces(self, *, space_service) -> ShougangFilePublishTargetSpacesResp:
|
||||
grouped = await space_service.get_grouped_spaces()
|
||||
spaces = list(grouped.public_spaces or []) + list(grouped.department_spaces or [])
|
||||
@@ -333,6 +362,7 @@ class ShougangApprovalService:
|
||||
space_service=space_service,
|
||||
)
|
||||
target_space = await self._ensure_publish_target_space(req.target_space_id, space_service=space_service)
|
||||
target_level = await self._space_level_for_payload(target_space)
|
||||
|
||||
target_document_title = None
|
||||
if req.target_document_id:
|
||||
@@ -372,10 +402,12 @@ class ShougangApprovalService:
|
||||
'applicant_department_id': applicant_department_id,
|
||||
'source_space_id': int(source_space.id),
|
||||
'source_space_name': source_space.name,
|
||||
'source_space_level': self._enum_value(source_level),
|
||||
'source_file_id': int(source_file.id),
|
||||
'source_file_name': file_name,
|
||||
'target_space_id': int(target_space.id),
|
||||
'target_space_name': target_space.name,
|
||||
'target_space_level': target_level,
|
||||
'target_document_id': req.target_document_id,
|
||||
'target_document_title': target_document_title,
|
||||
},
|
||||
|
||||
@@ -64,6 +64,9 @@ async def test_knowledge_space_create_submit_requires_approval_without_creating(
|
||||
approval_gate.request_or_pass.assert_awaited_once()
|
||||
gate_req = approval_gate.request_or_pass.await_args.args[0]
|
||||
assert gate_req.scenario_code == "knowledge_space_create_request"
|
||||
assert gate_req.payload_snapshot["space_level"] == KnowledgeSpaceLevelEnum.TEAM.value
|
||||
assert gate_req.payload_snapshot["auth_type"] == AuthTypeEnum.PUBLIC.value
|
||||
assert gate_req.payload_snapshot["is_released"] is True
|
||||
assert gate_req.payload_snapshot["create_params"]["name"] == "团队资料库"
|
||||
assert gate_req.payload_snapshot["create_params"]["user_group_id"] == 7
|
||||
assert result["decision"] == "pending"
|
||||
@@ -109,6 +112,44 @@ async def test_knowledge_space_create_submit_exempt_user_creates_directly(monkey
|
||||
assert result["space"]["id"] == 88
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_personal_private_space_create_skips_approval_for_regular_user(monkeypatch):
|
||||
from bisheng.approval.domain.schemas.shougang_approval_schema import (
|
||||
ShougangKnowledgeSpaceCreateSubmitReq,
|
||||
)
|
||||
from bisheng.approval.domain.services.shougang_approval_service import (
|
||||
ShougangApprovalService,
|
||||
)
|
||||
from bisheng.knowledge.domain.models.knowledge import AuthTypeEnum
|
||||
from bisheng.knowledge.domain.models.knowledge_space_scope import KnowledgeSpaceLevelEnum
|
||||
|
||||
created_space = SimpleNamespace(id=89)
|
||||
space_service = SimpleNamespace(
|
||||
validate_knowledge_space_create=AsyncMock(return_value=None),
|
||||
create_knowledge_space=AsyncMock(return_value=created_space),
|
||||
get_space_info=AsyncMock(return_value={"id": 89, "name": "私人资料库"}),
|
||||
)
|
||||
approval_gate = SimpleNamespace(request_or_pass=AsyncMock())
|
||||
service = ShougangApprovalService(approval_gate=approval_gate)
|
||||
monkeypatch.setattr(service, "_is_create_approval_exempt", AsyncMock(return_value=False))
|
||||
|
||||
result = await service.submit_knowledge_space_create(
|
||||
req=ShougangKnowledgeSpaceCreateSubmitReq(
|
||||
name="私人资料库",
|
||||
auth_type=AuthTypeEnum.PRIVATE,
|
||||
is_released=False,
|
||||
space_level=KnowledgeSpaceLevelEnum.PERSONAL,
|
||||
),
|
||||
login_user=SimpleNamespace(user_id=11, user_name="普通用户", tenant_id=1, is_admin=lambda: False),
|
||||
space_service=space_service,
|
||||
)
|
||||
|
||||
approval_gate.request_or_pass.assert_not_called()
|
||||
space_service.create_knowledge_space.assert_awaited_once()
|
||||
assert result["created"] is True
|
||||
assert result["space"]["id"] == 89
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_file_publish_source_requires_upload_file_permission():
|
||||
from bisheng.approval.domain.services.shougang_approval_service import ShougangApprovalService
|
||||
@@ -137,6 +178,27 @@ async def test_file_publish_source_requires_upload_file_permission():
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_file_publish_target_space_requires_view_space_not_upload_file(monkeypatch):
|
||||
from bisheng.approval.domain.services.shougang_approval_service import ShougangApprovalService
|
||||
from bisheng.knowledge.domain.models.knowledge import KnowledgeTypeEnum
|
||||
from bisheng.knowledge.domain.models.knowledge_space_scope import KnowledgeSpaceLevelEnum
|
||||
|
||||
monkeypatch.setattr(
|
||||
"bisheng.approval.domain.services.shougang_approval_service.KnowledgeDao.aquery_by_id",
|
||||
AsyncMock(return_value=SimpleNamespace(id=20, type=KnowledgeTypeEnum.SPACE.value, name="公共空间")),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"bisheng.approval.domain.services.shougang_approval_service.KnowledgeSpaceScopeDao.aget_by_space_id",
|
||||
AsyncMock(return_value=SimpleNamespace(level=KnowledgeSpaceLevelEnum.PUBLIC)),
|
||||
)
|
||||
space_service = SimpleNamespace(_require_permission_id=AsyncMock(return_value=None))
|
||||
|
||||
await ShougangApprovalService()._ensure_publish_target_space(20, space_service=space_service)
|
||||
|
||||
space_service._require_permission_id.assert_awaited_once_with("knowledge_space", 20, "view_space")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_file_publish_submit_requires_team_or_personal_success_file(monkeypatch):
|
||||
from bisheng.approval.domain.schemas.shougang_approval_schema import ShougangFilePublishSubmitReq
|
||||
@@ -172,7 +234,11 @@ async def test_file_publish_submit_requires_team_or_personal_success_file(monkey
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(service, "_ensure_can_publish_file", AsyncMock(return_value=None))
|
||||
monkeypatch.setattr(service, "_ensure_publish_target_space", AsyncMock(return_value=SimpleNamespace(id=20, name="公共空间")))
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_ensure_publish_target_space",
|
||||
AsyncMock(return_value=SimpleNamespace(id=20, name="公共空间", space_level=KnowledgeSpaceLevelEnum.PUBLIC.value)),
|
||||
)
|
||||
monkeypatch.setattr(service, "_get_primary_department_id", AsyncMock(return_value=9))
|
||||
monkeypatch.setattr(service, "_task_approver_user_ids", AsyncMock(return_value=[]))
|
||||
|
||||
@@ -189,6 +255,8 @@ async def test_file_publish_submit_requires_team_or_personal_success_file(monkey
|
||||
|
||||
gate_req = service.approval_gate.request_or_pass.await_args.args[0]
|
||||
assert gate_req.scenario_code == "knowledge_space_file_publish_request"
|
||||
assert gate_req.payload_snapshot["source_space_level"] == KnowledgeSpaceLevelEnum.TEAM.value
|
||||
assert gate_req.payload_snapshot["target_space_level"] == KnowledgeSpaceLevelEnum.PUBLIC.value
|
||||
assert gate_req.payload_snapshot["source_file_id"] == 100
|
||||
assert gate_req.payload_snapshot["target_space_id"] == 20
|
||||
assert result["created"] is False
|
||||
@@ -214,7 +282,11 @@ async def test_file_publish_submit_rejects_invalid_target_document(monkeypatch):
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(service, "_ensure_can_publish_file", AsyncMock(return_value=None))
|
||||
monkeypatch.setattr(service, "_ensure_publish_target_space", AsyncMock(return_value=SimpleNamespace(id=20, name="公共空间")))
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_ensure_publish_target_space",
|
||||
AsyncMock(return_value=SimpleNamespace(id=20, name="公共空间", space_level=KnowledgeSpaceLevelEnum.PUBLIC.value)),
|
||||
)
|
||||
version_service = SimpleNamespace(search_version_sources=AsyncMock(return_value=[]))
|
||||
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
@@ -371,6 +443,58 @@ async def test_file_publish_handler_links_existing_file_version_once(monkeypatch
|
||||
handler._copy_file.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_file_publish_handler_revalidates_source_and_target_scope_before_copy(monkeypatch):
|
||||
from bisheng.approval.domain.services.shougang_approval_handler import KnowledgeSpaceFilePublishApprovalHandler
|
||||
from bisheng.knowledge.domain.models.knowledge import KnowledgeTypeEnum
|
||||
from bisheng.knowledge.domain.models.knowledge_file import KnowledgeFileStatus
|
||||
from bisheng.knowledge.domain.models.knowledge_space_scope import KnowledgeSpaceLevelEnum
|
||||
|
||||
handler = KnowledgeSpaceFilePublishApprovalHandler()
|
||||
monkeypatch.setattr(
|
||||
"bisheng.approval.domain.services.shougang_approval_handler.KnowledgeFileDao.aget_file_by_filters",
|
||||
AsyncMock(return_value=[]),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"bisheng.approval.domain.services.shougang_approval_handler.KnowledgeDao.aquery_by_id",
|
||||
AsyncMock(
|
||||
side_effect=[
|
||||
SimpleNamespace(id=10, type=KnowledgeTypeEnum.SPACE.value, name="团队空间"),
|
||||
SimpleNamespace(id=20, type=KnowledgeTypeEnum.SPACE.value, name="个人空间"),
|
||||
]
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"bisheng.approval.domain.services.shougang_approval_handler.KnowledgeFileDao.query_by_id",
|
||||
AsyncMock(return_value=SimpleNamespace(id=100, knowledge_id=10, status=KnowledgeFileStatus.SUCCESS.value)),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"bisheng.approval.domain.services.shougang_approval_handler.KnowledgeSpaceScopeDao.aget_by_space_id",
|
||||
AsyncMock(
|
||||
side_effect=[
|
||||
SimpleNamespace(level=KnowledgeSpaceLevelEnum.TEAM),
|
||||
SimpleNamespace(level=KnowledgeSpaceLevelEnum.PERSONAL),
|
||||
]
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(handler, "_copy_file", Mock())
|
||||
|
||||
with pytest.raises(ValueError, match="target space must be public or department"):
|
||||
await handler.on_approved(
|
||||
102,
|
||||
{
|
||||
"tenant_id": 1,
|
||||
"applicant_user_id": 11,
|
||||
"applicant_user_name": "申请人",
|
||||
"source_space_id": 10,
|
||||
"source_file_id": 100,
|
||||
"target_space_id": 20,
|
||||
},
|
||||
)
|
||||
|
||||
handler._copy_file.assert_not_called()
|
||||
|
||||
|
||||
def test_shougang_scenarios_registered_in_default_presets():
|
||||
from bisheng.approval.domain.services.approval_registry import ApprovalRegistry
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ export type PublishToSquare = "yes" | "no";
|
||||
export interface CreateKnowledgeSpaceFormData {
|
||||
name: string;
|
||||
description: string;
|
||||
reason?: string;
|
||||
joinPolicy: JoinPolicy;
|
||||
publishToSquare: PublishToSquare;
|
||||
spaceLevel: SpaceLevel;
|
||||
@@ -89,6 +90,7 @@ interface CreateKnowledgeSpaceDrawerProps {
|
||||
mode?: "create" | "edit";
|
||||
editingSpace?: KnowledgeSpace | null;
|
||||
initialSpaceLevel?: SpaceLevel;
|
||||
showApprovalReason?: boolean;
|
||||
}
|
||||
|
||||
export function CreateKnowledgeSpaceDrawer({
|
||||
@@ -100,12 +102,14 @@ export function CreateKnowledgeSpaceDrawer({
|
||||
mode = "create",
|
||||
editingSpace,
|
||||
initialSpaceLevel,
|
||||
showApprovalReason = false,
|
||||
}: CreateKnowledgeSpaceDrawerProps) {
|
||||
const { showToast } = useToastContext();
|
||||
const confirm = useConfirm();
|
||||
const localize = useLocalize();
|
||||
const [name, setName] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [reason, setReason] = useState("");
|
||||
const [joinPolicy, setJoinPolicy] = useState<JoinPolicy>("review");
|
||||
const [publishToSquare, setPublishToSquare] = useState<PublishToSquare>("yes");
|
||||
const [spaceLevel, setSpaceLevel] = useState<SpaceLevel>(SpaceLevel.PERSONAL);
|
||||
@@ -191,6 +195,7 @@ export function CreateKnowledgeSpaceDrawer({
|
||||
const resetForm = () => {
|
||||
setName("");
|
||||
setDescription("");
|
||||
setReason("");
|
||||
setJoinPolicy("review");
|
||||
setPublishToSquare("yes");
|
||||
setSpaceLevel(SpaceLevel.PERSONAL);
|
||||
@@ -419,6 +424,7 @@ export function CreateKnowledgeSpaceDrawer({
|
||||
const payload: CreateKnowledgeSpaceFormData = {
|
||||
name: name.trim(),
|
||||
description: description.trim(),
|
||||
reason: mode === "create" && showApprovalReason ? reason.trim() || undefined : undefined,
|
||||
joinPolicy,
|
||||
publishToSquare: needPublishOption ? publishToSquare : "no",
|
||||
spaceLevel,
|
||||
@@ -674,6 +680,20 @@ export function CreateKnowledgeSpaceDrawer({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{mode === "create" && showApprovalReason && (
|
||||
<div className="space-y-2">
|
||||
<Label className="text-sm text-[#1D2129] font-medium">
|
||||
申请意见
|
||||
</Label>
|
||||
<Textarea
|
||||
value={reason}
|
||||
onChange={(e) => setReason(e.target.value)}
|
||||
placeholder="请输入申请意见"
|
||||
className="min-h-[88px] rounded-[6px] border-[#E5E6EB] bg-[#fff] text-[14px]"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 权限设置 */}
|
||||
<div className="space-y-3">
|
||||
<Label className="text-sm text-[#1D2129] font-medium">
|
||||
|
||||
@@ -138,18 +138,20 @@ jest.mock("~/components/ui/icon/File", () => ({
|
||||
}));
|
||||
|
||||
jest.mock("../CreateKnowledgeSpaceDrawer", () => ({
|
||||
CreateKnowledgeSpaceDrawer: ({ open, initialSpaceLevel, mode = "create", editingSpace, onConfirm }: any) => {
|
||||
CreateKnowledgeSpaceDrawer: ({ open, initialSpaceLevel, mode = "create", editingSpace, showApprovalReason, onConfirm }: any) => {
|
||||
if (!open) return null;
|
||||
return (
|
||||
<div data-testid="create-space-drawer">
|
||||
mode:{mode}
|
||||
initial:{initialSpaceLevel}
|
||||
editing:{editingSpace?.name || ""}
|
||||
approvalReason:{String(Boolean(showApprovalReason))}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onConfirm?.({
|
||||
name: "新空间",
|
||||
description: "说明",
|
||||
reason: "申请创建团队知识库",
|
||||
joinPolicy: "review",
|
||||
publishToSquare: "yes",
|
||||
spaceLevel: initialSpaceLevel,
|
||||
@@ -584,6 +586,7 @@ describe("PortalKnowledgeWorkbench", () => {
|
||||
renderWorkbench();
|
||||
|
||||
fireEvent.click(await screen.findByRole("button", { name: "新增团队知识库知识空间" }));
|
||||
expect(screen.getByTestId("create-space-drawer")).toHaveTextContent("approvalReason:true");
|
||||
fireEvent.click(screen.getByRole("button", { name: "提交创建" }));
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -597,6 +600,7 @@ describe("PortalKnowledgeWorkbench", () => {
|
||||
user_group_id: undefined,
|
||||
auto_tag_enabled: false,
|
||||
auto_tag_library_id: null,
|
||||
reason: "申请创建团队知识库",
|
||||
});
|
||||
});
|
||||
expect(createSpaceApi).not.toHaveBeenCalled();
|
||||
|
||||
@@ -1041,7 +1041,7 @@ export default function PortalKnowledgeWorkbench() {
|
||||
department_id: form.departmentId,
|
||||
user_group_id: form.userGroupId,
|
||||
auto_tag_enabled: form.autoTagEnabled,
|
||||
auto_tag_library_id: form.autoTagLibraryId,
|
||||
auto_tag_library_id: form.autoTagLibraryId, reason: form.reason,
|
||||
});
|
||||
|
||||
if (result.created && result.space) {
|
||||
|
||||
@@ -381,6 +381,7 @@ export function PortalDialogs({
|
||||
mode={editingSpace ? "edit" : "create"}
|
||||
editingSpace={editingSpace}
|
||||
initialSpaceLevel={pendingCreateLevel}
|
||||
showApprovalReason
|
||||
onViewSpace={onViewCreatedSpace}
|
||||
onManageMembers={onManageEditingSpaceMembers}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user