调整 发布
This commit is contained in:
@@ -11,14 +11,17 @@
|
||||
<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-option label="推送失败" :value="5" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="boxshadow">
|
||||
<!-- <div style="text-align: right; padding: 12px 0">
|
||||
<el-button type="primary" @click="goToAdd"> 新增发布 </el-button>
|
||||
</div> -->
|
||||
<div style="text-align: right; padding: 12px 0">
|
||||
<el-button type="primary" @click="fetchpublishfn"> 抓取 </el-button>
|
||||
</div>
|
||||
<ArtTable
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
@@ -65,7 +68,14 @@
|
||||
<template #default="scope">
|
||||
<ElRow>
|
||||
<el-button link @click="showDialog('detail', scope.row)"> 详情 </el-button>
|
||||
<el-button link type="primary" @click="editFn(scope.row)"> 编辑 </el-button>
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="editFn(scope.row)"
|
||||
v-if="scope.row.status === 0 || scope.row.status === 2"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button link type="success" @click="showAuditRecords(scope.row)"> 审核记录 </el-button>
|
||||
<el-button link type="danger" @click="deleteFn(scope.row)"> 删除 </el-button>
|
||||
</ElRow>
|
||||
@@ -110,7 +120,7 @@
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<!-- FAQ 展示 -->
|
||||
<el-descriptions-item label="FAQ 问答" :span="2" v-if="detailData.faqs && detailData.faqs.length">
|
||||
<!-- <el-descriptions-item label="FAQ 问答" :span="2" v-if="detailData.faqs && detailData.faqs.length">
|
||||
<div class="faq-display">
|
||||
<div v-for="(faq, index) in detailData.faqs" :key="index" class="faq-item">
|
||||
<div class="faq-question">
|
||||
@@ -123,7 +133,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions-item> -->
|
||||
<!-- 产品图 -->
|
||||
<el-descriptions-item label="产品图" :span="2">
|
||||
<div
|
||||
@@ -305,14 +315,15 @@
|
||||
<MultiFileUpload
|
||||
v-model="editAttachmentFileList"
|
||||
upload-text="点击上传附件"
|
||||
hint-text="支持多个文件上传"
|
||||
hint-text="仅支持单个文件上传"
|
||||
:max-count="1"
|
||||
:action-image-uplode="uploadActionFile"
|
||||
@change="handleEditAttachmentChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<!-- FAQ 编辑 -->
|
||||
<ElCol :sm="24" :md="24" :lg="24">
|
||||
<!-- <ElCol :sm="24" :md="24" :lg="24">
|
||||
<el-form-item label="FAQ 问答">
|
||||
<div class="faq-container">
|
||||
<div v-for="(faq, index) in editForm.faqs" :key="index" class="faq-item">
|
||||
@@ -344,7 +355,7 @@
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
</ElCol> -->
|
||||
</ElRow>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
@@ -452,6 +463,97 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 抓取弹窗 -->
|
||||
<el-dialog
|
||||
v-model="fetchDialogVisible"
|
||||
title="抓取数据"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div class="fetch-dialog-content">
|
||||
<el-form :model="fetchForm" label-width="70px" style="margin-bottom: 20px; display: flex">
|
||||
<el-form-item label="抓取链接">
|
||||
<el-input
|
||||
v-model="fetchForm.url"
|
||||
placeholder="请输入要抓取的链接"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleFetch" :loading="fetchLoading">抓取</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 抓取结果显示 -->
|
||||
<div v-if="fetchLoading" class="fetch-loading">
|
||||
<el-icon class="is-loading"><Loading /></el-icon>
|
||||
<span style="margin-left: 8px">正在抓取中...</span>
|
||||
</div>
|
||||
|
||||
<el-form v-else-if="fetchData" :model="fetchForm" label-width="100px" class="fetch-result-form">
|
||||
<ElRow :gutter="12">
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="产品名称">
|
||||
<el-input v-model="fetchForm.product_name" placeholder="请输入产品名称" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="车价(¥)">
|
||||
<el-input v-model="fetchForm.price" placeholder="请输入车价" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="车源地">
|
||||
<el-input v-model="fetchForm.source_place" placeholder="请输入车源地" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="上牌时间">
|
||||
<el-input v-model="fetchForm.plate_time" placeholder="请输入上牌时间" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="排量">
|
||||
<el-input v-model="fetchForm.displacement" placeholder="请输入排量" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="里程(Km)">
|
||||
<el-input v-model="fetchForm.mileage" placeholder="请输入里程" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="马力">
|
||||
<el-input v-model="fetchForm.power" placeholder="请输入马力" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<el-form-item label="车身颜色">
|
||||
<el-input v-model="fetchForm.body_color" placeholder="请输入车身颜色" />
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="24" :lg="24">
|
||||
<el-form-item label="车况介绍">
|
||||
<el-input
|
||||
v-model="fetchForm.condition_desc"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入车况介绍"
|
||||
/>
|
||||
</el-form-item>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="fetchDialogVisible = false">关 闭</el-button>
|
||||
<el-button type="primary" @click="handleFetchConfirm" :disabled="!fetchData">确认添加</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 图片预览组件 -->
|
||||
<ElImageViewer
|
||||
v-if="showImageViewer1"
|
||||
@@ -475,11 +577,13 @@
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElLoading,
|
||||
ElRow,
|
||||
ElCol,
|
||||
type FormInstance,
|
||||
type FormRules,
|
||||
type UploadFile
|
||||
} from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { Plus, Loading, User, ArrowRight } from '@element-plus/icons-vue'
|
||||
import { manageService } from '@/api/adminApi'
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
@@ -545,7 +649,8 @@
|
||||
body_color: string
|
||||
condition_desc: string
|
||||
mileage: string
|
||||
images: string[]
|
||||
images: string[] // 用于显示(images_pull)
|
||||
original_images: string[] // 用于保存提交(原始 images)
|
||||
intro_video: string[]
|
||||
attachment: { name: string; src: string }[]
|
||||
faqs: FAQItem[]
|
||||
@@ -571,6 +676,7 @@
|
||||
condition_desc: '',
|
||||
mileage: '',
|
||||
images: [],
|
||||
original_images: [],
|
||||
intro_video: [],
|
||||
attachment: [],
|
||||
faqs: [{ question: '', answer: '' }],
|
||||
@@ -647,9 +753,14 @@
|
||||
const showImageViewer1 = ref(false)
|
||||
const viewerIndex = ref(0)
|
||||
const currentPdfFiles = ref('')
|
||||
const imgList = computed(() =>
|
||||
parsePreviewList(detailData.value?.images_pull || detailData.value?.images || [])
|
||||
)
|
||||
const fetchImgList = ref<string[]>([])
|
||||
const imgList = computed(() => {
|
||||
// 如果抓取弹窗打开且有图片,显示抓取的图片
|
||||
if (fetchDialogVisible.value && fetchImgList.value.length > 0) {
|
||||
return fetchImgList.value
|
||||
}
|
||||
return parsePreviewList(detailData.value?.images_pull || detailData.value?.images || [])
|
||||
})
|
||||
|
||||
const handleAvatarClick1 = (index: string) => {
|
||||
if (index !== null && index !== undefined) {
|
||||
@@ -688,7 +799,10 @@
|
||||
const statusMap: Record<number, string> = {
|
||||
0: '待审核',
|
||||
1: '审核通过',
|
||||
2: '审核拒绝'
|
||||
2: '审核拒绝',
|
||||
3: '推送中',
|
||||
4: '推送成功',
|
||||
5: '推送失败'
|
||||
}
|
||||
return statusMap[status] || '未知'
|
||||
}
|
||||
@@ -697,7 +811,10 @@
|
||||
const colorMap: Record<number, 'success' | 'warning' | 'danger' | 'info'> = {
|
||||
0: 'warning',
|
||||
1: 'success',
|
||||
2: 'danger'
|
||||
2: 'danger',
|
||||
3: 'info',
|
||||
4: 'success',
|
||||
5: 'danger'
|
||||
}
|
||||
return colorMap[status] || 'info'
|
||||
}
|
||||
@@ -709,7 +826,10 @@
|
||||
const colorMap: Record<number, 'success' | 'warning' | 'danger' | 'info'> = {
|
||||
0: 'warning',
|
||||
1: 'success',
|
||||
2: 'danger'
|
||||
2: 'danger',
|
||||
3: 'info',
|
||||
4: 'success',
|
||||
5: 'danger'
|
||||
}
|
||||
return colorMap[status] || 'info'
|
||||
}
|
||||
@@ -792,15 +912,19 @@
|
||||
editForm.condition_desc = res.condition_desc || ''
|
||||
editForm.mileage = res.mileage || ''
|
||||
|
||||
// 处理图片
|
||||
const images = parsePreviewList(res.images_pull || res.images || [])
|
||||
editForm.images = images
|
||||
editImageFileList.value = images.map((url, idx) => ({
|
||||
// 处理图片:images_pull 用于显示,images 用于保存
|
||||
const displayImages = parsePreviewList(res.images_pull || res.images || [])
|
||||
const saveImages = parsePreviewList(res.images || [])
|
||||
|
||||
editForm.images = displayImages // 用于显示
|
||||
editForm.original_images = saveImages // 用于保存提交
|
||||
|
||||
editImageFileList.value = displayImages.map((url, idx) => ({
|
||||
name: `image_${idx}`,
|
||||
url,
|
||||
status: 'success' as const,
|
||||
uid: idx,
|
||||
response: { file_url: url, file_name: url }
|
||||
response: { file_url: url, file_name: saveImages[idx] || url }
|
||||
}))
|
||||
|
||||
// 处理视频
|
||||
@@ -965,6 +1089,7 @@
|
||||
|
||||
if (fileName && !editForm.images.includes(fileName)) {
|
||||
editForm.images.push(fileName)
|
||||
editForm.original_images.push(fileName)
|
||||
}
|
||||
editImageFileList.value = fileList as UploadFileWithResponse[]
|
||||
loadingInstance.value?.close()
|
||||
@@ -975,7 +1100,10 @@
|
||||
const fileName = resp?.file_name || resp?.data?.file_name || ''
|
||||
if (fileName) {
|
||||
const idx = editForm.images.indexOf(fileName)
|
||||
if (idx > -1) editForm.images.splice(idx, 1)
|
||||
if (idx > -1) {
|
||||
editForm.images.splice(idx, 1)
|
||||
editForm.original_images.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
editImageFileList.value = fileList as UploadFileWithResponse[]
|
||||
}
|
||||
@@ -1076,7 +1204,7 @@
|
||||
body_color: editForm.body_color,
|
||||
condition_desc: editForm.condition_desc,
|
||||
mileage: editForm.mileage,
|
||||
images: editForm.images.map((s) => String(s || '').trim()).filter(Boolean).join(','),
|
||||
images: editForm.original_images.map((s) => String(s || '').trim()).filter(Boolean).join(','),
|
||||
intro_video: editForm.intro_video.map((s) => String(s || '').trim()).filter(Boolean).join(','),
|
||||
attachment: editForm.attachment,
|
||||
faqs: validFaqs.length > 0 ? validFaqs : undefined,
|
||||
@@ -1179,6 +1307,129 @@
|
||||
getWorkList()
|
||||
}
|
||||
|
||||
// 抓取相关
|
||||
const fetchDialogVisible = ref(false)
|
||||
const fetchForm = reactive({
|
||||
url: '',
|
||||
product_name: '',
|
||||
price: '',
|
||||
source_place: '',
|
||||
plate_time: '',
|
||||
displacement: '',
|
||||
power: '',
|
||||
body_color: '',
|
||||
condition_desc: '',
|
||||
mileage: ''
|
||||
})
|
||||
const fetchLoading = ref(false)
|
||||
const fetchData = ref<any>(null)
|
||||
|
||||
// 打开抓取弹窗
|
||||
const fetchpublishfn = () => {
|
||||
fetchDialogVisible.value = true
|
||||
fetchForm.url = ''
|
||||
fetchForm.product_name = ''
|
||||
fetchForm.price = ''
|
||||
fetchForm.source_place = ''
|
||||
fetchForm.plate_time = ''
|
||||
fetchForm.displacement = ''
|
||||
fetchForm.power = ''
|
||||
fetchForm.body_color = ''
|
||||
fetchForm.condition_desc = ''
|
||||
fetchForm.mileage = ''
|
||||
fetchData.value = null
|
||||
fetchImgList.value = []
|
||||
}
|
||||
|
||||
// 执行抓取
|
||||
const handleFetch = async () => {
|
||||
if (!fetchForm.url || !fetchForm.url.trim()) {
|
||||
ElMessage.warning('请输入抓取链接')
|
||||
return
|
||||
}
|
||||
|
||||
fetchLoading.value = true
|
||||
fetchData.value = null
|
||||
|
||||
try {
|
||||
const res: any = await request.post({
|
||||
url: '/common/usedcardetail/crawl',
|
||||
params: { url: fetchForm.url.trim() }
|
||||
})
|
||||
fetchData.value = res?.data || res || {}
|
||||
|
||||
// 填充表单数据
|
||||
fetchForm.product_name = fetchData.value.product_name || ''
|
||||
fetchForm.price = fetchData.value.price || ''
|
||||
fetchForm.source_place = fetchData.value.source_place || ''
|
||||
fetchForm.plate_time = fetchData.value.plate_time || ''
|
||||
fetchForm.displacement = fetchData.value.displacement || ''
|
||||
fetchForm.power = fetchData.value.power || ''
|
||||
fetchForm.body_color = fetchData.value.body_color || ''
|
||||
fetchForm.condition_desc = fetchData.value.condition_desc || ''
|
||||
fetchForm.mileage = fetchData.value.mileage || ''
|
||||
|
||||
// 处理图片列表用于预览
|
||||
fetchImgList.value = parsePreviewList(fetchData.value.image_pull || fetchData.value.image || [])
|
||||
ElMessage.success(res?.message || '抓取成功')
|
||||
console.log('抓取接口返回数据:', fetchData.value)
|
||||
} catch (error: any) {
|
||||
console.error('抓取失败:', error)
|
||||
fetchData.value = null
|
||||
ElMessage.error(error?.message || '抓取失败,请稍后重试')
|
||||
} finally {
|
||||
fetchLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 确认添加抓取的数据
|
||||
// 确认添加抓取的数据
|
||||
const handleFetchConfirm = async () => {
|
||||
// 合并抓取接口返回的原始数据和用户修改的数据
|
||||
const formData = {
|
||||
...fetchData.value, // 保存所有抓取接口返回的原始数据
|
||||
// 用表单中修改的值替换对应字段
|
||||
product_name: fetchForm.product_name,
|
||||
price: fetchForm.price,
|
||||
source_place: fetchForm.source_place,
|
||||
plate_time: fetchForm.plate_time,
|
||||
displacement: fetchForm.displacement,
|
||||
power: fetchForm.power,
|
||||
body_color: fetchForm.body_color,
|
||||
condition_desc: fetchForm.condition_desc,
|
||||
mileage: fetchForm.mileage
|
||||
}
|
||||
console.log('保存抓取数据:', formData)
|
||||
|
||||
try {
|
||||
const res: any = await request.post({
|
||||
url: '/common/usedcardetail/crawl/store',
|
||||
params: formData
|
||||
})
|
||||
ElMessage.success(res?.message)
|
||||
fetchDialogVisible.value = false
|
||||
getWorkList() // 刷新列表
|
||||
} catch (error: any) {
|
||||
console.error('保存抓取数据失败:', error)
|
||||
ElMessage.error(error?.message || '保存失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 抓取图片预览点击
|
||||
const handleFetchAvatarClick = (index: number) => {
|
||||
viewerIndex.value = index
|
||||
showImageViewer.value = true
|
||||
}
|
||||
|
||||
// 格式化年月(如:2024年01月 -> 2024-01-01)
|
||||
function formatCnYearMonth(str: string) {
|
||||
const match = str.match(/(\d{4})年(\d{1,2})月/)
|
||||
if (!match) return str
|
||||
const year = match[1]
|
||||
const month = match[2].padStart(2, '0')
|
||||
return `${year}-${month}-01`
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getWorkList()
|
||||
})
|
||||
@@ -1470,4 +1721,35 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 抓取弹窗样式
|
||||
.fetch-dialog-content {
|
||||
.fetch-loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px 0;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.fetch-result {
|
||||
.thumb-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.avatarimg {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user