feat(web): load real data in dashboard and list pages

This commit is contained in:
2026-07-07 15:34:35 +08:00
parent d0e9f5fb42
commit 9a1565dd8d
6 changed files with 207 additions and 17 deletions

View File

@@ -11,12 +11,25 @@
<el-form-item label="渠道">
<el-input v-model="form.channelType" placeholder="wecom" />
</el-form-item>
<el-form-item label="所属主体">
<el-select v-model="form.subjectId" placeholder="选择主体">
<el-option
v-for="s in subjects"
:key="s.id"
:label="s.subjectName"
:value="s.id"
/>
</el-select>
</el-form-item>
<el-form-item label="账号ID">
<el-input v-model="form.accountId" placeholder="账号唯一标识" />
</el-form-item>
<el-form-item label="名称">
<el-input v-model="form.accountName" placeholder="名称" />
</el-form-item>
<el-form-item label="会话存档">
<el-switch v-model="form.sessionArchiveEnabled" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleCreate">创建</el-button>
</el-form-item>
@@ -35,18 +48,39 @@
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onMounted, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { createChannelAccount } from '@/api/channel'
import { createChannelAccount, listChannelAccounts, listChannelSubjects } from '@/api/channel'
const form = reactive({
accountType: 1,
channelType: 'wecom',
subjectId: undefined as number | undefined,
accountId: '',
accountName: '',
sessionArchiveEnabled: false,
})
const accounts = ref<any[]>([])
const subjects = ref<any[]>([])
async function loadAccounts() {
try {
const res: any = await listChannelAccounts()
accounts.value = res.data || []
} catch (e: any) {
ElMessage.error(e.message)
}
}
async function loadSubjects() {
try {
const res: any = await listChannelSubjects()
subjects.value = res.data || []
} catch (e: any) {
ElMessage.error(e.message)
}
}
async function handleCreate() {
try {
@@ -57,4 +91,9 @@ async function handleCreate() {
ElMessage.error(e.message)
}
}
onMounted(() => {
loadAccounts()
loadSubjects()
})
</script>

View File

@@ -14,6 +14,15 @@
<el-form-item label="主体名称">
<el-input v-model="form.subjectName" placeholder="主体名称" />
</el-form-item>
<el-form-item label="CorpID">
<el-input v-model="form.corpId" placeholder="CorpID" />
</el-form-item>
<el-form-item label="AgentID">
<el-input v-model="form.agentId" placeholder="AgentID" />
</el-form-item>
<el-form-item label="AgentSecret">
<el-input v-model="form.agentSecret" placeholder="AgentSecret" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleCreate">创建</el-button>
</el-form-item>
@@ -31,19 +40,30 @@
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onMounted, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { createChannelSubject } from '@/api/channel'
import { createChannelSubject, listChannelSubjects } from '@/api/channel'
const form = reactive({
channelType: 'wecom',
subjectCode: '',
subjectName: '',
corpId: '',
agentId: '',
agentSecret: '',
})
const subjects = ref<any[]>([])
async function loadSubjects() {
try {
const res: any = await listChannelSubjects()
subjects.value = res.data || []
} catch (e: any) {
ElMessage.error(e.message)
}
}
async function handleCreate() {
try {
const res: any = await createChannelSubject(form)
@@ -53,4 +73,6 @@ async function handleCreate() {
ElMessage.error(e.message)
}
}
onMounted(loadSubjects)
</script>

View File

@@ -16,6 +16,16 @@
<el-form-item label="名称">
<el-input v-model="form.conversationName" placeholder="群名称" />
</el-form-item>
<el-form-item label="负责人">
<el-select v-model="form.ownerAccountId" placeholder="选择负责人账号">
<el-option
v-for="a in accounts"
:key="a.id"
:label="a.accountName"
:value="a.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleCreate">创建</el-button>
</el-form-item>
@@ -28,23 +38,86 @@
<el-table-column prop="channelConversationId" label="渠道会话ID" />
<el-table-column prop="conversationName" label="名称" />
<el-table-column prop="status" label="状态" />
<el-table-column label="操作" width="120">
<template #default="{ row }">
<el-button link type="primary" @click="openBind(row)">绑定账号</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog v-model="bindVisible" title="绑定账号" width="500px">
<el-form :model="bindForm" label-width="100px">
<el-form-item label="账号">
<el-select v-model="bindForm.accountId" placeholder="选择账号">
<el-option
v-for="a in accounts"
:key="a.id"
:label="a.accountName"
:value="a.id"
/>
</el-select>
</el-form-item>
<el-form-item label="绑定类型">
<el-select v-model="bindForm.bindingType" placeholder="选择绑定类型">
<el-option label="发送主号" :value="1" />
<el-option label="发送备用号" :value="2" />
<el-option label="接收主号" :value="3" />
<el-option label="接收备用号" :value="4" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="bindVisible = false">取消</el-button>
<el-button type="primary" @click="handleBind">确认</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onMounted, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { createConversation } from '@/api/channel'
import {
bindConversationAccount,
createConversation,
listChannelAccounts,
listConversations,
} from '@/api/channel'
const form = reactive({
conversationType: 2,
channelType: 'wecom',
channelConversationId: '',
conversationName: '',
ownerAccountId: undefined as number | undefined,
})
const conversations = ref<any[]>([])
const accounts = ref<any[]>([])
const bindVisible = ref(false)
const currentConversationId = ref<number | undefined>()
const bindForm = reactive({
accountId: undefined as number | undefined,
bindingType: 1,
})
async function loadConversations() {
try {
const res: any = await listConversations()
conversations.value = res.data || []
} catch (e: any) {
ElMessage.error(e.message)
}
}
async function loadAccounts() {
try {
const res: any = await listChannelAccounts()
accounts.value = res.data || []
} catch (e: any) {
ElMessage.error(e.message)
}
}
async function handleCreate() {
try {
@@ -55,4 +128,28 @@ async function handleCreate() {
ElMessage.error(e.message)
}
}
function openBind(row: any) {
currentConversationId.value = row.id
bindForm.accountId = undefined
bindForm.bindingType = 1
bindVisible.value = true
}
async function handleBind() {
if (!currentConversationId.value) return
try {
await bindConversationAccount(currentConversationId.value, bindForm)
ElMessage.success('绑定成功')
bindVisible.value = false
await loadConversations()
} catch (e: any) {
ElMessage.error(e.message)
}
}
onMounted(() => {
loadConversations()
loadAccounts()
})
</script>

View File

@@ -2,13 +2,13 @@
<div>
<el-row :gutter="20">
<el-col :span="6">
<el-statistic title="渠道主体" :value="stats.subjects" />
<el-statistic title="渠道主体" :value="stats.subjectCount" />
</el-col>
<el-col :span="6">
<el-statistic title="渠道账号" :value="stats.accounts" />
<el-statistic title="渠道账号" :value="stats.accountCount" />
</el-col>
<el-col :span="6">
<el-statistic title="会话/群聊" :value="stats.conversations" />
<el-statistic title="会话/群聊" :value="stats.conversationCount" />
</el-col>
<el-col :span="6">
<el-statistic title="今日发送" :value="stats.sentToday" />
@@ -25,14 +25,27 @@
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { onMounted, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { getDashboardStats } from '@/api/dashboard'
const stats = reactive({
subjects: 0,
accounts: 0,
conversations: 0,
subjectCount: 0,
accountCount: 0,
conversationCount: 0,
sentToday: 0,
})
async function loadStats() {
try {
const res: any = await getDashboardStats()
Object.assign(stats, res.data || {})
} catch (e: any) {
ElMessage.error(e.message)
}
}
onMounted(loadStats)
</script>
<style scoped>

View File

@@ -35,9 +35,9 @@
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onMounted, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { createPerson } from '@/api/crm'
import { createPerson, listPersons } from '@/api/crm'
const form = reactive({
personCode: '',
@@ -48,6 +48,15 @@ const form = reactive({
const persons = ref<any[]>([])
async function loadPersons() {
try {
const res: any = await listPersons()
persons.value = res.data || []
} catch (e: any) {
ElMessage.error(e.message)
}
}
async function handleCreate() {
try {
const res: any = await createPerson(form)
@@ -57,4 +66,6 @@ async function handleCreate() {
ElMessage.error(e.message)
}
}
onMounted(loadPersons)
</script>

View File

@@ -4,8 +4,16 @@
<el-form-item label="标签名">
<el-input v-model="form.tagName" placeholder="标签名" />
</el-form-item>
<el-form-item label="父标签ID">
<el-input-number v-model="form.parentId" :min="0" />
<el-form-item label="父标签">
<el-select v-model="form.parentId" placeholder="选择父标签">
<el-option label="无" :value="0" />
<el-option
v-for="t in tags"
:key="t.id"
:label="t.tagName"
:value="t.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleCreate">创建</el-button>