java-mall-admin/src/views/settings/config/report.vue

364 lines
10 KiB
Vue

<template>
<div class="report_container">
<div class="filter">
<el-input
v-model="filter.reporterNickname"
class="input_item"
clearable
placeholder="请输入举报人昵称"
prefix-icon="el-icon-search"
/>
<el-select
v-model="filter.processingStatus"
clearable
filterable
placeholder="选择处理状态"
>
<el-option
v-for="item in reportList"
:key="item.report_id"
:label="item.report_name"
:value="item.report_id"
/>
</el-select>
<el-button size="medium" type="primary" @click="handleSearch">
查询
</el-button>
</div>
<div class="list">
<el-table
ref="reportTable"
:data="tableData"
style="width: 100%"
border
stripe
>
<el-table-column label="举报正文" prop="reportContent" width="180px">
<template #default="scope">
<div class="text-ellipsis" :title="scope.row.reportContent">
{{ scope.row.reportContent }}
</div>
</template>
</el-table-column>
<el-table-column label="举报凭证" prop="reportVerify" width="180px">
<template #default="scope">
<div
v-if="scope.row.reportVerify && scope.row.reportVerify.length"
class="img-group"
>
<el-image
v-for="(img, index) in scope.row.reportVerify"
:key="index"
:src="img.url"
:preview-src-list="scope.row.reportVerify.map((item) => item.url)"
class="img-thumb"
fit="cover"
:title="img.description || `举报凭证${index + 1}`"
v-if="index < 3"
/>
<span v-if="scope.row.reportVerify.length > 3" class="img-count">
+{{ scope.row.reportVerify.length - 3 }}
</span>
</div>
<span v-else class="no-data">无凭证</span>
</template>
</el-table-column>
<el-table-column label="举报人昵称" prop="reporterNickname" width="120" />
<el-table-column
label="举报人手机号"
prop="reporterPhone"
width="130"
/>
<el-table-column label="被举报人昵称" prop="reportedNickname" width="120" />
<el-table-column label="被举报人用户ID" prop="reportedUserId" width="140" />
<el-table-column label="举报时间" prop="reporterTime" width="180" />
<el-table-column label="状态" prop="processingStatus" width="110">
<template #default="scope">
<el-tag :type="getStatusTagType(scope.row.processingStatus)">
{{ getStatusText(scope.row.processingStatus) }}
</el-tag>
</template>
</el-table-column>
<!-- 处理凭证(后台上传) -->
<el-table-column label="处理凭证" prop="processingVerify" width="180px">
<template #default="scope">
<div
v-if="scope.row.processingVerify && scope.row.processingVerify.length"
class="img-group"
>
<el-image
v-for="(img, index) in scope.row.processingVerify"
:key="index"
:src="img.url"
:preview-src-list="scope.row.processingVerify.map((item) => item.url)"
class="img-thumb"
fit="cover"
:title="img.description || `处理凭证${index + 1}`"
v-if="index < 3"
/>
<span v-if="scope.row.processingVerify.length > 3" class="img-count">
+{{ scope.row.processingVerify.length - 3 }}
</span>
</div>
<span v-else class="no-data">无处理凭证</span>
</template>
</el-table-column>
<!-- 处理结果 -->
<el-table-column label="处理结果" prop="processingResult" width="180px">
<template #default="scope">
<div class="text-ellipsis" :title="scope.row.processingResult">
{{ scope.row.processingResult || '未处理' }}
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-button
plain
size="mini"
type="primary"
@click="handleReport(scope.row)"
:disabled="scope.row.processingStatus === '处理完成'"
>
处理举报
</el-button>
<el-button
plain
size="mini"
type="primary"
@click="handleDetail(scope.row)"
>
详情
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
background
:current-page="pagination.pageNum"
layout="total, sizes, prev, pager, next, jumper"
:page-size="pagination.pageSize"
:total="pagination.total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
<ReportDeal ref="handleReport" @success="handleSuccess" />
<ReportDetail ref="handleDetail" @success="handleSuccess" />
</div>
</div>
</template>
<script>
import ReportDeal from './reportDeal.vue'
import ReportDetail from './reportDetail.vue'
import { getReportList } from '@/api/base/config'
export default {
components: {
ReportDeal,
ReportDetail,
},
data() {
return {
filter: {
reporterNickname: '',
processingStatus: '',
},
reportList: [
{ report_id: 0, report_name: '未处理' },
{ report_id: 1, report_name: '已受理' },
{ report_id: 2, report_name: '已驳回' },
{ report_id: 3, report_name: '处理完成' },
],
tableData: [],
pagination: {
pageNum: 1,
pageSize: 10,
total: 0,
pages: 0,
},
multipleSelection: [],
}
},
mounted() {
this.handleReportList()
},
methods: {
handleReport(row) {
this.$refs.handleReport.open(row)
},
handleDetail(row) {
this.$refs.handleDetail.open(row)
},
handleSuccess() {
this.handleReportList()
},
handleSelectionChange(val) {
this.multipleSelection = val
},
async handleReportList() {
try {
const params = {
pageNum: this.pagination.pageNum,
pageSize: this.pagination.pageSize,
reporterNickname: this.filter.reporterNickname,
processingStatus: this.filter.processingStatus,
}
const res = await getReportList(params)
console.log('ssssss', params)
this.tableData = (res.records || []).map((item) => ({
id: item.id,
reportContent: item.reportContent,
// 解析用户举报凭证
reportVerify: item.evidenceImages
? JSON.parse(item.evidenceImages)
: [],
// 解析后台处理凭证
processingVerify: item.processingEvidenceImages
? JSON.parse(item.processingEvidenceImages)
: [],
// 处理结果
processingResult: item.processingResult || '',
reporterNickname: item.reporterNickname,
reporterPhone: item.reporterPhone || '无',
reporterTime: item.createdAt,
processingStatus: this.getStatusText(item.processingStatus),
reportedNickname: item.reportedNickname,
reportedUserId: item.reportedUserId || '无',
// 保留原始数据供弹窗使用
rawData: item,
}))
this.pagination = {
...this.pagination,
total: res.total || 0,
pageNum: res.current || 1,
pageSize: res.size || 10,
pages: res.pages || 0,
}
} catch (error) {
console.error('获取举报列表失败:', error)
this.$message.error('获取数据失败,请重试')
}
},
handleCurrentChange(val) {
this.pagination.pageNum = val
this.handleReportList()
},
handleSizeChange(val) {
this.pagination.pageSize = val
this.pagination.pageNum = 1
this.handleReportList()
},
handleSearch() {
this.pagination.pageNum = 1
this.handleReportList()
},
getStatusText(status) {
switch (status) {
case 0:
return '未处理'
case 1:
return '已受理'
case 2:
return '已驳回'
case 3:
return '处理完成'
default:
return '未知状态'
}
},
getStatusTagType(state) {
switch (state) {
case '未处理':
return 'warning'
case '已受理':
return 'info'
case '已驳回':
return 'danger'
case '处理完成':
return 'success'
default:
return 'default'
}
},
},
}
</script>
<style lang="scss" scoped>
.filter {
display: flex;
align-items: center;
padding: 20px;
margin-bottom: 15px;
gap: 10px;
border-radius: 5px;
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
background: #fff;
.input_item {
width: 250px;
}
}
.list {
background: #fff;
padding: 20px;
display: flex;
flex-direction: column;
gap: 10px;
border-radius: 5px;
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
}
// 图片样式
.img-group {
position: relative;
display: inline-flex;
gap: 5px;
}
.img-thumb {
width: 50px;
height: 50px;
cursor: pointer;
border-radius: 3px;
}
.img-count {
position: absolute;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
color: white;
font-size: 12px;
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
// 文本省略样式
.text-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
// 无数据样式
.no-data {
color: #999;
font-size: 12px;
}
// 表格单元格垂直居中
::v-deep .el-table__cell {
vertical-align: middle !important;
}
</style>