feat: 小程序前端显示分类标签
各页面增加垃圾信息分类标签显示: - 检测结果页显示分类标签 - 批量识别页和CSV导出增加分类标签列 - 历史记录页显示分类标签 - 管理后台审核页显示分类标签 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,13 @@ const APPEAL_STATUS_TEXT = {
|
|||||||
rejected: '已驳回'
|
rejected: '已驳回'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CATEGORY_LABELS = {
|
||||||
|
fraud: '疑似诈骗',
|
||||||
|
harassment: '疑似骚扰',
|
||||||
|
advertisement: '疑似广告',
|
||||||
|
spam: '疑似垃圾'
|
||||||
|
}
|
||||||
|
|
||||||
function buildPager(total, page, pageSize) {
|
function buildPager(total, page, pageSize) {
|
||||||
const totalValue = Number(total || 0)
|
const totalValue = Number(total || 0)
|
||||||
const totalPages = Math.max(Math.ceil(totalValue / pageSize), 1)
|
const totalPages = Math.max(Math.ceil(totalValue / pageSize), 1)
|
||||||
@@ -105,7 +112,8 @@ Page({
|
|||||||
created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
|
created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
|
||||||
review_status_text: REVIEW_STATUS_TEXT[item.manual_review_status] || item.manual_review_status,
|
review_status_text: REVIEW_STATUS_TEXT[item.manual_review_status] || item.manual_review_status,
|
||||||
spam_probability_text: this.formatPercent(item.spam_probability, 2),
|
spam_probability_text: this.formatPercent(item.spam_probability, 2),
|
||||||
appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status
|
appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status,
|
||||||
|
category_label: CATEGORY_LABELS[item.category] || ''
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -116,6 +124,7 @@ Page({
|
|||||||
...item,
|
...item,
|
||||||
created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
|
created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
|
||||||
appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status,
|
appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status,
|
||||||
|
category_label: CATEGORY_LABELS[item.category] || '',
|
||||||
appeal_evidence_urls: (item.appeal_evidence_urls || []).map((url) =>
|
appeal_evidence_urls: (item.appeal_evidence_urls || []).map((url) =>
|
||||||
url.startsWith('http') ? url : `${serverBase}${url}`
|
url.startsWith('http') ? url : `${serverBase}${url}`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
<view class="list-item" wx:for="{{intercepts}}" wx:key="id">
|
<view class="list-item" wx:for="{{intercepts}}" wx:key="id">
|
||||||
<view class="item-title">{{item.text}}</view>
|
<view class="item-title">{{item.text}}</view>
|
||||||
<view class="item-sub">用户:{{item.nickname || item.username}} · 垃圾概率:{{item.spam_probability_text}}</view>
|
<view class="item-sub">用户:{{item.nickname || item.username}} · 垃圾概率:{{item.spam_probability_text}}</view>
|
||||||
|
<view class="item-sub" wx:if="{{item.category_label}}">分类标签:<text class="status-spam">{{item.category_label}}</text></view>
|
||||||
<view class="item-sub">复核状态:{{item.review_status_text}} · 申诉状态:{{item.appeal_status_text}}</view>
|
<view class="item-sub">复核状态:{{item.review_status_text}} · 申诉状态:{{item.appeal_status_text}}</view>
|
||||||
<view class="item-sub">发布时间:{{item.created_text}}</view>
|
<view class="item-sub">发布时间:{{item.created_text}}</view>
|
||||||
|
|
||||||
@@ -100,6 +101,7 @@
|
|||||||
<view class="list-item" wx:for="{{appeals}}" wx:key="id">
|
<view class="list-item" wx:for="{{appeals}}" wx:key="id">
|
||||||
<view class="item-title">{{item.text}}</view>
|
<view class="item-title">{{item.text}}</view>
|
||||||
<view class="item-sub">申诉人:{{item.nickname || item.username}} · 当前状态:{{item.appeal_status_text}}</view>
|
<view class="item-sub">申诉人:{{item.nickname || item.username}} · 当前状态:{{item.appeal_status_text}}</view>
|
||||||
|
<view class="item-sub" wx:if="{{item.category_label}}">分类标签:<text class="status-spam">{{item.category_label}}</text></view>
|
||||||
<view class="item-sub">申诉理由类型:{{item.appeal_reason_type || '未选择'}}</view>
|
<view class="item-sub">申诉理由类型:{{item.appeal_reason_type || '未选择'}}</view>
|
||||||
<view class="item-sub">申诉理由:{{item.appeal_reason || '未填写'}}</view>
|
<view class="item-sub">申诉理由:{{item.appeal_reason || '未填写'}}</view>
|
||||||
<view class="item-sub">时间:{{item.created_text}}</view>
|
<view class="item-sub">时间:{{item.created_text}}</view>
|
||||||
|
|||||||
@@ -85,9 +85,10 @@ Page({
|
|||||||
const items = this.data.items
|
const items = this.data.items
|
||||||
if (!items.length) return ''
|
if (!items.length) return ''
|
||||||
|
|
||||||
const headers = ['文本', '判定结果', '置信度', '垃圾概率', '正常概率', '风险关键词']
|
const headers = ['文本', '判定结果', '分类标签', '置信度', '垃圾概率', '正常概率', '风险关键词']
|
||||||
const rows = items.map((item) => {
|
const rows = items.map((item) => {
|
||||||
const prediction = item.prediction === 'spam' ? '垃圾信息' : '正常信息'
|
const prediction = item.prediction === 'spam' ? '垃圾信息' : '正常信息'
|
||||||
|
const categoryLabel = item.category_label || ''
|
||||||
const confidence = item.confidence_text || '0%'
|
const confidence = item.confidence_text || '0%'
|
||||||
const spamProb = this.formatPercent(item.spam_probability, 4)
|
const spamProb = this.formatPercent(item.spam_probability, 4)
|
||||||
const hamProb = this.formatPercent(item.ham_probability, 4)
|
const hamProb = this.formatPercent(item.ham_probability, 4)
|
||||||
@@ -95,7 +96,7 @@ Page({
|
|||||||
// CSV 转义:文本中的逗号和换行需要处理
|
// CSV 转义:文本中的逗号和换行需要处理
|
||||||
const text = (item.text || '').replace(/"/g, '""')
|
const text = (item.text || '').replace(/"/g, '""')
|
||||||
const tokensEscaped = tokens.replace(/"/g, '""')
|
const tokensEscaped = tokens.replace(/"/g, '""')
|
||||||
return `"${text}","${prediction}","${confidence}","${spamProb}","${hamProb}","${tokensEscaped}"`
|
return `"${text}","${prediction}","${categoryLabel}","${confidence}","${spamProb}","${hamProb}","${tokensEscaped}"`
|
||||||
})
|
})
|
||||||
|
|
||||||
return [headers.join(','), ...rows].join('\n')
|
return [headers.join(','), ...rows].join('\n')
|
||||||
|
|||||||
@@ -66,6 +66,10 @@
|
|||||||
<text class="label">判定结果</text>
|
<text class="label">判定结果</text>
|
||||||
<text class="{{item.prediction === 'spam' ? 'status-spam' : 'status-ham'}}">{{item.prediction_text}}</text>
|
<text class="{{item.prediction === 'spam' ? 'status-spam' : 'status-ham'}}">{{item.prediction_text}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="row" wx:if="{{item.category_label}}">
|
||||||
|
<text class="label">分类标签</text>
|
||||||
|
<text class="status-spam">{{item.category_label}}</text>
|
||||||
|
</view>
|
||||||
<view class="row">
|
<view class="row">
|
||||||
<text class="label">置信度</text>
|
<text class="label">置信度</text>
|
||||||
<text class="value">{{item.confidence_text}}</text>
|
<text class="value">{{item.confidence_text}}</text>
|
||||||
|
|||||||
@@ -46,6 +46,11 @@
|
|||||||
<text class="{{result.publish_allowed ? 'status-ham' : 'status-spam'}}">{{result.publish_allowed ? '发布成功' : '已拦截,需申诉'}}</text>
|
<text class="{{result.publish_allowed ? 'status-ham' : 'status-spam'}}">{{result.publish_allowed ? '发布成功' : '已拦截,需申诉'}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view class="row" wx:if="{{result.detect.category_label}}">
|
||||||
|
<text class="label">分类标签</text>
|
||||||
|
<text class="status-spam">{{result.detect.category_label}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="row">
|
<view class="row">
|
||||||
<text class="label">模型判断</text>
|
<text class="label">模型判断</text>
|
||||||
<text class="value">{{result.detect.prediction_text}}</text>
|
<text class="value">{{result.detect.prediction_text}}</text>
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ const APPEAL_STATUS_TEXT = {
|
|||||||
rejected: '已驳回'
|
rejected: '已驳回'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CATEGORY_LABELS = {
|
||||||
|
fraud: '疑似诈骗',
|
||||||
|
harassment: '疑似骚扰',
|
||||||
|
advertisement: '疑似广告',
|
||||||
|
spam: '疑似垃圾'
|
||||||
|
}
|
||||||
|
|
||||||
const REASON_TYPE_OPTIONS = [
|
const REASON_TYPE_OPTIONS = [
|
||||||
{ value: '', label: '请选择申诉理由类型' },
|
{ value: '', label: '请选择申诉理由类型' },
|
||||||
{ value: '正常活动文案', label: '正常活动文案' },
|
{ value: '正常活动文案', label: '正常活动文案' },
|
||||||
@@ -86,7 +93,8 @@ Page({
|
|||||||
created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
|
created_text: (item.created_at || '').replace('T', ' ').slice(0, 19),
|
||||||
spam_probability_text: this.formatPercent(item.spam_probability, 2),
|
spam_probability_text: this.formatPercent(item.spam_probability, 2),
|
||||||
visibility_text: VIS_LABEL[item.visibility] || item.visibility,
|
visibility_text: VIS_LABEL[item.visibility] || item.visibility,
|
||||||
appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status
|
appeal_status_text: APPEAL_STATUS_TEXT[item.appeal_status] || item.appeal_status,
|
||||||
|
category_label: CATEGORY_LABELS[item.category] || ''
|
||||||
}))
|
}))
|
||||||
this.setData({ list })
|
this.setData({ list })
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -35,6 +35,11 @@
|
|||||||
<text class="{{item.status === 'blocked' ? 'status-spam' : 'status-ham'}}">{{item.status === 'blocked' ? '已拦截' : '已发布'}}</text>
|
<text class="{{item.status === 'blocked' ? 'status-spam' : 'status-ham'}}">{{item.status === 'blocked' ? '已拦截' : '已发布'}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view class="row" wx:if="{{item.category_label}}">
|
||||||
|
<text class="label">分类标签</text>
|
||||||
|
<text class="status-spam">{{item.category_label}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="row">
|
<view class="row">
|
||||||
<text class="label">垃圾概率</text>
|
<text class="label">垃圾概率</text>
|
||||||
<text class="value">{{item.spam_probability_text}}</text>
|
<text class="value">{{item.spam_probability_text}}</text>
|
||||||
|
|||||||
Reference in New Issue
Block a user