|
|
|
|
@ -94,40 +94,43 @@
|
|
|
|
|
</div>
|
|
|
|
|
<div class="data-table">
|
|
|
|
|
<el-table :data="interactionList" style="width: 100%" v-loading="tableLoading">
|
|
|
|
|
<el-table-column label="供需信息" min-width="200">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<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>
|
|
|
|
|
<el-tag :type="scope.row.type === 'demand' ? 'warning' : 'success'" size="small">
|
|
|
|
|
{{ scope.row.type === 'demand' ? '需求' : '供应' }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="供需信息" min-width="200">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<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; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" :title="scope.row.content || '-'">{{ scope.row.content || '-' }}</div>
|
|
|
|
|
<el-tag :type="getTypeTagType(scope.row.type)" size="small">
|
|
|
|
|
{{ getTypeDisplayValue(scope.row.type) }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="发布者" min-width="150">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<div class="user-info">
|
|
|
|
|
<div class="user-avatar">{{ scope.row.publisher.charAt(0) }}</div>
|
|
|
|
|
<div class="user-avatar">{{ scope.row.publisher ? scope.row.publisher.charAt(0) : '-' }}</div>
|
|
|
|
|
<div>
|
|
|
|
|
<div style="font-weight: 600; font-size: 14px;">{{ scope.row.publisher }}</div>
|
|
|
|
|
<div style="font-size: 12px; color: #666;">{{ scope.row.publisherInfo }}</div>
|
|
|
|
|
<div style="font-weight: 600; font-size: 14px;">{{ scope.row.publisher || '-' }}</div>
|
|
|
|
|
<div style="font-size: 12px; color: #666;">{{ scope.row.publisherInfo || '-' }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="发布时间" min-width="120">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<div style="font-size: 12px;">{{ scope.row.publishTime }}</div>
|
|
|
|
|
<div style="font-size: 12px;">{{ scope.row.created_at || '-' }}</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="交互记录" min-width="200">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<div>
|
|
|
|
|
<div class="interaction-detail">
|
|
|
|
|
<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>
|
|
|
|
|
<div v-if="scope.row.messages && scope.row.messages.length > 0">
|
|
|
|
|
<div v-for="(message, index) in scope.row.messages" :key="index" style="margin-bottom: 8px;">
|
|
|
|
|
<span style="font-size: 12px;">{{ message.to_user.name || '-' }}({{ message.to_user.year || '-' }}届) · {{ formatDateTime(message.created_at) || '-' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-else style="color: #999; font-size: 12px;">暂无交互记录</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
@ -135,7 +138,7 @@
|
|
|
|
|
<el-table-column label="状态" min-width="100">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<el-tag :type="getStatusType(scope.row.status)" size="small">
|
|
|
|
|
{{ scope.row.statusText }}
|
|
|
|
|
{{ getStatusText(scope.row.status) }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
@ -195,9 +198,22 @@ export default {
|
|
|
|
|
async fetchChartData() {
|
|
|
|
|
try {
|
|
|
|
|
this.loading = true
|
|
|
|
|
|
|
|
|
|
// 根据timeRange计算开始和结束日期
|
|
|
|
|
const endDate = new Date()
|
|
|
|
|
const startDate = new Date()
|
|
|
|
|
startDate.setDate(endDate.getDate() - this.filter.timeRange)
|
|
|
|
|
|
|
|
|
|
const params = {
|
|
|
|
|
timeRange: this.filter.timeRange,
|
|
|
|
|
supplyType: this.filter.supplyType || undefined
|
|
|
|
|
start_date: startDate.toISOString().split('T')[0], // YYYY-MM-DD格式
|
|
|
|
|
end_date: endDate.toISOString().split('T')[0], // YYYY-MM-DD格式
|
|
|
|
|
page_size: this.pageSize,
|
|
|
|
|
page: this.currentPage
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const type = this.getTypeValue(this.filter.supplyType)
|
|
|
|
|
if (type !== undefined) {
|
|
|
|
|
params.type = type
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await supplyDemandChart(params)
|
|
|
|
|
@ -211,8 +227,20 @@ export default {
|
|
|
|
|
interactionChange: response.interaction_growth_rate?.rate || 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新总数
|
|
|
|
|
this.totalCount = response.supply_demand_count || 0
|
|
|
|
|
// 更新交互记录列表
|
|
|
|
|
if (response.list && response.list.data) {
|
|
|
|
|
this.interactionList = response.list.data
|
|
|
|
|
}
|
|
|
|
|
console.log(this.interactionList)
|
|
|
|
|
// 更新分页数据
|
|
|
|
|
if (response.list) {
|
|
|
|
|
this.totalCount = response.list.total || 0
|
|
|
|
|
this.currentPage = response.list.current_page || 1
|
|
|
|
|
this.pageSize = response.list.per_page || 10
|
|
|
|
|
} else {
|
|
|
|
|
// 如果没有list结构,使用原有的总数
|
|
|
|
|
this.totalCount = response.supply_demand_count || 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取图表数据失败:', error)
|
|
|
|
|
@ -249,14 +277,27 @@ export default {
|
|
|
|
|
// 获取状态类型
|
|
|
|
|
getStatusType(status) {
|
|
|
|
|
const statusMap = {
|
|
|
|
|
normal: 'success',
|
|
|
|
|
closed: 'info',
|
|
|
|
|
pending: 'warning',
|
|
|
|
|
rejected: 'danger'
|
|
|
|
|
0: 'warning', // 待审核
|
|
|
|
|
1: 'success', // 通过
|
|
|
|
|
2: 'danger', // 拒绝
|
|
|
|
|
3: 'info', // 退回修改
|
|
|
|
|
4: 'info' // 永久隐藏
|
|
|
|
|
}
|
|
|
|
|
return statusMap[status] || 'info'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取状态文本
|
|
|
|
|
getStatusText(status) {
|
|
|
|
|
const statusMap = {
|
|
|
|
|
0: '待审核',
|
|
|
|
|
1: '通过',
|
|
|
|
|
2: '拒绝',
|
|
|
|
|
3: '退回修改',
|
|
|
|
|
4: '永久隐藏'
|
|
|
|
|
}
|
|
|
|
|
return statusMap[status] || '未知状态'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取变化样式类
|
|
|
|
|
getChangeClass(change) {
|
|
|
|
|
if (change > 0) return 'change-up'
|
|
|
|
|
@ -276,6 +317,62 @@ export default {
|
|
|
|
|
if (change > 0) return `+${change.toFixed(1)}%`
|
|
|
|
|
if (change < 0) return `${change.toFixed(1)}%`
|
|
|
|
|
return '0.0%'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取类型值映射
|
|
|
|
|
getTypeValue(supplyType) {
|
|
|
|
|
if (supplyType === 'supply') return 1
|
|
|
|
|
if (supplyType === 'demand') return 2
|
|
|
|
|
return undefined // 全部时不传type参数
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取类型显示值
|
|
|
|
|
getTypeDisplayValue(type) {
|
|
|
|
|
if (type === 'demand' || type === 2) return '需求'
|
|
|
|
|
if (type === 'supply' || type === 1) return '供应'
|
|
|
|
|
return '未知'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取类型标签样式
|
|
|
|
|
getTypeTagType(type) {
|
|
|
|
|
if (type === 'demand' || type === 2) return 'warning'
|
|
|
|
|
if (type === 'supply' || type === 1) return 'success'
|
|
|
|
|
return 'info'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 格式化日期时间
|
|
|
|
|
formatDateTime(dateTime) {
|
|
|
|
|
if (!dateTime) return '-'
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 如果是时间戳,转换为Date对象
|
|
|
|
|
let date
|
|
|
|
|
if (typeof dateTime === 'number') {
|
|
|
|
|
date = new Date(dateTime * 1000) // 假设是秒级时间戳
|
|
|
|
|
} else if (typeof dateTime === 'string') {
|
|
|
|
|
date = new Date(dateTime)
|
|
|
|
|
} else {
|
|
|
|
|
date = dateTime
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查日期是否有效
|
|
|
|
|
if (isNaN(date.getTime())) {
|
|
|
|
|
console.warn('Invalid date:', dateTime)
|
|
|
|
|
return '-'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 格式化日期
|
|
|
|
|
const year = date.getFullYear()
|
|
|
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
|
|
|
const hours = String(date.getHours()).padStart(2, '0')
|
|
|
|
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
|
|
|
|
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('格式化日期时间失败:', error, dateTime)
|
|
|
|
|
return '-'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|