feat(send-record): support tag and rule targets in test send

- Add tag/rule options to the target type selector.
- Show tag selector + scope selector (all/conversation/person) for tag targets.
- Show rule JSON textarea for rule targets.
- Load tag list on mount.
- Update buildTargetValue to build tag_id/scope and parsed rule payloads.
This commit is contained in:
2026-07-08 17:48:53 +08:00
parent ec0733cb28
commit 2cdbc662f3

View File

@@ -46,6 +46,8 @@
<el-select v-model="testForm.targetType" style="width: 140px">
<el-option label="会话" value="conversation" />
<el-option label="人员" value="person" />
<el-option label="标签" value="tag" />
<el-option label="规则" value="rule" />
</el-select>
</el-form-item>
<el-form-item label="目标" v-if="testForm.targetType === 'conversation'" style="width: 280px">
@@ -61,6 +63,31 @@
<el-form-item label="目标" v-if="testForm.targetType === 'person'" style="width: 280px">
<el-input v-model="personIdInput" placeholder="输入 person_id" />
</el-form-item>
<el-form-item label="目标" v-if="testForm.targetType === 'tag'" style="width: 220px">
<el-select v-model="selectedTagId" placeholder="选择标签" clearable>
<el-option
v-for="t in tags"
:key="t.id"
:label="t.tagName"
:value="t.id"
/>
</el-select>
</el-form-item>
<el-form-item label="范围" v-if="testForm.targetType === 'tag'" style="width: 200px">
<el-select v-model="tagScope" style="width: 120px">
<el-option label="全部" value="all" />
<el-option label="会话" value="conversation" />
<el-option label="人员" value="person" />
</el-select>
</el-form-item>
<el-form-item label="目标" v-if="testForm.targetType === 'rule'" style="width: 420px">
<el-input
v-model="ruleJson"
type="textarea"
:rows="2"
placeholder="输入规则 JSON"
/>
</el-form-item>
<el-form-item label="渠道">
<el-select v-model="testForm.channelStrategy.channel_type" style="width: 140px">
<el-option label="企微" value="wecom" />
@@ -214,6 +241,7 @@ import {
type QueryRecordsParams,
} from '@/api/sendRecord'
import { listConversations } from '@/api/channel'
import { listTags } from '@/api/crm'
interface RecordItem {
id: number
@@ -262,8 +290,12 @@ const testForm = reactive({
})
const selectedConversationId = ref<number | null>(null)
const personIdInput = ref('')
const selectedTagId = ref<number | null>(null)
const tagScope = ref<'all' | 'conversation' | 'person'>('all')
const ruleJson = ref('')
const textContent = ref('')
const conversations = ref<any[]>([])
const tags = ref<any[]>([])
function buildTargetValue() {
if (testForm.targetType === 'conversation' && selectedConversationId.value) {
@@ -272,6 +304,19 @@ function buildTargetValue() {
if (testForm.targetType === 'person' && personIdInput.value) {
return { person_id: Number(personIdInput.value) }
}
if (testForm.targetType === 'tag' && selectedTagId.value != null) {
return { tag_id: selectedTagId.value, scope: tagScope.value }
}
if (testForm.targetType === 'rule') {
const raw = ruleJson.value.trim()
if (!raw) return {}
try {
return JSON.parse(raw)
} catch {
ElMessage.warning('规则 JSON 格式错误')
return {}
}
}
return {}
}
@@ -396,8 +441,18 @@ async function loadConversations() {
}
}
async function loadTags() {
try {
const res: any = await listTags()
tags.value = res.data || []
} catch (e: any) {
ElMessage.error(e.message)
}
}
onMounted(() => {
loadConversations()
loadTags()
loadRecords()
loadStatistics()
})