| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /**
- * 内容安全检测工具类
- * 用于检测用户发布的文字、图片是否包含色情、低俗、违规等内容
- * 使用微信小程序内容安全API
- */
- const BASE_URL = 'https://api.zhongruanke.cn/api'
- // 敏感词列表(本地基础过滤)
- const SENSITIVE_WORDS = [
- // 色情相关
- '色情', '裸体', '性爱', '约炮', '一夜情', '援交', '卖淫', '嫖娼',
- // 低俗相关
- '傻逼', '操你', '草泥马', '妈的', '他妈的', '狗日的', '王八蛋',
- // 违规相关
- '赌博', '毒品', '枪支', '炸弹', '恐怖', '暴力',
- // 诈骗相关
- '刷单', '兼职日结', '高额返利', '免费领取'
- ]
- export default {
- /**
- * 检测文字内容是否安全
- * @param {string} content - 要检测的文字内容
- * @returns {Promise<{safe: boolean, message: string}>}
- */
- async checkText(content) {
- if (!content || !content.trim()) {
- return { safe: true, message: '' }
- }
-
- // 1. 本地敏感词过滤(快速检测)
- const localResult = this.localTextCheck(content)
- if (!localResult.safe) {
- return localResult
- }
-
- // 2. 调用后端接口进行内容安全检测
- try {
- const [error, res] = await uni.request({
- url: `${BASE_URL}/content-security/check-text`,
- method: 'POST',
- data: { content: content },
- timeout: 10000
- })
-
- if (error) {
- console.error('文字安全检测请求失败:', error)
- // 网络错误时,仅依赖本地检测结果
- return localResult
- }
-
- if (res.statusCode === 200 && res.data) {
- if (res.data.code === 200) {
- const data = res.data.data
- if (data && data.safe === false) {
- return {
- safe: false,
- message: data.message || '内容包含违规信息,请修改后重试'
- }
- }
- } else if (res.data.code === 87014) {
- // 微信内容安全API返回的违规码
- return {
- safe: false,
- message: '内容包含违规信息,请修改后重试'
- }
- }
- }
-
- return { safe: true, message: '' }
- } catch (e) {
- console.error('文字安全检测异常:', e)
- return localResult
- }
- },
-
- /**
- * 本地敏感词检测
- * @param {string} content - 要检测的文字内容
- * @returns {{safe: boolean, message: string}}
- */
- localTextCheck(content) {
- if (!content) return { safe: true, message: '' }
-
- const lowerContent = content.toLowerCase()
- for (const word of SENSITIVE_WORDS) {
- if (lowerContent.includes(word.toLowerCase())) {
- return {
- safe: false,
- message: '内容包含敏感词,请修改后重试'
- }
- }
- }
- return { safe: true, message: '' }
- },
-
- /**
- * 检测图片是否安全
- * @param {string} imageUrl - 图片URL(需要是可访问的网络地址)
- * @returns {Promise<{safe: boolean, message: string}>}
- */
- async checkImage(imageUrl) {
- if (!imageUrl) {
- return { safe: true, message: '' }
- }
-
- // 如果是本地临时文件,跳过检测(上传后再检测)
- if (imageUrl.startsWith('wxfile://') || imageUrl.startsWith('http://tmp/')) {
- return { safe: true, message: '' }
- }
-
- try {
- const [error, res] = await uni.request({
- url: `${BASE_URL}/content-security/check-image`,
- method: 'POST',
- data: { imageUrl: imageUrl },
- timeout: 15000
- })
-
- if (error) {
- console.error('图片安全检测请求失败:', error)
- return { safe: true, message: '' } // 网络错误时默认通过
- }
-
- if (res.statusCode === 200 && res.data) {
- if (res.data.code === 200) {
- const data = res.data.data
- if (data && data.safe === false) {
- return {
- safe: false,
- message: data.message || '图片包含违规内容,请更换后重试'
- }
- }
- } else if (res.data.code === 87014) {
- return {
- safe: false,
- message: '图片包含违规内容,请更换后重试'
- }
- }
- }
-
- return { safe: true, message: '' }
- } catch (e) {
- console.error('图片安全检测异常:', e)
- return { safe: true, message: '' }
- }
- },
-
- /**
- * 批量检测图片是否安全
- * @param {string[]} imageUrls - 图片URL数组
- * @returns {Promise<{safe: boolean, message: string, failedIndex: number}>}
- */
- async checkImages(imageUrls) {
- if (!imageUrls || imageUrls.length === 0) {
- return { safe: true, message: '', failedIndex: -1 }
- }
-
- // 过滤掉本地临时文件
- const networkUrls = imageUrls.filter(url =>
- url && !url.startsWith('wxfile://') && !url.startsWith('http://tmp/')
- )
-
- if (networkUrls.length === 0) {
- return { safe: true, message: '', failedIndex: -1 }
- }
-
- // 逐个检测图片
- for (let i = 0; i < networkUrls.length; i++) {
- const result = await this.checkImage(networkUrls[i])
- if (!result.safe) {
- return {
- safe: false,
- message: `第${i + 1}张图片包含违规内容,请更换后重试`,
- failedIndex: i
- }
- }
- }
-
- return { safe: true, message: '', failedIndex: -1 }
- },
-
- /**
- * 综合检测文字和图片
- * @param {string} content - 文字内容
- * @param {string[]} imageUrls - 图片URL数组
- * @returns {Promise<{safe: boolean, message: string}>}
- */
- async checkContent(content, imageUrls) {
- // 1. 检测文字
- const textResult = await this.checkText(content)
- if (!textResult.safe) {
- return textResult
- }
-
- // 2. 检测图片
- if (imageUrls && imageUrls.length > 0) {
- const imageResult = await this.checkImages(imageUrls)
- if (!imageResult.safe) {
- return imageResult
- }
- }
-
- return { safe: true, message: '' }
- }
- }
|