wechat_minapp/minapp_security/
mod.rs

1mod msg_sec_check;
2
3use serde::{Deserialize, Serialize};
4use serde_repr::Deserialize_repr;
5use strum::Display;
6
7pub use msg_sec_check::{Args, MsgSecCheckResult, Scene};
8
9#[derive(Debug, Deserialize_repr, Display, Serialize, PartialEq, Clone)]
10#[repr(i32)]
11pub enum Label {
12    #[strum(serialize = "正常")]
13    Normal = 100,
14
15    #[strum(serialize = "广告")]
16    Ad = 10001,
17
18    #[strum(serialize = "时政")]
19    Politics = 20001,
20
21    #[strum(serialize = "色情")]
22    Porn = 20002,
23
24    #[strum(serialize = "辱骂")]
25    Abuse = 20003,
26
27    #[strum(serialize = "违法犯罪")]
28    Illegal = 20006,
29
30    #[strum(serialize = "欺诈")]
31    Fraud = 20008,
32
33    #[strum(serialize = "低俗")]
34    Vulgar = 20012,
35
36    #[strum(serialize = "版权")]
37    Copyright = 20013,
38
39    #[strum(serialize = "其他")]
40    Other = 21000,
41}
42
43// 可选:为方便使用,可以添加一些辅助方法
44impl Label {
45    /// 根据数值获取对应的标签枚举
46    pub fn from_value(value: i32) -> Option<Self> {
47        match value {
48            100 => Some(Label::Normal),
49            10001 => Some(Label::Ad),
50            20001 => Some(Label::Politics),
51            20002 => Some(Label::Porn),
52            20003 => Some(Label::Abuse),
53            20006 => Some(Label::Illegal),
54            20008 => Some(Label::Fraud),
55            20012 => Some(Label::Vulgar),
56            20013 => Some(Label::Copyright),
57            21000 => Some(Label::Other),
58            _ => None,
59        }
60    }
61
62    /// 检查是否为正常内容
63    pub fn is_normal(&self) -> bool {
64        matches!(self, Label::Normal)
65    }
66
67    /// 检查是否为违规内容
68    pub fn is_violation(&self) -> bool {
69        !self.is_normal()
70    }
71}
72
73/// 内容安全检测建议
74#[derive(Debug, Deserialize, Serialize, Display, PartialEq, Clone)]
75pub enum Suggest {
76    #[strum(serialize = "risky")]
77    #[serde(rename = "risky")]
78    Risky,
79
80    #[strum(serialize = "pass")]
81    #[serde(rename = "pass")]
82    Pass,
83
84    #[strum(serialize = "review")]
85    #[serde(rename = "review")]
86    Review,
87}
88
89// 可选:为方便使用,可以添加一些辅助方法
90impl Suggest {
91    /// 检查是否通过
92    pub fn is_pass(&self) -> bool {
93        matches!(self, Suggest::Pass)
94    }
95
96    /// 检查是否有风险
97    pub fn is_risky(&self) -> bool {
98        matches!(self, Suggest::Risky)
99    }
100
101    /// 检查是否需要人工审核
102    pub fn needs_review(&self) -> bool {
103        matches!(self, Suggest::Review)
104    }
105
106    /// 获取建议的优先级(数值越小优先级越高)
107    pub fn priority(&self) -> u8 {
108        match self {
109            Suggest::Risky => 1,  // 最高优先级:有风险
110            Suggest::Review => 2, // 中等优先级:需要审核
111            Suggest::Pass => 3,   // 最低优先级:通过
112        }
113    }
114}
115
116impl From<&str> for Suggest {
117    fn from(s: &str) -> Self {
118        match s.to_lowercase().as_str() {
119            "risky" => Suggest::Risky,
120            "pass" => Suggest::Pass,
121            "review" => Suggest::Review,
122            _ => Suggest::Review,
123        }
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn test_suggest_enum() {
133        // 测试显示功能
134        assert_eq!(Suggest::Risky.to_string(), "risky");
135        assert_eq!(Suggest::Pass.to_string(), "pass");
136        assert_eq!(Suggest::Review.to_string(), "review");
137
138        // 测试从字符串创建
139        assert_eq!(Suggest::from("risky"), Suggest::Risky);
140        assert_eq!(Suggest::from("PASS"), Suggest::Pass);
141        assert_eq!(Suggest::from("ReViEw"), Suggest::Review);
142        assert_eq!(Suggest::from("invalid"), Suggest::Review);
143
144        // 测试辅助方法
145        assert!(Suggest::Pass.is_pass());
146        assert!(Suggest::Risky.is_risky());
147        assert!(Suggest::Review.needs_review());
148
149        // 测试优先级
150        assert_eq!(Suggest::Risky.priority(), 1);
151        assert_eq!(Suggest::Review.priority(), 2);
152        assert_eq!(Suggest::Pass.priority(), 3);
153    }
154
155    #[test]
156    fn test_serialization() {
157        // 测试序列化
158        let risky_json = serde_json::to_string(&Suggest::Risky).unwrap();
159        assert_eq!(risky_json, "\"risky\"");
160
161        let pass_json = serde_json::to_string(&Suggest::Pass).unwrap();
162        assert_eq!(pass_json, "\"pass\"");
163
164        // 测试反序列化
165        let review: Suggest = serde_json::from_str("\"review\"").unwrap();
166        assert_eq!(review, Suggest::Review);
167    }
168}