<template>
|
<view class="file-page">
|
<PageHeader title="附件管理" @back="goBack" />
|
|
<view class="file-list">
|
<view v-if="files.length > 0">
|
<view v-for="(f, idx) in files" :key="f.id || idx" class="file-item">
|
<view class="file-info">
|
<text class="file-name">{{ f.name }}</text>
|
</view>
|
<view class="file-actions">
|
<view class="btn-link" @click="previewFile(f)">预览</view>
|
<view class="btn-link danger" @click="confirmDelete(f)">删除</view>
|
</view>
|
</view>
|
</view>
|
<view v-else class="empty">暂无附件</view>
|
</view>
|
|
<view class="upload-bar">
|
<view class="btn-upload" @click="chooseFile">上传附件</view>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref } from 'vue'
|
import { onLoad, onShow } from '@dcloudio/uni-app'
|
import PageHeader from '@/components/PageHeader.vue'
|
import config from '@/config'
|
import { getToken } from '@/utils/auth'
|
import { qualityInspectFileAdd, qualityInspectFileDel, qualityInspectFileListPage } from '@/api/qualityManagement/qualityInspectFile.js'
|
|
const inspectId = ref('')
|
const files = ref([])
|
|
const getList = () => {
|
if (!inspectId.value) return
|
qualityInspectFileListPage({ inspectId: inspectId.value, current: 1, size: 200 })
|
.then(res => {
|
files.value = res?.data?.records || []
|
})
|
.catch(() => { files.value = [] })
|
}
|
|
const chooseFile = () => {
|
if (!inspectId.value) {
|
uni.showToast({ title: '缺少检验记录ID', icon: 'none' })
|
return
|
}
|
uni.chooseFile({
|
count: 1,
|
success: (res) => {
|
const path = res?.tempFiles?.[0]?.path
|
const name = res?.tempFiles?.[0]?.name
|
if (!path) return
|
uploadOne(path, name)
|
}
|
})
|
}
|
|
const uploadOne = (filePath, originalName) => {
|
const token = getToken()
|
if (!token) {
|
uni.showToast({ title: '未登录', icon: 'none' })
|
return
|
}
|
uni.showLoading({ title: '上传中...', mask: true })
|
uni.uploadFile({
|
url: config.baseUrl + '/file/upload',
|
filePath,
|
name: 'file',
|
header: { Authorization: 'Bearer ' + token },
|
success: (res) => {
|
uni.hideLoading()
|
try {
|
const resp = JSON.parse(res.data || '{}')
|
if (resp.code !== 200) throw new Error('upload fail')
|
const fileRow = {
|
inspectId: inspectId.value,
|
name: resp.data?.originalName || originalName || '附件',
|
url: resp.data?.tempPath
|
}
|
qualityInspectFileAdd(fileRow).then(() => {
|
uni.showToast({ title: '上传成功', icon: 'success' })
|
getList()
|
})
|
} catch (e) {
|
uni.showToast({ title: '上传失败', icon: 'none' })
|
}
|
},
|
fail: () => {
|
uni.hideLoading()
|
uni.showToast({ title: '上传失败', icon: 'none' })
|
}
|
})
|
}
|
|
const previewFile = (f) => {
|
const url = f?.url
|
if (!url) return
|
// H5/APP 统一用外部打开
|
uni.navigateTo({
|
url: `/pages/inspectionUpload/filePreview?url=${encodeURIComponent(url)}`
|
})
|
}
|
|
const confirmDelete = (f) => {
|
if (!f?.id) return
|
uni.showModal({
|
title: '删除',
|
content: '确认删除该附件?',
|
success: (r) => {
|
if (!r.confirm) return
|
qualityInspectFileDel([f.id]).then(() => {
|
uni.showToast({ title: '删除成功', icon: 'success' })
|
getList()
|
})
|
}
|
})
|
}
|
|
onLoad((options) => {
|
inspectId.value = options?.id || ''
|
if (!inspectId.value) {
|
const cached = uni.getStorageSync('rawMaterialFilesCtx')
|
if (cached) {
|
try {
|
const payload = typeof cached === 'string' ? JSON.parse(cached) : cached
|
inspectId.value = payload?.id || ''
|
uni.removeStorageSync('rawMaterialFilesCtx')
|
} catch (e) {
|
uni.removeStorageSync('rawMaterialFilesCtx')
|
}
|
}
|
}
|
})
|
|
onShow(() => {
|
getList()
|
})
|
|
const goBack = () => uni.navigateBack()
|
</script>
|
|
<style lang="scss" scoped>
|
.file-page { min-height: 100vh; background: #f5f5f5; padding-bottom: 120rpx; }
|
.file-list { margin: 24rpx; background: #fff; border-radius: 16rpx; padding: 12rpx 24rpx; }
|
.file-item { padding: 20rpx 0; border-bottom: 1rpx solid #eee; display: flex; justify-content: space-between; align-items: center; gap: 16rpx; }
|
.file-item:last-child { border-bottom: 0; }
|
.file-name { font-size: 28rpx; color: #333; }
|
.file-actions { display: flex; gap: 20rpx; }
|
.btn-link { color: #2979ff; font-size: 26rpx; }
|
.btn-link.danger { color: #f56c6c; }
|
.empty { text-align: center; padding: 60rpx 0; color: #999; font-size: 28rpx; }
|
.upload-bar { position: fixed; left: 0; right: 0; bottom: 0; padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom)); background: #fff; box-shadow: 0 -4rpx 16rpx rgba(0,0,0,0.04); }
|
.btn-upload { height: 88rpx; border-radius: 999rpx; background: #2979ff; color: #fff; font-size: 30rpx; display: flex; align-items: center; justify-content: center; }
|
</style>
|