p.tenant_id = #{q.tenantId} AND p.action_code = 'READ' AND p.revoked_at IS NULL AND p.valid_from <= CURRENT_TIMESTAMP AND (p.valid_to IS NULL OR CURRENT_TIMESTAMP < p.valid_to) AND (p.max_use_count IS NULL OR p.used_count < p.max_use_count) AND ((p.principal_type = 'USER' AND p.principal_id = #{q.userId}) OR (p.principal_type = 'ORG' AND p.include_child_orgs = FALSE AND p.principal_id IN #{id}) OR (p.principal_type = 'ORG' AND p.approved_org_scope = 'CHILDREN' AND p.source_type = 'WORKFLOW' AND p.granted_by_type = 'SERVICE' AND p.granted_by_id = 'dms-approved-read' AND p.action_code = 'READ' AND p.resource_type = 'FILE_VERSION' AND p.principal_id IN #{id}) OR (p.principal_type = 'ORG' AND p.include_child_orgs = TRUE AND p.principal_id IN #{id}) OR (p.principal_type = 'POSITION' AND p.principal_id IN #{id}) OR (p.principal_type = 'ROLE' AND p.principal_id IN #{id}) OR (p.principal_type = 'GROUP' AND p.principal_id IN #{id}) ) WITH RECURSIVE folder_ancestors(id, parent_id) AS ( SELECT f.id, f.parent_id FROM public.dms_folders f WHERE f.tenant_id = #{q.tenantId} AND f.id = #{q.folderId} AND f.f_delete_mark IS NULL UNION ALL SELECT parent.id, parent.parent_id FROM folder_ancestors child JOIN public.dms_folders parent ON parent.tenant_id = #{q.tenantId} AND parent.id = child.parent_id AND parent.f_delete_mark IS NULL) WITH RECURSIVE folder_descendants(id, parent_id) AS ( SELECT f.id, f.parent_id FROM public.dms_folders f WHERE f.tenant_id = #{q.tenantId} AND f.id = #{q.folderId} AND f.f_delete_mark IS NULL UNION ALL SELECT child.id, child.parent_id FROM folder_descendants parent JOIN public.dms_folders child ON child.tenant_id = #{q.tenantId} AND child.parent_id = parent.id AND child.f_delete_mark IS NULL), search_folder_ancestors(folder_id, ancestor_id, parent_id) AS ( SELECT folder.id, folder.id, folder.parent_id FROM folder_descendants folder UNION ALL SELECT chain.folder_id, parent.id, parent.parent_id FROM search_folder_ancestors chain JOIN public.dms_folders parent ON parent.tenant_id = #{q.tenantId} AND parent.id = chain.parent_id AND parent.f_delete_mark IS NULL) AND (STRPOS(LOWER(COALESCE(v.file_name, '')), LOWER(#{q.keyword})) > 0 OR STRPOS(LOWER(COALESCE(d.name, '')), LOWER(#{q.keyword})) > 0 OR STRPOS(LOWER(COALESCE(d.document_no, '')), LOWER(#{q.keyword})) > 0) AND (s.lifecycle_status IN ('SUPERSEDED', 'EXPIRED', 'REVOKED', 'OBSOLETE') OR (s.lifecycle_status = 'EFFECTIVE' AND s.effective_to <= CURRENT_TIMESTAMP) OR (s.lifecycle_status = 'INVALIDATED' AND s.approved_at IS NOT NULL)) OR (p.resource_type = 'FOLDER' AND (p.resource_id = d.folder_id OR (p.resource_scope = 'SUBTREE' AND p.resource_id IN (SELECT ancestor_id FROM search_folder_ancestors WHERE folder_id = d.folder_id))))) v.id, 'FILE_VERSION' AS resource_type, d.folder_id AS parent_id, d.name, d.id AS document_id, d.document_no, d.document_type, d.responsible_dept_id, v.version_no, v.version_label, v.file_name, v.mime_type, v.size_bytes, v.checksum_sha256, v.prepared_by, v.prepared_on, v.extended_properties, CASE WHEN s.lifecycle_status='EFFECTIVE' AND s.effective_to <= CURRENT_TIMESTAMP THEN 'EXPIRED' ELSE s.lifecycle_status END AS lifecycle_status, CASE WHEN s.lifecycle_status='INVALIDATED' THEN s.effective_to END AS invalidated_at, CASE WHEN s.lifecycle_status='REVOKED' THEN s.status_changed_at END AS revoked_at, s.status_reason, s.effective_from, s.effective_to, s.review_cycle_months, s.last_reviewed_on, s.next_review_on, v.created_at COALESCE((SELECT initial_version.file_name FROM public.dms_file_versions initial_version WHERE initial_version.tenant_id = d.tenant_id AND initial_version.document_id = d.id ORDER BY initial_version.version_no, initial_version.id LIMIT 1), d.name)d.id, 'DOCUMENT' AS resource_type, d.folder_id AS parent_id, AS name, d.id AS document_id, d.document_no, d.document_type, d.responsible_dept_id, NULL::BIGINT AS version_no, NULL::TEXT AS version_label, NULL::TEXT AS file_name, NULL::TEXT AS mime_type, NULL::BIGINT AS size_bytes, NULL::TEXT AS checksum_sha256, NULL::TEXT AS prepared_by, NULL::DATE AS prepared_on, NULL::jsonb AS extended_properties, CASE WHEN d.access_status='disable' AND d.disable_reason='yishixiao' THEN 'INVALIDATED' WHEN d.access_status='disable' AND d.disable_reason='yichexiao' THEN 'REVOKED' END AS lifecycle_status, CASE WHEN d.disable_reason='yishixiao' THEN d.disabled_at END AS invalidated_at, CASE WHEN d.disable_reason='yichexiao' THEN d.disabled_at END AS revoked_at, NULL::TEXT AS status_reason, NULL::TIMESTAMP AS effective_from, NULL::TIMESTAMP AS effective_to, NULL::INTEGER AS review_cycle_months, NULL::DATE AS last_reviewed_on, NULL::DATE AS next_review_on, d.created_at WITH RECURSIVE folder_ancestors(id, parent_id) AS ( SELECT f.id, f.parent_id FROM public.dms_folders f JOIN public.dms_documents start_document ON start_document.tenant_id = f.tenant_id AND start_document.folder_id = f.id WHERE f.tenant_id = #{q.tenantId} AND start_document.id = #{q.documentId} AND f.f_delete_mark IS NULL UNION ALL SELECT parent.id, parent.parent_id FROM folder_ancestors child JOIN public.dms_folders parent ON parent.tenant_id = #{q.tenantId} AND parent.id = child.parent_id AND parent.f_delete_mark IS NULL) e.tenant_id = #{q.tenantId} AND e.user_id = #{q.userId} AND e.action_code = 'READ' AND e.revoked_at IS NULL AND e.valid_from <= CURRENT_TIMESTAMP AND (e.valid_to IS NULL OR CURRENT_TIMESTAMP < e.valid_to) WITH eligible_versions(file_version_id) AS ( SELECT s.file_version_id FROM public.dms_version_states s WHERE s.tenant_id = #{q.tenantId} SELECT s.file_version_id FROM public.dms_file_permissions p JOIN public.dms_version_states s ON s.tenant_id = p.tenant_id AND s.document_id = p.resource_id WHERE AND p.resource_type = 'DOCUMENT' UNION SELECT p.resource_id FROM public.dms_file_permissions p WHERE AND p.resource_type = 'FILE_VERSION' )