lion 3 months ago
commit 6bbb8abb47

@ -107,3 +107,12 @@ export function supplyDemandDestroy(params) {
params
})
}
// 供需管理 - 获取详情
export function supplyDemandDetail(params) {
return request({
method: 'get',
url: '/api/mobile/supply-demand/detail',
params
})
}

@ -35,26 +35,26 @@
<div class="search-section">
<el-form :model="filters" inline>
<el-form-item>
<el-input
v-model="filters.keyword"
placeholder="搜索书名、作者"
<el-input
v-model="filters.keyword"
placeholder="搜索书名、作者"
clearable
@clear="handleSearch"
></el-input>
</el-form-item>
<el-form-item>
<el-select
v-model="filters.category"
placeholder="全部分类"
<el-select
v-model="filters.category"
placeholder="全部分类"
clearable
@clear="handleSearch"
@change="handleSearch"
>
<el-option label="全部分类" value=""></el-option>
<el-option
v-for="category in categoryList"
:key="category"
:label="category"
<el-option
v-for="category in categoryList"
:key="category"
:label="category"
:value="category"
></el-option>
</el-select>
@ -77,10 +77,11 @@
<el-button type="primary" icon="el-icon-search" @click="handleSearch"></el-button>
</el-form-item>
<el-form-item>
<el-button type="success" icon="el-icon-download" @click="handleExport"></el-button>
</el-form-item>
<el-form-item>
<el-button type="info" icon="el-icon-upload2" @click="handleImport"></el-button>
<el-button
type="success"
icon="el-icon-download"
@click="handleExport"
>导出数据</el-button>
</el-form-item>
</el-form>
</div>
@ -180,6 +181,8 @@
:page-size="listQuery.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
:pager-count="7"
background
></el-pagination>
</div>
@ -413,7 +416,7 @@ export default {
total: 0,
listQuery: {
page: 1,
limit: 10
page_size: 10
},
multipleSelection: [],
bookForm: {
@ -456,7 +459,7 @@ export default {
try {
const params = {
page: this.listQuery.page,
limit: this.listQuery.limit
page_size: this.listQuery.page_size
}
// filter
@ -487,7 +490,13 @@ export default {
this.total = res.list?.total || 0
this.listQuery.page = res.list?.current_page || 1
this.chartData = res.chart || {}
this.categoryList = res.category || []
//
if (res.category && typeof res.category === 'object') {
this.categoryList = Object.values(res.category).filter(category => category && category.trim() !== '')
} else {
this.categoryList = []
}
} catch (error) {
console.error('获取图书列表失败:', error)
this.$message.error('获取图书列表失败')
@ -497,14 +506,122 @@ export default {
this.listQuery.page = 1
this.getList()
},
handleExport() {
console.log('导出数据')
this.$message.info('数据导出中...')
},
handleImport() {
console.log('批量导入')
this.$message.info('批量导入功能')
async handleExport() {
try {
this.$message.info('正在获取所有图书数据,请稍候...')
//
const countParams = {
page: 1,
page_size: 1
}
//
let filterIndex = 0
if (this.filters.keyword) {
countParams.keyword = this.filters.keyword
}
if (this.filters.category) {
countParams[`filter[${filterIndex}][key]`] = 'category'
countParams[`filter[${filterIndex}][op]`] = 'eq'
countParams[`filter[${filterIndex}][value]`] = this.filters.category
filterIndex++
}
if (this.filters.status !== '') {
countParams[`filter[${filterIndex}][key]`] = 'status'
countParams[`filter[${filterIndex}][op]`] = 'eq'
countParams[`filter[${filterIndex}][value]`] = this.filters.status
filterIndex++
}
const countRes = await index(countParams)
const totalCount = countRes.list?.total || 0
if (totalCount === 0) {
this.$message.warning('没有找到可导出的图书数据')
return
}
// 使page_size
const params = {
page: 1,
page_size: totalCount
}
//
filterIndex = 0
if (this.filters.keyword) {
params.keyword = this.filters.keyword
}
if (this.filters.category) {
params[`filter[${filterIndex}][key]`] = 'category'
params[`filter[${filterIndex}][op]`] = 'eq'
params[`filter[${filterIndex}][value]`] = this.filters.category
filterIndex++
}
if (this.filters.status !== '') {
params[`filter[${filterIndex}][key]`] = 'status'
params[`filter[${filterIndex}][op]`] = 'eq'
params[`filter[${filterIndex}][value]`] = this.filters.status
filterIndex++
}
const res = await index(params)
const allBooks = res.list?.data || []
//
const exportData = allBooks.map(book => ({
书名: book.title || '未设置',
作者: book.author || '未知',
ISBN: book.isbn || '未设置',
出版社: book.publisher || '未设置',
出版年份: book.publish_year || '未设置',
分类: book.category || '未分类',
状态: this.getStatusText(book.status),
图书简介: book.description || '暂无简介',
添加时间: this.formatDateTime(book.created_at)
}))
// CSV
const headers = Object.keys(exportData[0])
const csvContent = [
headers.join(','),
...exportData.map(row =>
headers.map(header => {
const value = row[header] || ''
//
if (typeof value === 'string' && (value.includes(',') || value.includes('"') || value.includes('\n'))) {
return `"${value.replace(/"/g, '""')}"`
}
return value
}).join(',')
)
].join('\n')
//
const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' })
const link = document.createElement('a')
const url = URL.createObjectURL(blob)
link.setAttribute('href', url)
link.setAttribute('download', `图书数据_${new Date().toISOString().slice(0, 10)}.csv`)
link.style.visibility = 'hidden'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
this.$message.success(`成功导出 ${allBooks.length} 本图书数据`)
} catch (error) {
console.error('导出失败:', error)
this.$message.error('导出失败,请重试')
}
},
handleSelectionChange(val) {
this.multipleSelection = val
},
@ -514,9 +631,9 @@ export default {
},
getStatusTagType(status) {
const statusMap = {
0: 'success', //
1: 'warning', //
2: 'danger' //
0: 'success', //
1: 'warning', //
2: 'danger' //
}
return statusMap[status] || 'info'
},
@ -606,6 +723,19 @@ export default {
this.listQuery.page = val
this.getList()
},
//
handlePageJump(url) {
if (url) {
// URL
const pageMatch = url.match(/page=(\d+)/)
if (pageMatch) {
const page = parseInt(pageMatch[1])
this.listQuery.page = page
this.getList()
}
}
},
handleCloseModal() {
this.resetForm()
this.isEdit = false
@ -851,13 +981,25 @@ export default {
.pagination-container {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 20px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.pagination-info {
margin-top: 15px;
color: #666;
font-size: 14px;
text-align: center;
}
.pagination-info span {
margin: 0 10px;
}
.form-section {
background: #f8f9fa;
padding: 20px;
@ -991,6 +1133,11 @@ export default {
border: 1px dashed #d1d5db;
}
.no-location {
color: #999;
font-size: 12px;
}
/* Element UI 表格样式覆盖 */
::v-deep .el-table th {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

@ -1,31 +1,78 @@
<template>
<el-dialog :visible.sync="visible" width="70%" :title="'供需详情'">
<div class="supply-detail">
<el-dialog :visible="visible" width="70%" :title="'供需详情'" @close="handleClose">
<div v-if="finalDetail" class="supply-detail">
<div class="section">
<div class="label">供需类型</div>
<div>{{ detail.type === 1 ? '供应' : '需求' }}</div>
<div>{{ finalDetail.type === 1 ? '供应' : '需求' }}</div>
</div>
<div class="section">
<div class="label">标题</div>
<div>{{ detail.title }}</div>
<div>{{ finalDetail.title || '-' }}</div>
</div>
<div class="section">
<div class="label">详细描述</div>
<div>{{ detail.content }}</div>
<div>{{ finalDetail.content || '-' }}</div>
</div>
<div class="section">
<div class="label">行业标签</div>
<div>{{ detail.tag || '-' }}</div>
<div>{{ finalDetail.tag || '-' }}</div>
</div>
<div class="section">
<div class="label">联系人</div>
<div>{{ finalDetail.contact_name || '-' }}</div>
</div>
<div class="section">
<div class="label">公开模式</div>
<div>
<span v-if="finalDetail.public_way === 1"></span>
<span v-else-if="finalDetail.public_way === 2">私信后自动公开</span>
<span v-else-if="finalDetail.public_way === 3">不公开</span>
<span v-else>-</span>
</div>
</div>
<div class="section">
<div class="label">时效性</div>
<div>
<span v-if="finalDetail.expire_time">{{ finalDetail.expire_time }}</span>
<span v-else></span>
</div>
</div>
<div class="section">
<div class="label">联系方式</div>
<div>
<div v-if="detail.mobile">{{ detail.mobile }}</div>
<div v-if="detail.wechat">{{ detail.wechat }}</div>
<div v-if="detail.email">{{ detail.email }}</div>
<div v-if="finalDetail.mobile">{{ finalDetail.mobile }}</div>
<div v-if="finalDetail.wechat">{{ finalDetail.wechat }}</div>
<div v-if="finalDetail.email">{{ finalDetail.email }}</div>
<div v-if="!finalDetail.mobile && !finalDetail.wechat && !finalDetail.email">-</div>
</div>
</div>
<div v-if="finalDetail.files && finalDetail.files.length > 0" class="section">
<div class="label">相关图片</div>
<div class="image-list">
<img
v-for="file in finalDetail.files"
:key="file.id"
:src="file.url"
class="detail-image"
@click="handlePreviewImage(file.url)"
>
</div>
</div>
</div>
<div v-else-if="loading" class="no-data">
<i class="el-icon-loading" />
<p>加载中...</p>
</div>
<div v-else class="no-data">
<i class="el-icon-warning" />
<p>暂无数据</p>
</div>
<!-- 图片预览弹窗 -->
<el-dialog :visible.sync="previewVisible" width="50%" title="图片预览">
<img width="100%" :src="previewImage" alt="预览图片">
</el-dialog>
<span slot="footer" class="dialog-footer">
<el-button @click="$emit('update:visible', false)">关闭</el-button>
</span>
@ -33,14 +80,117 @@
</template>
<script>
import { supplyDemandDetail } from '@/api/student/index.js'
export default {
props: {
visible: Boolean,
detail: Object
visible: {
type: Boolean,
default: false
},
detail: {
type: Object,
default: () => null
},
id: {
type: [String, Number],
default: null // id
}
},
data() {
return {
previewVisible: false,
previewImage: '',
loading: false,
detailData: null
}
},
computed: {
// 使detail使detailData
finalDetail() {
return this.detail || this.detailData
}
},
watch: {
visible(val) {
if (val && this.id && !this.detail) {
this.fetchDetail()
}
},
id: {
immediate: true,
handler(val) {
if (val && this.visible && !this.detail) {
this.fetchDetail()
}
}
}
},
methods: {
async fetchDetail() {
if (!this.id) return
this.loading = true
try {
const res = await supplyDemandDetail({ id: this.id })
this.detailData = res.data || res
} catch (error) {
console.error('获取详情失败:', error)
this.$message.error('获取详情失败')
} finally {
this.loading = false
}
},
handlePreviewImage(url) {
if (url) {
this.previewImage = url
this.previewVisible = true
}
},
handleClose() {
this.$emit('update:visible', false)
},
getImageUrl(fileId) {
const detail = this.finalDetail
if (detail && detail.images && detail.images[fileId]) {
return detail.images[fileId]
}
return ''
}
}
}
</script>
<style scoped>
.supply-detail .section { margin-bottom: 16px; }
.supply-detail .label { font-weight: bold; margin-bottom: 4px; }
</style>
.no-data {
text-align: center;
padding: 40px;
color: #999;
}
.no-data i {
font-size: 24px;
margin-bottom: 10px;
}
.image-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.detail-image {
width: 80px;
height: 80px;
object-fit: cover;
border-radius: 4px;
cursor: pointer;
border: 1px solid #e4e7ed;
}
.detail-image:hover {
border-color: #409eff;
}
</style>

@ -1,5 +1,5 @@
<template>
<el-dialog :visible.sync="visible" width="70%" title="编辑供需">
<el-dialog :visible.sync="dialogVisible" width="70%" title="编辑供需">
<el-form :model="form" label-width="80px">
<el-form-item label="供需类型">
<el-radio-group v-model="form.type">
@ -8,48 +8,105 @@
</el-radio-group>
</el-form-item>
<el-form-item label="标题">
<el-input v-model="form.title" maxlength="50" show-word-limit></el-input>
<el-input v-model="form.title" maxlength="50" show-word-limit />
</el-form-item>
<el-form-item label="详细描述">
<el-input type="textarea" v-model="form.content" :rows="4" maxlength="200" show-word-limit></el-input>
<el-input v-model="form.content" type="textarea" :rows="4" maxlength="200" show-word-limit />
</el-form-item>
<el-form-item label="行业标签">
<el-input
v-model="tagInput"
placeholder="输入后回车键确认"
style="margin-bottom: 8px;"
@keyup.enter.native="addTag"
@blur="addTag"
style="margin-bottom: 8px;"
/>
<div>
<el-tag
v-for="(tag, idx) in tagList"
:key="tag + idx"
closable
@close="removeTag(idx)"
style="margin-right: 8px;"
@close="removeTag(idx)"
>{{ tag }}</el-tag>
</div>
<div style="color: #999; font-size: 12px; margin-top: 4px;">
建议添加相关行业标签方便其他校友找到你
</div>
</el-form-item>
<!-- 图片上传 -->
<el-form-item label="相关图片">
<el-upload
list-type="picture-card"
:file-list="imageList"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:before-upload="beforeImageUpload"
:on-success="handleUploadSuccess"
:http-request="handleCustomUpload"
multiple
>
<i class="el-icon-plus" />
</el-upload>
<el-dialog :visible.sync="previewVisible">
<img width="100%" :src="previewImage" alt="">
</el-dialog>
<div style="color: #999; font-size: 12px; margin-top: 4px;">
最多上传9张图片支持jpgpng格式单张不超过2MB
</div>
</el-form-item>
<!-- 时效性选择 -->
<el-form-item label="时效性">
<el-radio-group v-model="form.validityType">
<el-radio label="longterm">长期有效</el-radio>
<el-radio label="specific">具体日期</el-radio>
</el-radio-group>
<div v-if="form.validityType === 'specific'" style="margin-top: 12px;">
<el-date-picker
v-model="form.expireTime"
type="date"
placeholder="选择到期日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:picker-options="pickerOptions"
/>
</div>
<div style="color: #999; font-size: 12px; margin-top: 4px;">
<span v-if="form.validityType === 'longterm'"></span>
<span v-else></span>
</div>
</el-form-item>
<!-- 联系人 -->
<el-form-item label="联系人" required>
<el-input
v-model="form.contactName"
placeholder="请输入联系人姓名"
maxlength="20"
show-word-limit
/>
<div style="color: #999; font-size: 12px; margin-top: 4px;">
默认为您的姓名可修改
</div>
</el-form-item>
<el-form-item label="联系方式" required>
<div class="contact-type-group">
<el-button
:type="form.contactType === 'wechat' ? 'primary' : 'default'"
@click="form.contactType = 'wechat'"
icon="el-icon-chat-dot-round"
@click="form.contactType = 'wechat'"
>微信</el-button>
<el-button
:type="form.contactType === 'mobile' ? 'primary' : 'default'"
@click="form.contactType = 'mobile'"
icon="el-icon-phone"
@click="form.contactType = 'mobile'"
>电话</el-button>
<el-button
:type="form.contactType === 'email' ? 'primary' : 'default'"
@click="form.contactType = 'email'"
icon="el-icon-message"
@click="form.contactType = 'email'"
>邮箱</el-button>
</div>
<div style="margin-top: 12px;">
@ -69,44 +126,121 @@
placeholder="请输入邮箱"
/>
</div>
<!-- 联系方式公开模式 -->
<div style="margin-top: 16px;">
<div style="margin-bottom: 8px; color: #606266; font-size: 14px;">公开模式</div>
<el-radio-group v-model="form.publicWay">
<el-radio :label="1">直接公开</el-radio>
<el-radio :label="2">私信后自动公开</el-radio>
<el-radio :label="3">不公开</el-radio>
</el-radio-group>
<div style="color: #999; font-size: 12px; margin-top: 4px;">
<span v-if="form.publicWay === 1"></span>
<span v-else-if="form.publicWay === 2">用户私信后联系方式自动公开</span>
<span v-else></span>
</div>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="$emit('update:visible', false)">取消</el-button>
<el-button @click="handleCancel"></el-button>
<el-button type="primary" @click="handleSave"></el-button>
</span>
</el-dialog>
</template>
<script>
import { uploads } from '@/api/uploads'
export default {
props: {
visible: Boolean,
detail: Object
detail: {
type: Object,
default: () => null
}
},
data() {
return {
dialogVisible: false,
form: {
type: 1,
title: '',
content: '',
contactType: 'mobile',
mobile: '',
wechat: '',
email: ''
email: '',
publicWay: 1,
validityType: 'longterm',
expireTime: '',
contactName: ''
},
tagInput: '',
tagList: []
tagList: [],
imageList: [],
newUploadedFileIds: [],
previewVisible: false,
previewImage: '',
pickerOptions: {
disabledDate(time) {
return time.getTime() < Date.now() - 8.64e7
}
}
}
},
watch: {
visible: {
immediate: true,
handler(val) {
this.dialogVisible = val
}
},
dialogVisible(val) {
this.$emit('update:visible', val)
},
detail: {
immediate: true,
handler(val) {
if (!val) {
// detail null
this.form = {
type: 1,
title: '',
content: '',
contactType: 'mobile',
mobile: '',
wechat: '',
email: '',
publicWay: 1,
validityType: 'longterm',
expireTime: '',
contactName: ''
}
this.tagList = []
this.imageList = []
return
}
this.form = {
...val,
contactType: val.wechat ? 'wechat' : val.email ? 'email' : 'mobile'
id: val.id,
type: val.type || 1,
title: val.title || '',
content: val.content || '',
contactType: val.wechat ? 'wechat' : (val.email ? 'email' : 'mobile'),
mobile: val.mobile || '',
wechat: val.wechat || '',
email: val.email || '',
publicWay: val.public_way || 1,
validityType: val.expire_time ? 'specific' : 'longterm',
expireTime: val.expire_time || '',
contactName: val.contact_name || ''
}
this.tagList = Array.isArray(val.tag)
? val.tag
: (val.tag ? val.tag.split(',').filter(Boolean) : [])
this.imageList = Array.isArray(val.files)
? val.files.map(f => ({ id: f.id, url: f.url, name: f.original_name || '' }))
: (Array.isArray(val.file_ids) ? val.file_ids.map(id => ({ id, url: (val.images && val.images[id]) || '' })) : [])
}
}
},
@ -121,6 +255,63 @@ export default {
removeTag(idx) {
this.tagList.splice(idx, 1)
},
//
handlePictureCardPreview(file) {
this.previewImage = file.url
this.previewVisible = true
},
handleRemove(file, fileList) {
this.imageList = fileList
// ID
const removedId = file.response?.id || file.id
if (removedId) {
this.newUploadedFileIds = this.newUploadedFileIds.filter(id => id !== removedId)
}
},
handleUploadSuccess(response, file, fileList) {
this.imageList = fileList
},
async handleCustomUpload({ file, onSuccess, onError }) {
try {
const formData = new FormData()
formData.append('file', file)
const res = await uploads(formData)
//
const uploadedId = res.id || res.data?.id
const uploadedUrl = res.url || res.data?.url
const responsePayload = { id: uploadedId, url: uploadedUrl }
// ID
if (uploadedId) this.newUploadedFileIds.push(uploadedId)
// el-upload
onSuccess(responsePayload, file)
} catch (e) {
onError(e)
}
},
beforeImageUpload(file) {
const isJPG = file.type === 'image/jpeg'
const isPNG = file.type === 'image/png'
const isLt2M = file.size / 1024 / 1024 < 2
const isLt9 = this.imageList.length < 9
if (!isJPG && !isPNG) {
this.$message.error('上传图片只能是 JPG/PNG 格式!')
return false
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB!')
return false
}
if (!isLt9) {
this.$message.error('最多只能上传9张图片!')
return false
}
return true
},
handleCancel() {
this.dialogVisible = false
this.newUploadedFileIds = []
},
handleSave() {
const data = {
id: this.form.id,
@ -130,13 +321,24 @@ export default {
wechat: this.form.wechat,
mobile: this.form.mobile,
email: this.form.email,
type: this.form.type
type: this.form.type,
public_way: this.form.publicWay,
validity_type: this.form.validityType,
expire_time: this.form.validityType === 'specific' ? this.form.expireTime : null,
contact_name: this.form.contactName,
file_ids: this.imageList.map(item => item.response?.id || item.id).filter(Boolean)
}
// file_ids
if (this.newUploadedFileIds && this.newUploadedFileIds.length) {
const fileIdSet = new Set(data.file_ids)
this.newUploadedFileIds.forEach(id => fileIdSet.add(id))
data.file_ids = Array.from(fileIdSet)
}
if (this.form.contactType !== 'wechat') data.wechat = ''
if (this.form.contactType !== 'mobile') data.mobile = ''
if (this.form.contactType !== 'email') data.email = ''
this.$emit('save', data)
this.$emit('update:visible', false)
this.dialogVisible = false
}
}
}
@ -147,4 +349,4 @@ export default {
gap: 12px;
margin-bottom: 8px;
}
</style>
</style>

@ -23,6 +23,8 @@
<el-option label="待审核" value="0"></el-option>
<el-option label="已通过" value="1"></el-option>
<el-option label="已拒绝" value="2"></el-option>
<el-option label="退回修改" value="3"></el-option>
<el-option label="永久隐藏" value="4"></el-option>
</el-select>
</el-form-item>
<el-form-item>
@ -60,7 +62,7 @@
</el-table-column>
<el-table-column label="类型" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.type === 1 ? 'success' : 'primary'" size="small">
<el-tag :type="getTypeTagType(scope.row.type)" size="small">
{{ scope.row.type === 1 ? '供应' : '需求' }}
</el-tag>
</template>
@ -100,12 +102,14 @@
<div class="time-display-secondary">{{ formatTime(scope.row.created_at) }}</div>
</template>
</el-table-column>
<el-table-column label="操作" width="170" fixed="right">
<el-table-column label="操作" width="220" fixed="right">
<template slot-scope="scope">
<div class="action-buttons">
<el-button v-if="scope.row.status === 0 || scope.row.status === 2" type="success" size="mini" icon="el-icon-check" @click="handleApprove(scope.row)"></el-button>
<el-button v-if="scope.row.status === 0 || scope.row.status === 2 || scope.row.status === 3" type="success" size="mini" icon="el-icon-check" @click="handleApprove(scope.row)"></el-button>
<el-button type="primary" size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)"></el-button>
<el-button v-if="scope.row.status === 0" type="danger" size="mini" icon="el-icon-close" @click="handleReject(scope.row)"></el-button>
<el-button v-if="scope.row.status === 0 || scope.row.status === 1" type="warning" size="mini" icon="el-icon-refresh" @click="handleReturnForRevision(scope.row)">退</el-button>
<el-button v-if="scope.row.status === 0 || scope.row.status === 1" type="info" size="mini" icon="el-icon-hide" @click="handlePermanentlyHide(scope.row)"></el-button>
<el-button type="info" size="mini" icon="el-icon-view" @click="handleView(scope.row)"></el-button>
</div>
</template>
@ -130,6 +134,7 @@
<SupplyDemandDetail
:visible.sync="showDetailDialog"
:detail="currentDetail"
:id="currentDetailId"
:readonly="true"
/>
<SupplyDemandEdit
@ -166,6 +171,7 @@ export default {
multipleSelection: [],
showDetailDialog: false,
currentDetail: null,
currentDetailId: null,
showEditDialog: false
}
},
@ -203,8 +209,8 @@ export default {
//
this.list = res.data || []
this.total = res.total || 0
// status0
this.pendingCount = this.list.filter(item => item.status === 0).length
// status03 + 退
this.pendingCount = this.list.filter(item => item.status === 0 || item.status === 3).length
},
handleSearch() {
this.listQuery.page = 1
@ -221,7 +227,9 @@ export default {
const statusMap = {
0: 'warning', //
1: 'success', //
2: 'danger' //
2: 'danger', //
3: 'warning', // 退
4: 'info' //
}
return statusMap[status] || 'info'
},
@ -229,10 +237,15 @@ export default {
const statusText = {
0: '待审核',
1: '已通过',
2: '已拒绝'
2: '已拒绝',
3: '退回修改',
4: '永久隐藏'
}
return statusText[status] || '未知'
},
getTypeTagType(type) {
return type === 1 ? 'success' : 'primary'
},
async handleApprove(row) {
try {
await supplyDemandSave({ id: row.id, status: 1 })
@ -244,6 +257,7 @@ export default {
},
handleEdit(row) {
this.currentDetail = row
this.currentDetailId = row.id
this.showEditDialog = true
this.showDetailDialog = false
},
@ -265,8 +279,30 @@ export default {
this.$message.error('操作失败')
}
},
async handleReturnForRevision(row) {
try {
await supplyDemandSave({ id: row.id, status: 3 })
this.$message.success('已退回修改!')
this.getList()
} catch (e) {
this.$message.error('操作失败')
}
},
async handlePermanentlyHide(row) {
try {
await supplyDemandSave({ id: row.id, status: 4 })
this.$message.success('已永久隐藏!')
this.getList()
} catch (e) {
this.$message.error('操作失败')
}
},
handleView(row) {
console.log('handleView called with row:', row)
console.log('row.id:', row.id)
this.currentDetail = row
this.currentDetailId = row.id
console.log('currentDetailId set to:', this.currentDetailId)
this.showDetailDialog = true
this.showEditDialog = false
},
@ -361,7 +397,10 @@ export default {
.user-info {
display: flex;
align-items: center;
gap: 8px;
}
.user-info > * + * {
margin-left: 8px;
}
.user-avatar {
@ -404,11 +443,10 @@ export default {
.action-buttons {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.el-button {
margin: 0;
}
.action-buttons .el-button {
margin: 0 3px 3px 0;
}
.pagination-container {

Loading…
Cancel
Save