客户图片预览
This commit is contained in:
@@ -89,50 +89,31 @@ export function updateCustomer(data) {
|
||||
})
|
||||
}
|
||||
|
||||
function isLikelyBackendOrProxyAsset(absoluteUrl) {
|
||||
try {
|
||||
const p = new URL(absoluteUrl).pathname || ''
|
||||
return p.startsWith('/api/') || p.includes('/customerManagement')
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按列表/详情中保存的地址拉取图片:相对路径或指向本系统接口的完整 URL 走 axios(含 Token、业务头,经 dev 代理);
|
||||
* 其余完整 URL(如公网图床、MinIO 外链)返回 { useDirect: true, url },由前端用 img 直链展示。
|
||||
* 预览客户照片(后端从 MinIO 拉流)。
|
||||
* 方式一:传 url(与 uploadPhoto 返回的 MinIO 访问 URL 一致)。
|
||||
* 方式二:传 id + photoType(front | side | life),由后端读库再拉 MinIO。
|
||||
* @param {{ url?: string, id?: string|number, photoType?: 'front'|'side'|'life' }}=} params
|
||||
*/
|
||||
export function loadCustomerPhotoForDisplay(storedUrl) {
|
||||
if (storedUrl == null || String(storedUrl).trim() === '') {
|
||||
return Promise.reject(new Error('EMPTY_URL'))
|
||||
export function previewCustomerPhoto(params) {
|
||||
const p = params && typeof params === 'object' ? params : {}
|
||||
const query = {}
|
||||
if (p.url != null && String(p.url).trim() !== '') {
|
||||
query.url = String(p.url).trim()
|
||||
}
|
||||
const raw = String(storedUrl).trim()
|
||||
const isAbs = /^https?:\/\//i.test(raw)
|
||||
if (isAbs && !isLikelyBackendOrProxyAsset(raw)) {
|
||||
return Promise.resolve({ useDirect: true, url: raw })
|
||||
if (p.id != null && String(p.id).trim() !== '') {
|
||||
query.id = String(p.id).trim()
|
||||
}
|
||||
|
||||
let path = raw
|
||||
if (isAbs) {
|
||||
try {
|
||||
const u = new URL(raw)
|
||||
path = u.pathname + (u.search || '')
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
if (!path.startsWith('/')) {
|
||||
path = `/${path}`
|
||||
}
|
||||
if (path.startsWith('/api/')) {
|
||||
path = path.slice(4)
|
||||
if (p.photoType != null && String(p.photoType).trim() !== '') {
|
||||
query.photoType = String(p.photoType).trim()
|
||||
}
|
||||
return request({
|
||||
url: path,
|
||||
url: '/customerManagement/previewPhoto',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob',
|
||||
timeout: 120000
|
||||
}).then(blob => ({ useDirect: false, blob }))
|
||||
})
|
||||
}
|
||||
|
||||
/** 客户照片上传至 MinIO;id 可选,有则作为 query 传入;成功时响应 data 中含 url */
|
||||
|
||||
@@ -578,7 +578,7 @@ import {
|
||||
addCustomer,
|
||||
updateCustomer,
|
||||
uploadCustomerPhoto,
|
||||
loadCustomerPhotoForDisplay,
|
||||
previewCustomerPhoto,
|
||||
deleteCustomer,
|
||||
batchDeleteCustomer,
|
||||
exportCustomerFlow,
|
||||
@@ -989,16 +989,13 @@ export default {
|
||||
})
|
||||
if (!kind) return
|
||||
|
||||
const fieldMap = { front: 'frontPhotoUrl', side: 'sidePhotoUrl', life: 'lifePhotoUrl' }
|
||||
const titleMap = { front: '正面照片', side: '侧面照片', life: '生活照片' }
|
||||
const field = fieldMap[kind]
|
||||
const stored = field && row[field] ? String(row[field]).trim() : ''
|
||||
if (!stored) {
|
||||
this.$message.warning(`该客户未设置${titleMap[kind] || '该类型'}地址`)
|
||||
if (row.id == null || String(row.id).trim() === '') {
|
||||
this.$message.warning('无法预览:缺少客户ID')
|
||||
return
|
||||
}
|
||||
|
||||
this.photoPreviewTitle = `${row.customerName || '客户'} — ${titleMap[kind]}`
|
||||
this.photoPreviewTitle = `${row.customerName || '客户'} — ${titleMap[kind] || ''}`
|
||||
this.photoPreviewLoadError = false
|
||||
this.revokePhotoPreviewObjectUrl()
|
||||
this.photoPreviewSrc = ''
|
||||
@@ -1006,35 +1003,38 @@ export default {
|
||||
this.photoPreviewLoading = true
|
||||
|
||||
try {
|
||||
const result = await loadCustomerPhotoForDisplay(stored)
|
||||
if (result.useDirect) {
|
||||
this.photoPreviewSrc = result.url
|
||||
} else {
|
||||
const blob = result.blob
|
||||
if (!(blob instanceof Blob) || blob.size === 0) {
|
||||
this.$message.error('未获取到图片数据')
|
||||
return
|
||||
}
|
||||
const ct = (blob.type || '').toLowerCase()
|
||||
if (ct.includes('json') || ct === 'text/plain') {
|
||||
const text = await blob.text()
|
||||
let msg = '加载失败'
|
||||
try {
|
||||
const j = JSON.parse(text)
|
||||
msg = j.message || j.msg || msg
|
||||
} catch (e) {
|
||||
if (text) msg = text.slice(0, 200)
|
||||
}
|
||||
this.$message.error(msg)
|
||||
this.photoPreviewVisible = false
|
||||
return
|
||||
}
|
||||
this.photoPreviewObjectUrl = URL.createObjectURL(blob)
|
||||
this.photoPreviewSrc = this.photoPreviewObjectUrl
|
||||
const blob = await previewCustomerPhoto({ id: row.id, photoType: kind })
|
||||
if (!(blob instanceof Blob) || blob.size === 0) {
|
||||
this.$message.error('未获取到图片数据')
|
||||
this.photoPreviewVisible = false
|
||||
return
|
||||
}
|
||||
const ct = (blob.type || '').toLowerCase()
|
||||
if (ct.includes('json') || ct === 'text/plain') {
|
||||
const text = await blob.text()
|
||||
let msg = '加载失败'
|
||||
try {
|
||||
const j = JSON.parse(text)
|
||||
msg = j.message || j.msg || msg
|
||||
} catch (e) {
|
||||
if (text) msg = text.slice(0, 200)
|
||||
}
|
||||
this.$message.error(msg)
|
||||
this.photoPreviewVisible = false
|
||||
return
|
||||
}
|
||||
this.photoPreviewObjectUrl = URL.createObjectURL(blob)
|
||||
this.photoPreviewSrc = this.photoPreviewObjectUrl
|
||||
} catch (err) {
|
||||
console.error('加载客户照片失败:', err)
|
||||
this.$message.error((err && err.message) || '加载照片失败,请稍后重试')
|
||||
const status = err && err.response && err.response.status
|
||||
if (status === 404) {
|
||||
this.$message.warning('未找到该照片或客户未上传此类型照片')
|
||||
} else if (status === 400) {
|
||||
this.$message.warning('请求参数无效')
|
||||
} else {
|
||||
this.$message.error((err && err.message) || '加载照片失败,请稍后重试')
|
||||
}
|
||||
this.photoPreviewVisible = false
|
||||
} finally {
|
||||
this.photoPreviewLoading = false
|
||||
|
||||
Reference in New Issue
Block a user