426 lines
12 KiB
Rust
426 lines
12 KiB
Rust
//! 宪法条款生命周期管理模块
|
||
//!
|
||
//! 提供条款的激活、停用、生效时间管理和优先级管理功能
|
||
|
||
use crate::ConstitutionalClause;
|
||
use serde::{Deserialize, Serialize};
|
||
use std::collections::HashMap;
|
||
|
||
/// 条款状态
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||
pub enum ClauseStatus {
|
||
/// 草稿状态
|
||
Draft,
|
||
/// 待激活
|
||
Pending,
|
||
/// 已激活
|
||
Active,
|
||
/// 已停用
|
||
Suspended,
|
||
/// 已废止
|
||
Revoked,
|
||
}
|
||
|
||
/// 条款生命周期信息
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct ClauseLifecycle {
|
||
/// 条款索引
|
||
pub clause_index: u64,
|
||
/// 当前状态
|
||
pub status: ClauseStatus,
|
||
/// 优先级(数字越小优先级越高)
|
||
pub priority: u32,
|
||
/// 生效时间
|
||
pub effective_from: u64,
|
||
/// 失效时间(0表示永久有效)
|
||
pub effective_until: u64,
|
||
/// 激活时间
|
||
pub activated_at: Option<u64>,
|
||
/// 停用时间
|
||
pub suspended_at: Option<u64>,
|
||
/// 废止时间
|
||
pub revoked_at: Option<u64>,
|
||
/// 激活者
|
||
pub activated_by: Option<String>,
|
||
/// 停用者
|
||
pub suspended_by: Option<String>,
|
||
/// 废止者
|
||
pub revoked_by: Option<String>,
|
||
/// 停用原因
|
||
pub suspension_reason: Option<String>,
|
||
/// 废止原因
|
||
pub revocation_reason: Option<String>,
|
||
}
|
||
|
||
impl ClauseLifecycle {
|
||
/// 创建新的生命周期信息
|
||
pub fn new(clause_index: u64, effective_from: u64) -> Self {
|
||
Self {
|
||
clause_index,
|
||
status: ClauseStatus::Draft,
|
||
priority: 100, // 默认优先级
|
||
effective_from,
|
||
effective_until: 0, // 永久有效
|
||
activated_at: None,
|
||
suspended_at: None,
|
||
revoked_at: None,
|
||
activated_by: None,
|
||
suspended_by: None,
|
||
revoked_by: None,
|
||
suspension_reason: None,
|
||
revocation_reason: None,
|
||
}
|
||
}
|
||
|
||
/// 是否在指定时间生效
|
||
pub fn is_effective_at(&self, timestamp: u64) -> bool {
|
||
if self.status != ClauseStatus::Active {
|
||
return false;
|
||
}
|
||
|
||
if timestamp < self.effective_from {
|
||
return false;
|
||
}
|
||
|
||
if self.effective_until > 0 && timestamp >= self.effective_until {
|
||
return false;
|
||
}
|
||
|
||
true
|
||
}
|
||
|
||
/// 是否已激活
|
||
pub fn is_active(&self) -> bool {
|
||
self.status == ClauseStatus::Active
|
||
}
|
||
|
||
/// 是否已停用
|
||
pub fn is_suspended(&self) -> bool {
|
||
self.status == ClauseStatus::Suspended
|
||
}
|
||
|
||
/// 是否已废止
|
||
pub fn is_revoked(&self) -> bool {
|
||
self.status == ClauseStatus::Revoked
|
||
}
|
||
}
|
||
|
||
/// 生命周期管理器
|
||
pub struct LifecycleManager {
|
||
/// 条款生命周期信息
|
||
lifecycles: HashMap<u64, ClauseLifecycle>,
|
||
}
|
||
|
||
impl LifecycleManager {
|
||
/// 创建新的生命周期管理器
|
||
pub fn new() -> Self {
|
||
Self {
|
||
lifecycles: HashMap::new(),
|
||
}
|
||
}
|
||
|
||
/// 注册条款生命周期
|
||
pub fn register(&mut self, clause: &ConstitutionalClause) {
|
||
let lifecycle = ClauseLifecycle::new(clause.clause_index, clause.effective_from);
|
||
self.lifecycles.insert(clause.clause_index, lifecycle);
|
||
}
|
||
|
||
/// 激活条款
|
||
pub fn activate(
|
||
&mut self,
|
||
clause_index: u64,
|
||
activated_by: String,
|
||
timestamp: u64,
|
||
) -> Result<(), String> {
|
||
let lifecycle = self.lifecycles
|
||
.get_mut(&clause_index)
|
||
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
|
||
|
||
if lifecycle.status == ClauseStatus::Revoked {
|
||
return Err("已废止的条款无法激活".to_string());
|
||
}
|
||
|
||
lifecycle.status = ClauseStatus::Active;
|
||
lifecycle.activated_at = Some(timestamp);
|
||
lifecycle.activated_by = Some(activated_by);
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 停用条款
|
||
pub fn suspend(
|
||
&mut self,
|
||
clause_index: u64,
|
||
suspended_by: String,
|
||
reason: String,
|
||
timestamp: u64,
|
||
) -> Result<(), String> {
|
||
let lifecycle = self.lifecycles
|
||
.get_mut(&clause_index)
|
||
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
|
||
|
||
if lifecycle.status == ClauseStatus::Revoked {
|
||
return Err("已废止的条款无法停用".to_string());
|
||
}
|
||
|
||
lifecycle.status = ClauseStatus::Suspended;
|
||
lifecycle.suspended_at = Some(timestamp);
|
||
lifecycle.suspended_by = Some(suspended_by);
|
||
lifecycle.suspension_reason = Some(reason);
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 废止条款
|
||
pub fn revoke(
|
||
&mut self,
|
||
clause_index: u64,
|
||
revoked_by: String,
|
||
reason: String,
|
||
timestamp: u64,
|
||
) -> Result<(), String> {
|
||
let lifecycle = self.lifecycles
|
||
.get_mut(&clause_index)
|
||
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
|
||
|
||
lifecycle.status = ClauseStatus::Revoked;
|
||
lifecycle.revoked_at = Some(timestamp);
|
||
lifecycle.revoked_by = Some(revoked_by);
|
||
lifecycle.revocation_reason = Some(reason);
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 设置优先级
|
||
pub fn set_priority(&mut self, clause_index: u64, priority: u32) -> Result<(), String> {
|
||
let lifecycle = self.lifecycles
|
||
.get_mut(&clause_index)
|
||
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
|
||
|
||
lifecycle.priority = priority;
|
||
Ok(())
|
||
}
|
||
|
||
/// 设置生效时间范围
|
||
pub fn set_effective_period(
|
||
&mut self,
|
||
clause_index: u64,
|
||
from: u64,
|
||
until: u64,
|
||
) -> Result<(), String> {
|
||
if until > 0 && from >= until {
|
||
return Err("生效时间必须早于失效时间".to_string());
|
||
}
|
||
|
||
let lifecycle = self.lifecycles
|
||
.get_mut(&clause_index)
|
||
.ok_or_else(|| format!("条款 {} 不存在", clause_index))?;
|
||
|
||
lifecycle.effective_from = from;
|
||
lifecycle.effective_until = until;
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 获取生命周期信息
|
||
pub fn get_lifecycle(&self, clause_index: u64) -> Option<&ClauseLifecycle> {
|
||
self.lifecycles.get(&clause_index)
|
||
}
|
||
|
||
/// 获取所有激活的条款
|
||
pub fn list_active_clauses(&self) -> Vec<u64> {
|
||
self.lifecycles
|
||
.values()
|
||
.filter(|lc| lc.is_active())
|
||
.map(|lc| lc.clause_index)
|
||
.collect()
|
||
}
|
||
|
||
/// 获取在指定时间生效的条款
|
||
pub fn list_effective_clauses_at(&self, timestamp: u64) -> Vec<u64> {
|
||
self.lifecycles
|
||
.values()
|
||
.filter(|lc| lc.is_effective_at(timestamp))
|
||
.map(|lc| lc.clause_index)
|
||
.collect()
|
||
}
|
||
|
||
/// 按优先级排序的条款列表
|
||
pub fn list_clauses_by_priority(&self) -> Vec<(u64, u32)> {
|
||
let mut clauses: Vec<_> = self.lifecycles
|
||
.values()
|
||
.filter(|lc| lc.is_active())
|
||
.map(|lc| (lc.clause_index, lc.priority))
|
||
.collect();
|
||
|
||
clauses.sort_by_key(|(_, priority)| *priority);
|
||
clauses
|
||
}
|
||
|
||
/// 获取条款状态统计
|
||
pub fn get_status_statistics(&self) -> StatusStatistics {
|
||
let mut stats = StatusStatistics::default();
|
||
|
||
for lifecycle in self.lifecycles.values() {
|
||
match lifecycle.status {
|
||
ClauseStatus::Draft => stats.draft += 1,
|
||
ClauseStatus::Pending => stats.pending += 1,
|
||
ClauseStatus::Active => stats.active += 1,
|
||
ClauseStatus::Suspended => stats.suspended += 1,
|
||
ClauseStatus::Revoked => stats.revoked += 1,
|
||
}
|
||
}
|
||
|
||
stats
|
||
}
|
||
}
|
||
|
||
impl Default for LifecycleManager {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
/// 状态统计信息
|
||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||
pub struct StatusStatistics {
|
||
/// 草稿数量
|
||
pub draft: usize,
|
||
/// 待激活数量
|
||
pub pending: usize,
|
||
/// 已激活数量
|
||
pub active: usize,
|
||
/// 已停用数量
|
||
pub suspended: usize,
|
||
/// 已废止数量
|
||
pub revoked: usize,
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
use nac_udm::primitives::Hash;
|
||
use crate::ClauseTier;
|
||
|
||
fn create_test_clause(index: u64) -> ConstitutionalClause {
|
||
ConstitutionalClause {
|
||
clause_index: index,
|
||
title: "测试条款".to_string(),
|
||
content: "测试内容".to_string(),
|
||
clause_hash: Hash::zero(),
|
||
effective_from: 1000,
|
||
tier: ClauseTier::Eternal,
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn test_register_and_activate() {
|
||
let mut manager = LifecycleManager::new();
|
||
let clause = create_test_clause(1);
|
||
|
||
manager.register(&clause);
|
||
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
|
||
|
||
let lifecycle = manager.get_lifecycle(1).unwrap();
|
||
assert!(lifecycle.is_active());
|
||
assert_eq!(lifecycle.activated_by, Some("测试用户".to_string()));
|
||
}
|
||
|
||
#[test]
|
||
fn test_suspend() {
|
||
let mut manager = LifecycleManager::new();
|
||
let clause = create_test_clause(1);
|
||
|
||
manager.register(&clause);
|
||
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
|
||
manager.suspend(1, "测试用户".to_string(), "测试停用".to_string(), 3000).unwrap();
|
||
|
||
let lifecycle = manager.get_lifecycle(1).unwrap();
|
||
assert!(lifecycle.is_suspended());
|
||
assert_eq!(lifecycle.suspension_reason, Some("测试停用".to_string()));
|
||
}
|
||
|
||
#[test]
|
||
fn test_revoke() {
|
||
let mut manager = LifecycleManager::new();
|
||
let clause = create_test_clause(1);
|
||
|
||
manager.register(&clause);
|
||
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
|
||
manager.revoke(1, "测试用户".to_string(), "测试废止".to_string(), 4000).unwrap();
|
||
|
||
let lifecycle = manager.get_lifecycle(1).unwrap();
|
||
assert!(lifecycle.is_revoked());
|
||
assert_eq!(lifecycle.revocation_reason, Some("测试废止".to_string()));
|
||
}
|
||
|
||
#[test]
|
||
fn test_is_effective_at() {
|
||
let mut manager = LifecycleManager::new();
|
||
let clause = create_test_clause(1);
|
||
|
||
manager.register(&clause);
|
||
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
|
||
manager.set_effective_period(1, 1000, 5000).unwrap();
|
||
|
||
let lifecycle = manager.get_lifecycle(1).unwrap();
|
||
assert!(!lifecycle.is_effective_at(500)); // 未生效
|
||
assert!(lifecycle.is_effective_at(3000)); // 生效中
|
||
assert!(!lifecycle.is_effective_at(6000)); // 已失效
|
||
}
|
||
|
||
#[test]
|
||
fn test_priority() {
|
||
let mut manager = LifecycleManager::new();
|
||
let clause1 = create_test_clause(1);
|
||
let clause2 = create_test_clause(2);
|
||
|
||
manager.register(&clause1);
|
||
manager.register(&clause2);
|
||
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
|
||
manager.activate(2, "测试用户".to_string(), 2000).unwrap();
|
||
|
||
manager.set_priority(1, 10).unwrap();
|
||
manager.set_priority(2, 5).unwrap();
|
||
|
||
let clauses = manager.list_clauses_by_priority();
|
||
assert_eq!(clauses[0].0, 2); // 优先级5
|
||
assert_eq!(clauses[1].0, 1); // 优先级10
|
||
}
|
||
|
||
#[test]
|
||
fn test_status_statistics() {
|
||
let mut manager = LifecycleManager::new();
|
||
|
||
manager.register(&create_test_clause(1));
|
||
manager.register(&create_test_clause(2));
|
||
manager.register(&create_test_clause(3));
|
||
|
||
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
|
||
manager.activate(2, "测试用户".to_string(), 2000).unwrap();
|
||
manager.suspend(2, "测试用户".to_string(), "测试".to_string(), 3000).unwrap();
|
||
|
||
let stats = manager.get_status_statistics();
|
||
assert_eq!(stats.draft, 1);
|
||
assert_eq!(stats.active, 1);
|
||
assert_eq!(stats.suspended, 1);
|
||
}
|
||
|
||
#[test]
|
||
fn test_list_active_clauses() {
|
||
let mut manager = LifecycleManager::new();
|
||
|
||
manager.register(&create_test_clause(1));
|
||
manager.register(&create_test_clause(2));
|
||
manager.register(&create_test_clause(3));
|
||
|
||
manager.activate(1, "测试用户".to_string(), 2000).unwrap();
|
||
manager.activate(2, "测试用户".to_string(), 2000).unwrap();
|
||
|
||
let active = manager.list_active_clauses();
|
||
assert_eq!(active.len(), 2);
|
||
assert!(active.contains(&1));
|
||
assert!(active.contains(&2));
|
||
}
|
||
}
|