diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..84c239d --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1 @@ +/media/* \ No newline at end of file diff --git a/frontend/src/api/material.js b/frontend/src/api/material.js index bed4164..03f8502 100644 --- a/frontend/src/api/material.js +++ b/frontend/src/api/material.js @@ -1,17 +1,4 @@ -import api from './client' - -const toFormData = (payload) => { - const form = new FormData() - Object.entries(payload).forEach(([key, value]) => { - if (value === undefined || value === null) return - if (Array.isArray(value)) { - form.append(key, JSON.stringify(value)) - return - } - form.append(key, value) - }) - return form -} +import api from './client' export const fetchMaterials = async (params) => { const { data } = await api.get('/material/', { params }) @@ -23,18 +10,21 @@ export const fetchMaterialDetail = async (id) => { return data } -export const createMaterial = async (payload, withFile = false) => { - const dataPayload = withFile ? toFormData(payload) : payload - const { data } = await api.post('/material/', dataPayload, { - headers: withFile ? { 'Content-Type': 'multipart/form-data' } : undefined - }) +export const createMaterial = async (payload) => { + const { data } = await api.post('/material/', payload) return data } -export const updateMaterial = async (id, payload, withFile = false) => { - const dataPayload = withFile ? toFormData(payload) : payload - const { data } = await api.put(`/material/${id}/`, dataPayload, { - headers: withFile ? { 'Content-Type': 'multipart/form-data' } : undefined +export const updateMaterial = async (id, payload) => { + const { data } = await api.put(`/material/${id}/`, payload) + return data +} + +export const uploadImage = async (file) => { + const formData = new FormData() + formData.append('file', file) + const { data } = await api.post('/upload/', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, }) return data } diff --git a/frontend/src/views/MaterialManage.vue b/frontend/src/views/MaterialManage.vue index e1e8a24..9d0ec6e 100644 --- a/frontend/src/views/MaterialManage.vue +++ b/frontend/src/views/MaterialManage.vue @@ -105,11 +105,12 @@ - 选择图片 + {{ uploading ? '上传中...' : '选择图片' }}
预览 @@ -168,7 +169,7 @@ import { ref, reactive, onMounted } from 'vue' import { useRouter } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import { useAuth } from '@/store/auth' -import { fetchMaterials, fetchMaterialDetail, createMaterial, updateMaterial, deleteMaterial, submitMaterial, approveMaterial, rejectMaterial, fetchMaterialChoices } from '@/api/material' +import { fetchMaterials, fetchMaterialDetail, createMaterial, updateMaterial, deleteMaterial, submitMaterial, approveMaterial, rejectMaterial, fetchMaterialChoices, uploadImage } from '@/api/material' import { fetchCategories, fetchSubcategories } from '@/api/category' import { fetchFactorySimple } from '@/api/factory' @@ -186,7 +187,7 @@ const dialogVisible = ref(false) const dialogTitle = ref('') const isEdit = ref(false) const currentId = ref(null) -const fileRef = ref(null) +const uploading = ref(false) const filters = reactive({ name: '', @@ -312,7 +313,6 @@ const resetForm = () => { limit_condition: '', factory: null }) - fileRef.value = null } const onCategoryChange = async (val, resetSub = true) => { @@ -352,22 +352,31 @@ const openEdit = async (row) => { dialogVisible.value = true } -const onFileChange = (file) => { - fileRef.value = file.raw - form.brochure = file.raw +const handleUpload = async (options) => { + uploading.value = true + try { + const result = await uploadImage(options.file) + form.brochure = result.path + form.brochure_url = result.url + ElMessage.success('图片上传成功') + } catch { + ElMessage.error('图片上传失败') + } finally { + uploading.value = false + } } const onSave = async () => { try { const payload = { ...form } - const withFile = !!fileRef.value + delete payload.brochure_url if (!isAdmin.value) { delete payload.factory } if (isEdit.value) { - await updateMaterial(currentId.value, payload, withFile) + await updateMaterial(currentId.value, payload) } else { - await createMaterial(payload, withFile) + await createMaterial(payload) } ElMessage.success('保存成功') dialogVisible.value = false