接入交互统计

dev
linyongLynn 3 months ago
parent 950953b512
commit 825236b76e

@ -116,3 +116,13 @@ export function supplyDemandDetail(params) {
params params
}) })
} }
// 供需管理 - 获取图表数据
export function supplyDemandChart(params) {
return request({
method: 'get',
url: '/api/admin/supply-demand/chart',
params
})
}

@ -696,10 +696,10 @@
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="showSystemDataModal = false">取消</el-button> <el-button @click="showSystemDataModal = false">取消</el-button>
<el-button type="warning" @click="consolePrintSelectedData" :disabled="(allSelectedStudents.length + selectedSystemStudents.length) === 0"> <!-- <el-button type="warning" @click="consolePrintSelectedData" :disabled="(allSelectedStudents.length + selectedSystemStudents.length) === 0">
<i class="el-icon-view"></i> <i class="el-icon-view"></i>
控制台打印 控制台打印
</el-button> </el-button> -->
<el-button type="primary" @click="exportSystemData" :disabled="(allSelectedStudents.length + selectedSystemStudents.length) === 0"> <el-button type="primary" @click="exportSystemData" :disabled="(allSelectedStudents.length + selectedSystemStudents.length) === 0">
<i class="el-icon-download"></i> <i class="el-icon-download"></i>
导出数据 导出数据

@ -33,7 +33,9 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="操作"> <el-form-item label="操作">
<el-button type="primary" @click="updateStats"></el-button> <el-button type="primary" @click="updateStats" :loading="loading">
{{ loading ? '更新中...' : '更新统计' }}
</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -49,10 +51,10 @@
<i class="el-icon-document-add"></i> <i class="el-icon-document-add"></i>
</div> </div>
</div> </div>
<div class="stat-value">156</div> <div class="stat-value">{{ chartData.totalCount || 0 }}</div>
<div class="stat-change change-up"> <div class="stat-change" :class="getChangeClass(chartData.publishChange)">
<i class="el-icon-arrow-up"></i> <i :class="getChangeIcon(chartData.publishChange)"></i>
<span>+8.3% 较上期</span> <span>{{ formatChange(chartData.publishChange) }} 较上期</span>
</div> </div>
</div> </div>
@ -63,10 +65,10 @@
<i class="el-icon-message"></i> <i class="el-icon-message"></i>
</div> </div>
</div> </div>
<div class="stat-value">1562</div> <div class="stat-value">{{ chartData.messageCount || 0 }}</div>
<div class="stat-change change-up"> <div class="stat-change" :class="getChangeClass(chartData.messageChange)">
<i class="el-icon-arrow-up"></i> <i :class="getChangeIcon(chartData.messageChange)"></i>
<span>+15.7% 较上期</span> <span>{{ formatChange(chartData.messageChange) }} 较上期</span>
</div> </div>
</div> </div>
@ -77,10 +79,10 @@
<i class="el-icon-chat-dot-round"></i> <i class="el-icon-chat-dot-round"></i>
</div> </div>
</div> </div>
<div class="stat-value">347</div> <div class="stat-value">{{ chartData.interactionCount || 0 }}</div>
<div class="stat-change change-up"> <div class="stat-change" :class="getChangeClass(chartData.interactionChange)">
<i class="el-icon-arrow-up"></i> <i :class="getChangeIcon(chartData.interactionChange)"></i>
<span>+12.5% 较上期</span> <span>{{ formatChange(chartData.interactionChange) }} 较上期</span>
</div> </div>
</div> </div>
</div> </div>
@ -91,19 +93,19 @@
供需交互明细 供需交互明细
</div> </div>
<div class="data-table"> <div class="data-table">
<el-table :data="interactionList" style="width: 100%"> <el-table :data="interactionList" style="width: 100%" v-loading="tableLoading">
<el-table-column label="供需信息" width="300"> <el-table-column label="供需信息" min-width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<div style="max-width: 250px;"> <div>
<div style="font-weight: 600; font-size: 14px; margin-bottom: 5px;">{{ scope.row.title }}</div> <div style="font-weight: 600; font-size: 14px; margin-bottom: 5px;">{{ scope.row.title }}</div>
<div style="font-size: 12px; color: #666; margin-bottom: 5px;">{{ scope.row.description }}</div> <div style="font-size: 12px; color: #666; margin-bottom: 5px;">{{ scope.row.description }}</div>
<el-tag :type="scope.row.type === 'demand' ? 'warning' : 'success'" size="small"> <el-tag :type="scope.row.type === 'demand' ? 'warning' : 'success'" size="small">
{{ scope.row.type === 'demand' ? '需求' : '供应' }} {{ scope.row.type === 'demand' ? '需求' : '供应' }}
</el-tag> </el-tag>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="发布者" width="200"> <el-table-column label="发布者" min-width="150">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="user-info"> <div class="user-info">
<div class="user-avatar">{{ scope.row.publisher.charAt(0) }}</div> <div class="user-avatar">{{ scope.row.publisher.charAt(0) }}</div>
@ -114,14 +116,14 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="发布时间" width="120"> <el-table-column label="发布时间" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<div style="font-size: 12px;">{{ scope.row.publishTime }}</div> <div style="font-size: 12px;">{{ scope.row.publishTime }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="交互记录" width="300"> <el-table-column label="交互记录" min-width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<div style="max-width: 280px;"> <div>
<div class="interaction-detail"> <div class="interaction-detail">
<div v-for="(interaction, index) in scope.row.interactions" :key="index" style="margin-bottom: 8px;"> <div v-for="(interaction, index) in scope.row.interactions" :key="index" style="margin-bottom: 8px;">
<span style="font-size: 12px;">{{ interaction.user }}({{ interaction.year }}) · {{ interaction.time }}</span> <span style="font-size: 12px;">{{ interaction.user }}({{ interaction.year }}) · {{ interaction.time }}</span>
@ -130,7 +132,7 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" width="100"> <el-table-column label="状态" min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="getStatusType(scope.row.status)" size="small"> <el-tag :type="getStatusType(scope.row.status)" size="small">
{{ scope.row.statusText }} {{ scope.row.statusText }}
@ -143,7 +145,7 @@
<!-- 分页 --> <!-- 分页 -->
<div class="pagination-container"> <div class="pagination-container">
<div class="pagination-info"> <div class="pagination-info">
<span class="text-muted">显示 1-10 {{ totalCount }} 条记录</span> <span class="text-muted">显示 {{ (currentPage - 1) * pageSize + 1 }}-{{ Math.min(currentPage * pageSize, totalCount) }} {{ totalCount }} 条记录</span>
</div> </div>
<el-pagination <el-pagination
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
@ -159,6 +161,8 @@
</template> </template>
<script> <script>
import { supplyDemandChart } from '@/api/student'
export default { export default {
name: 'InteractionStats', name: 'InteractionStats',
data() { data() {
@ -169,70 +173,120 @@ export default {
}, },
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
totalCount: 156, totalCount: 0,
interactionList: [ loading: false,
{ tableLoading: false,
title: '寻找技术合作伙伴', chartData: {
description: '互联网科技类企业合作具备AI开发能力...', totalCount: 0,
type: 'demand', messageCount: 0,
publisher: '张总', interactionCount: 0,
publisherInfo: '2010届 · 科技公司', publishChange: 0,
publishTime: '2024-01-10\n09:30', messageChange: 0,
interactions: [ interactionChange: 0
{ user: '李经理', year: '2015届', time: '2024-01-12 14:30' }, },
{ user: '王顾问', year: '2008届', time: '2024-01-13 16:45' } interactionList: []
],
status: 'normal',
statusText: '正常'
},
{
title: '投融资咨询服务',
description: '提供企业投融资、财务咨询等专业服务...',
type: 'supply',
publisher: '赵总',
publisherInfo: '2012届 · 投资公司',
publishTime: '2024-01-08\n14:20',
interactions: [
{ user: '陈经理', year: '2018届', time: '2024-01-11 15:30' },
{ user: '孙总', year: '2005届', time: '2024-01-14 09:15' }
],
status: 'normal',
statusText: '正常'
},
{
title: '企业管理咨询',
description: '人力资源、组织架构、流程优化等管理咨询...',
type: 'supply',
publisher: '孙总',
publisherInfo: '2005届 · 咨询公司',
publishTime: '2024-01-05\n11:40',
interactions: [
{ user: '陈经理', year: '2018届', time: '2024-01-15 11:20' },
{ user: '刘总', year: '2013届', time: '2024-01-15 16:30' }
],
status: 'closed',
statusText: '已关闭'
}
]
} }
}, },
mounted() {
this.fetchChartData()
},
methods: { methods: {
updateStats() { //
console.log('更新统计数据:', this.filter) async fetchChartData() {
try {
this.loading = true
const params = {
timeRange: this.filter.timeRange,
supplyType: this.filter.supplyType || undefined
}
const response = await supplyDemandChart(params)
if (response) {
this.chartData = {
totalCount: response.supply_demand_count || 0,
messageCount: response.message_count || 0,
interactionCount: response.interaction_count || 0,
publishChange: response.supply_demand_growth_rate?.rate || 0,
messageChange: response.message_growth_rate?.rate || 0,
interactionChange: response.interaction_growth_rate?.rate || 0
}
//
this.totalCount = response.supply_demand_count || 0
}
} catch (error) {
console.error('获取图表数据失败:', error)
this.$message.error('获取统计数据失败,请重试')
} finally {
this.loading = false
}
},
//
async updateStats() {
await this.fetchChartData()
this.$message.success('统计数据已更新') this.$message.success('统计数据已更新')
}, },
handleCurrentChange(page) {
//
async handleCurrentChange(page) {
this.currentPage = page this.currentPage = page
console.log('切换到第', page, '页') this.tableLoading = true
// API
this.$message.info(`正在加载第 ${page} 页数据...`) try {
// API
// 使
await this.fetchChartData()
this.$message.info(`已加载第 ${page} 页数据`)
} catch (error) {
console.error('加载分页数据失败:', error)
this.$message.error('加载数据失败')
} finally {
this.tableLoading = false
}
}, },
//
getStatusType(status) { getStatusType(status) {
const statusMap = { const statusMap = {
normal: 'success', normal: 'success',
closed: 'info' closed: 'info',
pending: 'warning',
rejected: 'danger'
} }
return statusMap[status] || 'info' return statusMap[status] || 'info'
},
//
getChangeClass(change) {
if (change > 0) return 'change-up'
if (change < 0) return 'change-down'
return 'change-neutral'
},
//
getChangeIcon(change) {
if (change > 0) return 'el-icon-arrow-up'
if (change < 0) return 'el-icon-arrow-down'
return 'el-icon-minus'
},
//
formatChange(change) {
if (change > 0) return `+${change.toFixed(1)}%`
if (change < 0) return `${change.toFixed(1)}%`
return '0.0%'
}
},
//
watch: {
filter: {
handler() {
this.currentPage = 1
this.fetchChartData()
},
deep: true
} }
} }
} }
@ -397,6 +451,19 @@ export default {
} }
} }
} }
//
::v-deep .el-table {
width: 100% !important;
.el-table__body-wrapper {
overflow-x: auto;
}
.el-table__header-wrapper {
overflow-x: auto;
}
}
} }
.user-info { .user-info {

Loading…
Cancel
Save