Oroqen-Manage/src/views/oroqen/inheritor/components/OroqenInheritorModal.vue
2025-08-10 10:09:34 +08:00

265 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref, reactive } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from '../OroqenInheritor.data';
import { saveOrUpdate } from '../OroqenInheritor.api';
import { useMessage } from '/@/hooks/web/useMessage';
import { getDateByPicker } from '/@/utils';
import { uploadFile } from '/@/api/common/api';
import { defHttp } from '/@/utils/http/axios';
const { createMessage } = useMessage();
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const isDetail = ref(false);
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate, scrollToField }] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 }
});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, width: "800px" });
isUpdate.value = !!data?.isUpdate;
isDetail.value = data?.mode === 'detail';
if (unref(isUpdate)) {
//表单赋值
await setFieldsValue({
...data.record,
});
}
// 详情模式时禁用整个表单
setProps({ disabled: unref(isDetail) });
});
//日期个性化选择
const fieldPickers = reactive({});
const getTitle = computed(() => (!unref(isUpdate) ? '新增' : unref(isDetail) ? '详情' : '编辑'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
console.log('表单验证通过,提交数据:', values);
// 预处理日期数据
changeDateValue(values);
setModalProps({ confirmLoading: true });
// 处理文件上传
await handleFileUploads(values);
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} catch (error) {
console.error('表单提交失败:', error);
// 处理表单验证错误
if (error && error.errorFields) {
console.error('表单验证错误字段:', error.errorFields);
const firstField = error.errorFields[0];
if (firstField) {
console.error('第一个错误字段:', firstField);
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
// 显示具体的验证错误信息
const fieldName = firstField.name[0] || firstField.name;
const errorMessage = firstField.errors?.[0] || '字段验证失败';
createMessage.error(`${fieldName}: ${errorMessage}`);
}
} else if (error && error.message) {
createMessage.error(error.message);
} else if (typeof error === 'string') {
createMessage.error(error);
} else {
createMessage.error('操作失败,请重试');
}
// 不要抛出错误避免未处理的Promise拒绝
return;
} finally {
setModalProps({ confirmLoading: false });
}
}
/**
* 处理文件上传
* @param formData 表单数据
*/
async function handleFileUploads(formData) {
console.log('开始处理文件上传,表单数据:', formData);
try {
// 传承人模块只有一个头像字段
const fileFields = ['avatar'];
for (const field of fileFields) {
// 如果字段有值且包含blob URL说明有新文件需要上传
if (formData[field] && typeof formData[field] === 'string') {
const fieldValue = formData[field];
const filePaths = fieldValue.split(',').filter(path => path.trim());
for (const path of filePaths) {
if (path.startsWith('blob:')) {
// 这是一个需要处理的blob文件
console.log(`发现需要处理的blob文件: ${field} -> ${path}`);
try {
const uploadedPath = await uploadBlobFile(path, field);
// 替换表单数据中的blob URL为服务器路径
formData[field] = formData[field].replace(path, uploadedPath);
console.log(`文件上传成功,更新路径: ${path} -> ${uploadedPath}`);
} catch (error) {
console.error(`上传文件失败 (${field}):`, error);
createMessage.error(`上传文件失败: ${error.message}`);
throw error;
}
}
}
}
}
console.log('所有文件处理完成,最终表单数据:', formData);
} catch (error) {
console.error('文件上传处理失败:', error);
throw error;
}
}
/**
* 上传blob文件
* @param filePath 文件路径或blob URL
* @param fieldName 字段名
* @returns 上传后的文件路径
*/
async function uploadBlobFile(filePath, fieldName) {
try {
console.log('处理文件:', filePath, '字段:', fieldName);
let file;
let fileName;
if (filePath.startsWith('blob:')) {
// 从blob URL获取文件
console.log('从blob URL获取文件');
const response = await fetch(filePath);
const blob = await response.blob();
fileName = `${fieldName}_${Date.now()}.${blob.type.split('/')[1] || 'jpg'}`;
file = new File([blob], fileName, { type: blob.type });
console.log('从blob URL创建的文件:', file);
} else {
console.log('非blob URL可能是已存在的文件路径');
return filePath; // 返回原路径,可能是已存在的文件
}
if (!file) {
throw new Error('无法获取文件对象');
}
// 确定业务路径 - 传承人模块只有头像
let bizPath = 'inheritor/avatar';
// 上传文件参数
const uploadParams = {
file: file,
name: 'file',
filename: fileName,
data: {
biz: bizPath
}
};
console.log('上传参数:', uploadParams);
console.log('上传参数详细信息:');
console.log('- file对象:', file);
console.log('- file.name:', file.name);
console.log('- file.size:', file.size);
console.log('- file.type:', file.type);
console.log('- bizPath:', bizPath);
// 上传文件
const uploadResult = await defHttp.uploadFile(
{
url: '/sys/common/upload',
timeout: 30000
},
uploadParams,
{
isReturnResponse: true
}
);
console.log('上传结果完整信息:', uploadResult);
console.log('上传结果类型:', typeof uploadResult);
// 处理可能的undefined情况
if (!uploadResult) {
console.error('上传结果为空或undefined');
throw new Error('上传失败:服务器未返回结果');
}
console.log('上传结果success字段:', uploadResult?.success);
console.log('上传结果message字段:', uploadResult?.message);
console.log('上传结果code字段:', uploadResult?.code);
// 检查上传结果 - 兼容不同的返回格式
const isSuccess = uploadResult && (
uploadResult.success === true ||
uploadResult.code === 0 ||
uploadResult.code === 200
);
if (isSuccess) {
const filePath = uploadResult.message || uploadResult.result || uploadResult.data;
console.log('上传成功,文件路径:', filePath);
return filePath;
} else {
console.error('上传失败详细信息:', {
result: uploadResult,
success: uploadResult?.success,
message: uploadResult?.message,
code: uploadResult?.code,
error: uploadResult?.error
});
throw new Error(uploadResult?.message || uploadResult?.error || '上传失败,请检查网络连接或联系管理员');
}
} catch (error) {
console.error('上传文件失败:', error);
throw error;
}
}
/**
* 处理日期值
* @param formData 表单数据
*/
const changeDateValue = (formData) => {
if (formData && fieldPickers) {
for (let key in fieldPickers) {
if (formData[key]) {
formData[key] = getDateByPicker(formData[key], fieldPickers[key]);
}
}
}
};
</script>