审核模块

This commit is contained in:
凌尛 2025-06-24 17:46:32 +08:00
parent 2281f31313
commit 5806be9409
4 changed files with 602 additions and 0 deletions

View File

@ -0,0 +1,45 @@
import instance from '../../utils/axios.js'
const violationApi = {
// 获取查询参数与分页参数
pageQuery: (params) => {
// 转换分页参数名称
const convertedParams = {
...params,
pageNum: params.page,
pageSize: params.size
}
// 删除旧的参数
delete convertedParams.page
delete convertedParams.size
return instance.get('/violation/pageQuery', {
params: convertedParams,
// paramsSerializer: params => {
// return Object.entries(params)
// .filter(([_, v]) => v !== undefined)
// .map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
// .join('&')
// }
})
},
submit: (ids,remark) => {
return instance.post('/violation/errorSubmit?ids='+ids+"&remark="+remark);
},
successSubmit:(ids) => {
return instance.post('/violation/successSubmit?ids='+ids);
},
removeSubmit:(ids) => {
return instance.post('/violation/removeSubmit?ids='+ids);
},
editSubmit:(ids,sort) => {
return instance.post('/violation/editSubmit?id='+ids+"&sort="+sort);
}
}
export { violationApi }

View File

@ -84,6 +84,18 @@
}]
}]
},
{
title: '审核管理',
path: '/examine',
children:[{
title: '违规审核',
path: '/examine/violation',
children:[{
title: '违规列表',
path: '/examine/violation/list'
}]
}]
}
// ...
])
</script>

View File

@ -37,6 +37,11 @@ const routes = [{
path: '/tools/cards/list',
component: () => import('@/views/Tools/Cards/List.vue'),
meta: { title: '卡密列表' }
},
{
path: '/examine/violation/list',
component: () => import('@/views/Examine/Violation/List.vue'),
meta: { title: '违规列表' }
}
]
}]

View File

@ -0,0 +1,540 @@
<template>
<div class="list-container">
<!-- 搜索区域 -->
<div class="search-area">
<el-form :inline="true" :model="searchForm">
<el-form-item label="违规类型">
<el-select v-model="searchForm.type" placeholder="请选择违规类型" clearable style="min-width: 150px;">
<el-option label="isbn" :value="0" />
<el-option label="书名" :value="1" />
<el-option label="作者" :value="2" />
<el-option label="出版社" :value="3" />
</el-select>
</el-form-item>
<el-form-item label="违规内容">
<el-input v-model="searchForm.name" placeholder="请输入违规内容" clearable />
</el-form-item>
<el-form-item label="审核状态">
<el-select v-model="searchForm.review" placeholder="请选择审核状态" clearable style="min-width: 150px;">
<el-option label="待提交" :value="0" />
<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-item label="状态">
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable style="min-width: 150px;">
<el-option label="正常" :value="0" />
<el-option label="停用" :value="1" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="resetSearch">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="search-area">
<!-- 操作按钮 -->
<ActionBar @refresh="refreshData">
<template #left>
<el-button type="success" :disabled="multiple" @click="btnSuccess()">通过</el-button>
<el-button type="danger" :disabled="multiple" @click="btnError()" >驳回</el-button>
<el-button type="danger" :disabled="multiple" @click="btnRemove()" >删除</el-button>
<el-button type="warning" :disabled="single" @click="btnEdit()">修改</el-button>
</template>
</ActionBar>
<!-- 数据表格 -->
<el-table
ref="tableRef"
:data="tableData"
border
stripe
style="width: 100%;"
v-loading="loading"
@selection-change="handleSelectionChange"
:row-class-name="setReviewCellStyle"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键" align="center" prop="id" v-if="true" />
<el-table-column label="违规平台" align="center" prop="sort" width="250px" >
<template #default="scope">
<span v-for="fruit in scope.row.sort.split(',')" :key="fruit" >
{{getSort(fruit)}} &nbsp;
</span>
</template>
</el-table-column>
<el-table-column label="违规类型" align="center" prop="type">
<template #default="{ row }">
{{ getViolationType(row.type) }}
</template>
</el-table-column>
<el-table-column label="违规内容" align="center" prop="name" />
<el-table-column label="违规原因" align="center" prop="content" />
<el-table-column label="审核状态" align="center" prop="review" >
<template #default="{ row }">
{{ getReview(row.review) }}
</template>
</el-table-column>
<el-table-column label="审核意见" align="center" prop="remark" />
<el-table-column label="状态" align="center" prop="status">
<template #default="{ row }">
{{ getStatusType(row.status) }}
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
v-model:current-page="pagination.current"
v-model:page-size="pagination.size"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
<!-- 获取卡密对话框 -->
<el-dialog
title="驳回原因"
v-model="violationVisible"
width="500px"
:close-on-click-modal="false"
>
<el-input
v-model="remark"
style="width: 100%"
:rows="10"
type="textarea"
placeholder="请输入驳回原因"
/>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="submit">提交</el-button>
<el-button @click="violationVisible = false">取消</el-button>
</span>
</template>
</el-dialog>
<el-dialog title="修改违规平台" v-model="violtaionEditVisible" width="500px">
<el-form-item label="违规平台" prop="sort">
<el-checkbox-group v-model="sortArr">
<el-checkbox v-for="dict in getSortContent()" :key="dict.value" :label="dict.value">
{{ dict.label }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="editSubmit">提交</el-button>
<el-button @click="violtaionEditVisible = false">取消</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { violationApi } from '@/api/modules/violation.js'
import RefreshButton from '@/components/RefreshButton.vue'
import ActionBar from '@/components/ActionBar.vue'
//
const tableData = ref([])
const loading = ref(false)
const tableRef = ref(null)
const remark = ref('')
//
const searchForm = reactive({
type:'',
name:'',
review:'',
status:''
})
//
const pagination = reactive({
current: 1,
size: 10,
total: 0
})
const ids = ref([]);
const names = ref([]);
const reviews = ref([]);
const sorts = ref([]);
const single = ref(true);
const multiple = ref(true);
/** 多选框选中数据 */
const handleSelectionChange = (selection) => {
ids.value = selection.map(item => item.id);
names.value = selection.map(item => item.name);
reviews.value = selection.map(item => item.review);
sorts.value = selection.map(item => item.sort);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
const violationVisible = ref(false)
const violtaionEditVisible = ref(false);
//
onMounted(() => {
fetchData()
})
//
const fetchData = async () => {
loading.value = true
try {
//
const params = {
page: pagination.current,
size: pagination.size,
type: searchForm.type !== null ? searchForm.type : undefined,
name: searchForm.name || undefined,
status: searchForm.status || undefined,
review: searchForm.review !== null ? searchForm.review : undefined,
}
// 使API
const res = await violationApi.pageQuery(params)
// response.data使res
if (res.code === 200) {
tableData.value = res.data.list || []
pagination.total = res.data.total || 0
} else {
ElMessage.error(res.message || '获取数据失败')
}
} catch (error) {
console.error('获取数据失败:', error)
//
if (error.code === 'ECONNABORTED') {
ElMessage.error('请求超时,请检查网络连接或联系管理员')
} else if (error.response) {
ElMessage.error(`请求失败: ${error.response.status} ${error.response.statusText}`)
} else if (error.request) {
ElMessage.error('服务器未响应,请稍后再试')
} else {
ElMessage.error(`请求错误: ${error.message}`)
}
//
tableData.value = []
pagination.total = 0
} finally {
loading.value = false
}
}
//
const btnError = () => {
for(var i=0;i<reviews.value.length;i++){
if(reviews.value[i] != '1' ){
ElMessage.error('请选择待审核的数据!!!')
return;
}
}
//
violationVisible.value = true
}
//
const btnRemove = async () => {
//
await violationApi.removeSubmit(ids.value);
ElMessage.success('删除成功');
fetchData();
}
//
const sortArr = ref([]);
const btnEdit = () => {
violtaionEditVisible.value = true;
sortArr.value = sorts.value[0].split(',');
}
//
const btnSuccess = async () => {
for(var i=0;i<reviews.value.length;i++){
if(reviews.value[i] != '1' ){
ElMessage.error('请选择待审核的数据!!!')
return;
}
}
const res = await violationApi.successSubmit(ids.value);
if(res.code == '200'){
ElMessage.success('审核成功');
fetchData()
}else{
ElMessage.error('系统异常,请联系管理员');
}
}
const setReviewCellStyle = ({ row, column }) => {
if (row.review == 1) {
return 'shenhe-row'; // class
}
}
//
const refreshData = () => {
fetchData()
}
//
const handleSearch = () => {
pagination.current = 1
fetchData()
}
//
const resetSearch = () => {
searchForm.type = ''
searchForm.name = ''
searchForm.review = ''
searchForm.status = null
pagination.current = 1
fetchData()
}
//
const handleSizeChange = (size) => {
pagination.size = size
pagination.current = 1
fetchData()
}
//
const handleCurrentChange = (current) => {
pagination.current = current
fetchData()
}
//
const getStatusType = (status) => {
const map = {
0: '正常',
1: '停用'
}
return map[status] || 'info'
}
const getReview = (review) => {
const map = {
0: '待提交',
1: '待审核',
2: '已审核',
3: '已撤回',
4: '审核失败'
}
return map[review] || 'info'
}
const getSort = (sort) => {
const map = {
0:'拼多多',
1:'孔夫子',
2:'淘宝',
3:'咸鱼'
}
return map[sort] || 'info'
}
const getSortContent = () =>{
return [
{
"label":"拼多多",
"value":"0"
},
{
"label":"孔夫子",
"value":"1"
},
{
"label":"淘宝",
"value":"2"
},
{
"label":"咸鱼",
"value":"3"
},
]
}
//
const getViolationType = (type) => {
const map = {
0: 'isbn',
1: '书名',
2: '作者',
3: '出版社'
}
return map[type] || type
}
//
const formatDateTime = (timestamp) => {
if (!timestamp) return '-'
const date = new Date(timestamp)
return date.toLocaleString()
}
//
const submit = async () =>{
if(!remark.value){
ElMessage.error('请填写驳回原因!!!');
return
}
const res = await violationApi.submit(ids.value,remark.value);
if(res.code == '200'){
violationVisible.value = false;
ElMessage.success('驳回成功');
remark.value = '';
fetchData()
}else{
ElMessage.error('系统异常,请联系管理员');
}
}
//
const editSubmit = async() =>{
const res = await violationApi.editSubmit(ids.value,sortArr.value);
if(res.code == '200'){
violtaionEditVisible.value = false;
ElMessage.success('修改成功');
sortArr.value = [];
fetchData()
}else{
ElMessage.error('系统异常,请联系管理员');
}
}
</script>
<style scoped>
/* .list-container {
padding: 5px;
} */
.search-area {
margin-bottom: 20px;
padding: 15px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
text-align: left;
}
.search-area .el-form-item {
margin-right: 18px;
margin-bottom: 10px;
}
.action-bar {
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
text-align: left;
}
.action-left {
display: flex;
gap: 10px;
}
.action-right {
display: flex;
gap: 10px;
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-start;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
.card-secret-content {
text-align: left;
p {
margin-bottom: 15px;
font-size: 16px;
}
}
.card-params-content {
text-align: left;
p {
margin-bottom: 15px;
font-size: 16px;
}
}
:global(.warning-row) {
/* background: red !important;
color: white !important; */
background:#fdf6ec !important
}
:global(.shenhe-row) {
/* background: red !important;
color: white !important; */
background:#fde8e8 !important
}
.unit-label {
margin-left: 5px;
}
</style>