赛事上传素材

This commit is contained in:
马梓彭 2026-04-27 09:55:40 +08:00
parent 518e7d33a3
commit c3f8796c88
3 changed files with 198 additions and 28 deletions

View File

@ -96,7 +96,6 @@ export const usereventrecordMaterialPost = (registrationid, data) => {
* @param {File} data.File - 凭证图片 (单张)
* @param {number} data.PayAmount - 支付金额
* @param {string} data.PayTime - 支付时间 (ISO格式)
* @param {string} [data.TransactionId] - 交易流水号 (可选)
* @returns {Promise<{
* code: number,
* message: string,
@ -113,7 +112,6 @@ export const usereventrecordVoucherPost = (registrationid, data) => {
formData.append('File', data.File);
formData.append('PayAmount', data.PayAmount);
formData.append('PayTime', data.PayTime);
if (data.TransactionId) formData.append('TransactionId', data.TransactionId);
return http.post(`/usereventrecord/voucher/${registrationid}`, formData, {
headers: {

View File

@ -16,8 +16,10 @@
// https://www.wangeditor.com/v5/for-frame.html#vue3
import '@wangeditor/editor/dist/css/style.css';
import { reactive, shallowRef, watch, onBeforeUnmount } from 'vue';
import { IDomEditor } from '@wangeditor/editor';
import { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor';
import { Toolbar, Editor } from '@wangeditor/editor-for-vue';
import { ElMessage } from 'element-plus';
import http from '/@/utils/http';
// 定义父组件传过来的值
const props = defineProps({
@ -51,12 +53,63 @@ const props = defineProps({
// 定义子组件向父组件传值/事件
const emit = defineEmits(['update:getHtml', 'update:getText']);
// 定义变量内容
const editorRef = shallowRef();
const state = reactive({
editorConfig: {
placeholder: props.placeholder,
// 自定义上传图片
const customUploadImage = async (file: File, insertFn: (url: string, alt: string, href: string) => void) => {
// 检查文件类型
if (!file.type.startsWith('image/')) {
ElMessage.error('请上传图片类型的文件');
return;
}
// 检查文件大小(限制 5M)
const maxSize = 5 * 1024 * 1024;
if (file.size > maxSize) {
ElMessage.error('图片大小不能超过 5M');
return;
}
const formData = new FormData();
formData.append('file', file);
try {
const data = await http.instance.post(`/file/upload`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
if (data && data[0] && data[0].url) {
const url = data[0].url;
insertFn(url, file.name, url);
ElMessage.success('图片上传成功');
} else {
ElMessage.error('图片上传失败,未获取到有效URL');
}
} catch (error) {
console.error('上传图片失败', error);
ElMessage.error('图片上传失败,请重试');
}
};
// 定义编辑器配置
const editorConfig: Partial<IEditorConfig> = {
placeholder: props.placeholder,
MENU_CONF: {
uploadImage: {
customUpload: customUploadImage,
// 也可以使用 server 方式,但这里我们使用自定义上传
// server: '/api/file/upload',
// fieldName: 'file',
// maxFileSize: 5 * 1024 * 1024,
// allowedFileTypes: ['image/*'],
},
},
};
// 定义变量内容
const editorRef = shallowRef<IDomEditor>();
const state = reactive({
editorConfig,
editorVal: props.getHtml,
});

View File

@ -163,22 +163,40 @@
<el-dialog title="上传付款凭证" v-model="isShowVoucherDialog" width="650px" :close-on-click-modal="false">
<el-form ref="voucherFormRef" :model="voucherForm" :rules="voucherRules" label-width="120px">
<el-form-item label="支付金额" prop="PayAmount">
<el-input-number v-model="voucherForm.PayAmount" :min="0" style="width: 100%;" />
<el-input-number
v-model="voucherForm.PayAmount"
:min="0.01"
:precision="2"
:step="0.01"
@change="handlePayAmountChange"
style="width: 100%;"
placeholder="请输入支付金额"
/>
</el-form-item>
<el-form-item label="支付时间" prop="PayTime">
<el-date-picker v-model="voucherForm.PayTime" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss"
style="width: 100%;" />
<el-date-picker
v-model="voucherForm.PayTime"
type="datetime"
value-format="YYYY-MM-DDTHH:mm:ss"
style="width: 100%;"
placeholder="请选择支付时间"
/>
</el-form-item>
<el-form-item label="交易流水号">
<el-input v-model="voucherForm.TransactionId" placeholder="可选" />
</el-form-item>
<el-form-item label="凭证文件" prop="File">
<el-upload :limit="1" :auto-upload="false" drag :file-list="voucherUploadFileList" :on-change="onVoucherFileChange">
<el-form-item label="凭证文件" prop="File" required>
<el-upload
:limit="1"
:auto-upload="false"
drag
:file-list="voucherUploadFileList"
:on-change="onVoucherFileChange"
:on-remove="onVoucherFileRemove"
:accept="'.jpg,.jpeg,.png,.pdf'"
>
<el-icon>
<UploadFilled />
</el-icon>
<div style="margin-top: 8px; font-size: 12px; color: var(--el-text-color-secondary);">请上传凭证文件</div>
<div style="margin-top: 8px; font-size: 12px; color: var(--el-text-color-secondary);">请上传凭证文件(仅支持jpg、jpeg、png、pdf格式,不超过5MB)</div>
</el-upload>
</el-form-item>
</el-form>
@ -907,30 +925,45 @@ const submitMaterial = async () => {
const isShowVoucherDialog = ref(false);
const voucherSubmitting = ref(false);
const voucherForm = reactive({
PayAmount: 0,
PayAmount: null,
PayTime: '',
TransactionId: '',
File: null,
});
const voucherUploadFileList = ref([]);
const voucherFormRef = ref();
// 允许的文件类型
const allowedFileTypes = ['image/jpeg', 'image/jpg', 'image/png', 'application/pdf'];
// 允许的文件扩展名
const allowedFileExtensions = ['.jpg', '.jpeg', '.png', '.pdf'];
// 最大文件大小 5MB
const maxFileSize = 5 * 1024 * 1024;
const voucherRules = reactive({
PayAmount: [
{ required: true, message: '请输入支付金额', trigger: ['blur', 'change'] },
{
validator: (_rule, value, callback) => {
if (value === '' || value === null || value === undefined) return callback(new Error('请输入支付金额'));
if (Number(value) < 0) return callback(new Error('支付金额不能为负数'));
if (value === '' || value === null || value === undefined) {
return callback(new Error('请输入支付金额'));
}
const numValue = Number(value);
if (isNaN(numValue) || numValue <= 0) {
return callback(new Error('支付金额必须大于0'));
}
return callback();
},
trigger: 'change',
trigger: ['blur', 'change'],
},
],
PayTime: [{ required: true, message: '请选择支付时间', trigger: 'change' }],
PayTime: [{ required: true, message: '请选择支付时间', trigger: ['blur', 'change'] }],
File: [
{ required: true, message: '请上传凭证文件', trigger: 'change' },
{
validator: (_rule, value, callback) => {
if (!value) return callback(new Error('请上传凭证文件'));
if (!value) {
return callback(new Error('请上传凭证文件'));
}
return callback();
},
trigger: 'change',
@ -941,32 +974,118 @@ const voucherRules = reactive({
const openVoucherDialog = (row) => {
if (row) currentRow.value = row;
voucherSubmitting.value = false;
voucherForm.PayAmount = 0;
voucherForm.PayAmount = null;
voucherForm.PayTime = '';
voucherForm.TransactionId = '';
voucherForm.File = null;
voucherUploadFileList.value = [];
// 打开对话框后清除之前的验证状态
nextTick(() => {
if (voucherFormRef.value) {
voucherFormRef.value.clearValidate();
}
});
isShowVoucherDialog.value = true;
};
const handlePayAmountChange = (value) => {
// 当金额改变时,触发表单验证
if (voucherFormRef.value) {
voucherFormRef.value.validateField('PayAmount');
}
};
const validateFile = (file) => {
// 检查文件类型
const fileName = file.name.toLowerCase();
const hasValidExtension = allowedFileExtensions.some(ext => fileName.endsWith(ext));
const hasValidType = allowedFileTypes.includes(file.type);
if (!hasValidExtension && !hasValidType) {
ElMessage.error('仅支持jpg、jpeg、png、pdf格式的文件');
return false;
}
// 检查文件大小
if (file.size > maxFileSize) {
ElMessage.error('文件大小不能超过5MB');
return false;
}
return true;
};
const onVoucherFileChange = (_file, fileList) => {
// 如果有文件被添加,验证它
if (fileList && fileList.length > 0) {
const lastFile = fileList[fileList.length - 1];
if (lastFile.raw && !validateFile(lastFile.raw)) {
// 验证失败,移除该文件
voucherUploadFileList.value = [];
voucherForm.File = null;
// 触发表单验证
if (voucherFormRef.value) {
voucherFormRef.value.validateField('File');
}
return;
}
}
voucherUploadFileList.value = fileList;
const first = (fileList ?? []).find((f) => f?.raw);
voucherForm.File = first?.raw ?? null;
// 触发表单验证
if (voucherFormRef.value) {
voucherFormRef.value.validateField('File');
}
};
const onVoucherFileRemove = (_file, _fileList) => {
// 文件被删除时,更新表单数据并触发验证
voucherForm.File = null;
if (voucherFormRef.value) {
voucherFormRef.value.validateField('File');
}
};
const submitVoucher = async () => {
if (!currentRow.value?.registrationId) return;
if (!voucherFormRef.value) return;
// 先清除可能的旧验证
voucherFormRef.value.clearValidate();
// 执行完整表单验证
voucherFormRef.value.validate(async (valid) => {
if (!valid) return;
if (!valid) {
ElMessage.warning('请完善表单信息后再提交');
return;
}
// 二次验证支付金额
if (!voucherForm.PayAmount || Number(voucherForm.PayAmount) <= 0) {
ElMessage.warning('请输入有效的支付金额');
return;
}
// 二次验证文件
if (!voucherForm.File) {
ElMessage.warning('请上传凭证文件');
return;
}
// 二次验证支付时间
if (!voucherForm.PayTime) {
ElMessage.warning('请选择支付时间');
return;
}
voucherSubmitting.value = true;
try {
const payload = {
File: voucherForm.File,
PayAmount: voucherForm.PayAmount,
PayTime: voucherForm.PayTime,
TransactionId: voucherForm.TransactionId || undefined,
};
const { succeeded, data } = await usereventrecordVoucherPost(currentRow.value.registrationId, payload);
if (succeeded) {