use crate::error::AppError; use crate::models::wiki::WikiPageRevision; use crate::service::RepoService; use crate::session::Session; use super::util::clamp_limit_offset; impl RepoService { /// 获取页面的修订历史 pub async fn wiki_get_revisions( &self, ctx: &Session, wk_name: &str, repo_name: &str, slug: &str, limit: i64, offset: i64, ) -> Result, AppError> { let user_uid = ctx.user().ok_or(AppError::Unauthorized)?; let page = self.wiki_get_page(ctx, wk_name, repo_name, slug).await?; self.ensure_repo_readable(user_uid, &self.resolve_repo(wk_name, repo_name).await?) .await?; let (limit, offset) = clamp_limit_offset(limit, offset); sqlx::query_as::<_, WikiPageRevision>( "SELECT id, page_id, version, title, content, editor_id, commit_message, created_at \ FROM wiki_page_revision WHERE page_id = $1 ORDER BY version DESC LIMIT $2 OFFSET $3", ) .bind(page.id) .bind(limit) .bind(offset) .fetch_all(self.ctx.db.reader()) .await .map_err(AppError::Database) } /// 获取特定版本的修订详情 pub async fn wiki_get_revision( &self, ctx: &Session, wk_name: &str, repo_name: &str, slug: &str, version: i32, ) -> Result { let user_uid = ctx.user().ok_or(AppError::Unauthorized)?; let page = self.wiki_get_page(ctx, wk_name, repo_name, slug).await?; self.ensure_repo_readable(user_uid, &self.resolve_repo(wk_name, repo_name).await?) .await?; sqlx::query_as::<_, WikiPageRevision>( "SELECT id, page_id, version, title, content, editor_id, commit_message, created_at \ FROM wiki_page_revision WHERE page_id = $1 AND version = $2", ) .bind(page.id) .bind(version) .fetch_optional(self.ctx.db.reader()) .await .map_err(AppError::Database)? .ok_or_else(|| AppError::NotFound("Revision not found".into())) } /// 比较两个版本的差异 pub async fn wiki_compare_revisions( &self, ctx: &Session, wk_name: &str, repo_name: &str, slug: &str, old_version: i32, new_version: i32, ) -> Result<(WikiPageRevision, WikiPageRevision), AppError> { let old = self .wiki_get_revision(ctx, wk_name, repo_name, slug, old_version) .await?; let new = self .wiki_get_revision(ctx, wk_name, repo_name, slug, new_version) .await?; Ok((old, new)) } }