优化
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const source = readFileSync(resolve(process.cwd(), 'src/modules/trucking/components/TruckAttachmentDialog.vue'), 'utf8')
|
||||
|
||||
describe('TruckAttachmentDialog interaction governance', () => {
|
||||
it('shows existing attachments without exposing file-service internals', () => {
|
||||
expect(source).toContain('预约附件')
|
||||
expect(source).toContain('attachmentTypeLabel(item.attachmentType)')
|
||||
expect(source).not.toContain('文件 ID')
|
||||
expect(source).not.toContain('item.objectKey')
|
||||
})
|
||||
|
||||
it('hides the unavailable manual reference flow but keeps deletion', () => {
|
||||
expect(source).not.toContain('referenceTruckAppointmentAttachment')
|
||||
expect(source).not.toContain('输入文件服务 ID')
|
||||
expect(source).toContain('deleteTruckAppointmentAttachment')
|
||||
expect(source).toContain('<Trash2 :size="15" />删除')
|
||||
})
|
||||
})
|
||||
@@ -1,28 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { deleteTruckAppointmentAttachment, referenceTruckAppointmentAttachment } from '../api/platformTrucking'
|
||||
import { Trash2 } from '@lucide/vue'
|
||||
import { deleteTruckAppointmentAttachment } from '../api/platformTrucking'
|
||||
import type { TruckAttachmentReference } from '../types'
|
||||
const props = defineProps<{ modelValue: boolean; appointmentId?: string; attachments: TruckAttachmentReference[]; canManage?: boolean }>()
|
||||
const emit = defineEmits<{ 'update:modelValue': [boolean]; changed: [] }>()
|
||||
const fileId = ref(''); const fileName = ref(''); const busy = ref(false)
|
||||
async function add() { if (!props.appointmentId || !/^\d+$/.test(fileId.value)) return; busy.value = true; try { await referenceTruckAppointmentAttachment(props.appointmentId, { fileId: fileId.value, fileName: fileName.value || null }); fileId.value = ''; fileName.value = ''; emit('changed'); ElMessage.success('附件引用已添加') } catch { ElMessage.error('附件引用失败') } finally { busy.value = false } }
|
||||
const busy = ref(false)
|
||||
const attachmentTypeLabels: Record<string, string> = { DISPATCH_ORDER: '派车单', DRIVER_DOCUMENT: '司机证件', VEHICLE_DOCUMENT: '车辆证件', OTHER: '其他附件' }
|
||||
function attachmentTypeLabel(value: string | null | undefined) { return value ? attachmentTypeLabels[value] || '业务附件' : '业务附件' }
|
||||
async function remove(item: TruckAttachmentReference) { if (!props.appointmentId || !item.id) return; await ElMessageBox.confirm('确认删除该附件引用?', '删除确认', { type: 'warning' }); busy.value = true; try { await deleteTruckAppointmentAttachment(props.appointmentId, item.id); emit('changed'); ElMessage.success('附件引用已删除') } catch { ElMessage.error('删除失败') } finally { busy.value = false } }
|
||||
</script>
|
||||
<template>
|
||||
<el-dialog :model-value="props.modelValue" title="附件引用" width="min(640px, 94vw)" @update:model-value="emit('update:modelValue', $event)">
|
||||
<el-alert type="info" :closable="false" title="仅允许引用文件服务中属于当前预约和客户范围的文件,后端会校验归属与业务类型。" />
|
||||
<el-form v-if="props.appointmentId && props.canManage" inline @submit.prevent="add"><el-form-item label="文件 ID"><el-input v-model="fileId" placeholder="输入文件服务 ID" /></el-form-item><el-form-item label="文件名"><el-input v-model="fileName" placeholder="可选" /></el-form-item><el-button type="primary" :loading="busy" @click="add">添加引用</el-button></el-form>
|
||||
<el-empty v-if="attachments.length === 0" description="暂无真实附件引用" :image-size="72" />
|
||||
<el-dialog :model-value="props.modelValue" title="预约附件" width="min(640px, 94vw)" @update:model-value="emit('update:modelValue', $event)">
|
||||
<el-empty v-if="attachments.length === 0" description="暂无预约附件" :image-size="72" />
|
||||
<div v-for="item in attachments" :key="item.fileId" class="attachment-row">
|
||||
<div><strong>{{ item.fileName || '未命名文件' }}</strong><small>文件 ID:{{ item.fileId }} · {{ item.attachmentType || '业务附件' }}</small></div>
|
||||
<code v-if="item.objectKey">{{ item.objectKey }}</code>
|
||||
<el-button v-if="props.appointmentId && props.canManage && item.id" text type="danger" :loading="busy" @click="remove(item)">删除</el-button>
|
||||
<div><strong>{{ item.fileName || '未命名文件' }}</strong><small>{{ attachmentTypeLabel(item.attachmentType) }}{{ item.uploadedAt ? ` · ${item.uploadedAt}` : '' }}</small></div>
|
||||
<el-button v-if="props.appointmentId && props.canManage && item.id" text type="danger" :loading="busy" @click="remove(item)"><Trash2 :size="15" />删除</el-button>
|
||||
</div>
|
||||
<template #footer><el-button type="primary" @click="emit('update:modelValue', false)">关闭</el-button></template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<style scoped>
|
||||
.attachment-row { display:flex; justify-content:space-between; gap:12px; margin:14px 0; padding:12px; border:1px solid var(--el-border-color-lighter); border-radius:6px; overflow-wrap:anywhere; }.attachment-row small { display:block; margin-top:4px; color:var(--el-text-color-secondary); }.attachment-row code { color:var(--el-text-color-secondary); font-size:12px; }
|
||||
.attachment-row { display:flex; justify-content:space-between; gap:12px; margin:14px 0; padding:12px; border:1px solid var(--el-border-color-lighter); border-radius:6px; overflow-wrap:anywhere; }.attachment-row small { display:block; margin-top:4px; color:var(--el-text-color-secondary); }
|
||||
@media (max-width: 560px) { .attachment-row { flex-direction:column; } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user