<template>
<view class="container">
<view class="header">
<text class="header-title">在线投诉举报平台</text>
<text class="header-subtitle">诚信是企业生存和发展的根本</text>
</view>
<!-- 欢迎页面 -->
<view v-if="showWelcome" class="welcome-section">
<view class="welcome-image">
<image src="/static/OnlinComplaint.jpg" mode=""></image>
</view>
<view class="welcome-content">
<text class="welcome-text">欢迎举报</text>
<text class="welcome-text indent">诚信是做人做事的根本,同样诚信的企业才能生存和发展。其亚的任何人,无论职务的高低,都应谨守廉洁并自觉接受各方监督。</text>
<text class="welcome-text indent">任何单位和个人都有有权举报其亚员工的违法违纪行为。同时,我们将对您提供的信息严格保密,一经查实,将根据公司制度给予相应奖励。</text>
<text class="welcome-text indent">您可以选择匿名举报,无需填写个人联系方式。</text>
</view>
<view
class="accept-box"
:class="{disabled: countdown > 0}"
@tap="handleAccept"
>
<text>我已阅读并理解上述内容</text>
<view class="timer">
{{ countdown }}s
</view>
</view>
</view>
<!-- 表单页面 -->
<view v-else class="form-section">
<view class="section-title">
<uni-icons type="compose" size="24" color="#3498db"></uni-icons>
<text>投诉信息</text>
</view>
<view class="form-row">
<view class="form-col">
<view class="form-group">
<label for="title" class="required">投诉标题</label>
<input
type="text"
id="title"
placeholder="请输入投诉标题"
v-model="formData.title"
:class="{error: errors.title}"
@blur="validateField('title')"
>
<text v-if="errors.title" class="error-text">{{ errors.title }}</text>
</view>
</view>
<view class="form-col">
<view class="form-group">
<label for="category" class="required">类别</label>
<picker
@change="bindPickerChange"
:value="categoryIndex"
:range="categories.map(item => item.label)"
class="picker"
@blur="validateField('category')"
>
<view class="picker-content" :class="{placeholder: !formData.category, error: errors.category}">
{{ formData.category || '请选择投诉类别' }}
</view>
</picker>
<text v-if="errors.category" class="error-text">{{ errors.category }}</text>
</view>
</view>
</view>
<view class="form-row">
<view class="form-col">
<view class="form-group">
<label for="complaineeName" class="required">被投诉人姓名</label>
<input
type="text"
id="complaineeName"
placeholder="请输入被投诉人姓名"
v-model="formData.complaineeName"
:class="{error: errors.complaineeName}"
@blur="validateField('complaineeName')"
>
<text v-if="errors.complaineeName" class="error-text">{{ errors.complaineeName }}</text>
</view>
</view>
<view class="form-col">
<view class="form-group">
<label for="company" class="required">被投诉人公司</label>
<input
type="text"
id="company"
placeholder="请输入公司名称"
v-model="formData.company"
:class="{error: errors.company}"
@blur="validateField('company')"
>
<text v-if="errors.company" class="error-text">{{ errors.company }}</text>
</view>
</view>
</view>
<view class="form-row">
<view class="form-col">
<view class="form-group">
<label for="department" class="required">被投诉人部门</label>
<input
type="text"
id="department"
placeholder="请输入部门名称"
v-model="formData.department"
:class="{error: errors.department}"
@blur="validateField('department')"
>
<text v-if="errors.department" class="error-text">{{ errors.department }}</text>
</view>
</view>
</view>
<view class="form-group">
<label for="content" class="required">投诉内容</label>
<textarea
id="content"
placeholder="请您如实详细填写投诉内容(时间、地点、事件、经过)"
v-model="formData.content"
:class="{error: errors.content}"
@blur="validateField('content')"
></textarea>
<view class="content-counter">
<text>{{ formData.content.length }}/2000</text>
</view>
<text v-if="errors.content" class="error-text">{{ errors.content }}</text>
</view>
<view class="section-title">
<uni-icons type="paperclip" size="24" color="#3498db"></uni-icons>
<text>上传附件</text>
</view>
<view class="upload-area" @tap="chooseAndUploadFile" :class="{disabled: uploadDisabled}">
<view class="upload-icon">
<uni-icons type="cloud-upload" size="48" color="#3498db"></uni-icons>
</view>
<view class="upload-text">点击上传到此处</view>
<view class="file-types">支持word文档、照片、MP3、MP4等格式,每次上传文件大小不超过10M,附件过大请发投诉渠道邮箱</view>
<view v-if="uploading" class="upload-progress">
<uni-progress :percent="uploadProgress" stroke-width="48" activeColor="#3498db"></uni-progress>
</view>
</view>
<view v-if="files.length > 0" class="file-list">
<view v-for="(file, index) in files" :key="index" class="file-item">
<uni-icons type="paperclip" size="18" color="#3498db"></uni-icons>
<view class="file-info">
<text class="file-name">{{ file.name }}</text>
<text class="file-size">({{ formatFileSize(file.size) }})</text>
</view>
<view
class="delete-btn"
@tap="removeFile(index)"
>X
<uni-icons
type="close"
size="16"
color="#ffffff"
></uni-icons>
</view>
</view>
</view>
<view class="section-title">
<uni-icons type="person" size="24" color="#3498db"></uni-icons>
<text>联系方式(选填,支持匿名)</text>
</view>
<view class="form-row">
<view class="form-col">
<view class="form-group">
<label for="name">姓名(选填)</label>
<input
type="text"
id="name"
placeholder="请输入您的姓名(选填)"
v-model="formData.name"
:class="{error: errors.name}"
@blur="validateField('name')"
>
<text v-if="errors.name" class="error-text">{{ errors.name }}</text>
</view>
</view>
<view class="form-col">
<view class="form-group">
<label for="phone">手机号(选填)</label>
<input
type="number"
id="phone"
placeholder="请输入您的手机号(选填)"
v-model="formData.phone"
:class="{error: errors.phone}"
@blur="validateField('phone')"
>
<text v-if="errors.phone" class="error-text">{{ errors.phone }}</text>
</view>
</view>
</view>
<view class="form-row">
<view class="form-col">
<view class="form-group">
<label for="email">邮箱(选填)</label>
<input
type="email"
id="email"
placeholder="请输入您的邮箱(选填)"
v-model="formData.email"
:class="{error: errors.email}"
@blur="validateField('email')"
>
<text v-if="errors.email" class="error-text">{{ errors.email }}</text>
</view>
</view>
</view>
<view class="privacy-note">
您可以选择匿名举报,无需填写个人联系方式。如填写联系方式,我们会对您的个人信息及投诉内容进行严格保密,便于后续跟进调查。
</view>
<button class="submit-btn" @tap="submitForm" :disabled="uploading || processing">
<template v-if="processing">处理中...</template>
<template v-else>提交投诉</template>
</button>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { onShow } from '@dcloudio/uni-app';
// 存储openID的变量
const openId = ref('');
// 表单数据
const formData = ref({
title: '',
category: '', // 存储显示的类别名称
categoryValue: '', // 存储实际提交的类别值
complaineeName: '',
company: '',
department: '',
content: '',
name: '', // 可选
phone: '', // 可选
email: '' // 可选
});
// 错误信息
const errors = ref({});
// 文件列表 - 存储上传成功后的文件信息
const files = ref([]);
// 上传状态管理
const uploading = ref(false);
const uploadProgress = ref(0);
const uploadDisabled = ref(false);
// 处理状态(用于获取OpenID和提交过程中)
const processing = ref(false);
// 类别选择(包含显示文本和对应的值)
const categories = ref([
{ label: '财务违规', value: '1' },
{ label: '道德问题', value: '2' },
{ label: '职场骚扰', value: '3' },
{ label: '安全隐患', value: '4' }
]);
const categoryIndex = ref(-1);
// 欢迎页状态
const showWelcome = ref(true);
const countdown = ref(5);
// 处理接受按钮点击
const handleAccept = () => {
if (countdown.value > 0) return;
showWelcome.value = false;
};
// 选择类别 - 同时记录显示文本和实际值
const bindPickerChange = (e) => {
categoryIndex.value = e.detail.value;
const selected = categories.value[e.detail.value];
formData.value.category = selected.label; // 显示用
formData.value.categoryValue = selected.value; // 实际提交用
validateField('category'); // 选择后立即验证
};
// 选择并上传文件
const chooseAndUploadFile = async () => {
if (uploading.value) return;
try {
// 选择文件
const res = await uni.chooseFile({
count: 5 - files.value.length, // 限制总文件数不超过5个
type: 'all',
extension: ['png', 'jpg', 'jpeg', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'mp3', 'mp4'],
});
if (res.tempFiles && res.tempFiles.length > 0) {
// 开始上传
uploadFiles(res.tempFiles);
}
} catch (err) {
console.log('选择文件失败', err);
uni.showToast({
title: '选择文件失败',
icon: 'error',
duration: 2000
});
}
};
// 上传文件到服务器
const uploadFiles = async (tempFiles) => {
uploading.value = true;
uploadDisabled.value = true;
uploadProgress.value = 0;
// 显示加载弹窗(小圆圈)
uni.showLoading({
title: '正在上传...',
mask: true // 防止背景点击
});
try {
// 计算总文件大小
const totalSize = tempFiles.reduce((sum, file) => sum + file.size, 0);
let uploadedSize = 0;
// 逐个上传文件
for (let i = 0; i < tempFiles.length; i++) {
const file = tempFiles[i];
await new Promise((resolve, reject) => {
uni.uploadFile({
url: '/api/file/upload',
filePath: file.path,
name: 'file',
header: {},
timeout: 360000, // 1分钟超时
// 移除进度更新逻辑(不再需要)
success: (res) => {
try {
const response = JSON.parse(res.data);
if (res.statusCode === 200 && response.code === 200 && response.data) {
uploadedSize += file.size;
files.value.push({
name: response.data.name,
size: file.size,
url: response.data.url,
id: Date.now() + i
});
resolve();
} else {
throw new Error(response.msg || `文件上传失败,错误代码: ${response.code}`);
}
} catch (err) {
reject(err);
}
},
fail: (err) => {
reject(new Error(`上传失败: ${err.errMsg}`));
}
});
});
}
// 文件上传成功后提示
uni.showToast({
title: '文件上传成功',
icon: 'success'
});
} catch (err) {
console.error('文件上传失败', err);
uni.showToast({
title: err.message || '文件上传失败',
icon: 'error'
});
} finally {
// 关闭加载弹窗
uni.hideLoading();
uploading.value = false;
uploadDisabled.value = false;
uploadProgress.value = 0;
}
};
// 移除文件
const removeFile = (index) => {
files.value.splice(index, 1);
};
// 格式化文件大小
const formatFileSize = (bytes) => {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
// 单个字段验证
const validateField = (field) => {
const value = formData.value[field];
let error = '';
switch(field) {
case 'title':
if (!value) error = '请输入投诉标题';
else if (value.length > 100) error = '标题长度不能超过100个字符';
break;
case 'category':
if (!value) error = '请选择投诉类别';
break;
case 'complaineeName':
if (!value) error = '请输入被投诉人姓名';
else if (value.length > 50) error = '姓名长度不能超过50个字符';
break;
case 'company':
if (!value) error = '请输入被投诉人公司';
else if (value.length > 100) error = '公司名称长度不能超过100个字符';
break;
case 'department':
if (!value) error = '请输入被投诉人部门';
else if (value.length > 100) error = '部门名称长度不能超过100个字符';
break;
case 'content':
if (!value) error = '请输入投诉内容';
else if (value.length < 1) error = '投诉内容不能为空';
break;
case 'name':
if (value && value.length > 50) error = '姓名长度不能超过50个字符';
break;
case 'phone':
const phoneRegex = /^1[3-9]\d{9}$/;
if (value && value.trim() !== '' && !phoneRegex.test(value)) {
error = '请输入有效的手机号码';
}
break;
case 'email':
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (value && value.trim() !== '' && !emailRegex.test(value)) {
error = '请输入有效的邮箱地址';
}
break;
}
errors.value[field] = error;
return !error;
};
// 表单验证 - 验证所有必填项和格式
const validateForm = () => {
errors.value = {};
let isValid = true;
// 验证所有字段
const allFields = ['title', 'category', 'complaineeName', 'company', 'department', 'content', 'name', 'phone', 'email'];
allFields.forEach(field => {
if (!validateField(field)) {
isValid = false;
}
});
return isValid;
};
// 提交表单
const submitForm = async () => {
if (uploading.value || processing.value) {
uni.showToast({
title: '操作处理中,请稍后',
icon: 'none',
duration: 2000
});
return;
}
// 先验证表单
const isValid = validateForm();
if (!isValid) {
// 滚动到第一个错误字段
const firstErrorField = Object.keys(errors.value).find(key => errors.value[key]);
if (firstErrorField) {
const element = document.getElementById(firstErrorField);
if (element) {
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
// 给错误字段添加闪烁效果
element.classList.add('error-highlight');
setTimeout(() => element.classList.remove('error-highlight'), 1000);
}
}
const firstError = Object.values(errors.value).find(msg => msg);
if (firstError) {
uni.showToast({
title: firstError,
icon: 'none',
duration: 2000
});
}
return;
}
processing.value = true;
try {
// 从本地缓存获取OpenID
const openId = uni.getStorageSync('wechat_openid') || '';
// 准备提交的数据
const submitData = {
title: formData.value.title,
complaintType: formData.value.categoryValue,
bcomplaintName: formData.value.complaineeName,
bcomplaintCompany: formData.value.company,
bcomplaintDept: formData.value.department,
bcomplaintContent: formData.value.content,
processingStatus: "1",
fileUrl: files.value.map(file => file.url).join(','),
complaintPerson: formData.value.name || '',
phoneNumber: formData.value.phone || '',
email: formData.value.email || '',
wxUserId: openId // 将openID传入wxUserId字段
};
uni.showLoading({
title: '提交中...',
mask: true
});
// 提交表单数据到接口
await new Promise((resolve, reject) => {
uni.request({
url: '/api/incorruptFront/addComplainTs',
method: 'POST',
data: submitData,
header: {
'Content-Type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200 && res.data.code === 200) {
resolve(res.data);
} else {
reject(new Error(res.data.msg || '提交失败'));
}
},
fail: (err) => {
reject(new Error(`网络错误: ${err.errMsg}`));
}
});
});
uni.hideLoading();
uni.showToast({
title: '投诉信息已提交',
icon: 'success',
duration: 2000
});
// 2秒后返回首页
setTimeout(() => {
uni.reLaunch({ url: '/pages/index/index' });
}, 2000);
} catch (error) {
console.error('提交表单失败', error);
uni.hideLoading();
uni.showToast({
title: error.message || '提交失败,请重试',
icon: 'error',
duration: 2000
});
} finally {
processing.value = false;
}
};
// 页面加载
onMounted(() => {
// 启动倒计时
const timer = setInterval(() => {
if (countdown.value > 0) {
countdown.value--;
} else {
clearInterval(timer);
}
}, 1000);
// 从缓存获取openID
openId.value = uni.getStorageSync('wechat_openid') || '';
});
</script>
<style lang="scss">
/* 基础样式保持不变 */
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
padding: 20rpx;
}
.header {
background: linear-gradient(135deg, #3498db 0%, #2c3e50 100%);
color: white;
text-align: center;
padding: 40rpx 20rpx;
border-radius: 0 0 30rpx 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.15);
}
.header-title {
display: block;
font-size: 40rpx;
font-weight: bold;
margin-bottom: 15rpx;
letter-spacing: 1rpx;
}
.header-subtitle {
font-size: 28rpx;
opacity: 0.9;
}
.welcome-section {
padding: 30rpx;
transition: all 0.5s ease;
}
.welcome-image {
width: 100%;
height: 300rpx;
border-radius: 20rpx;
overflow: hidden;
box-shadow: 0 8rpx 25rpx rgba(0, 0, 0, 0.1);
display: flex;
justify-content: center;
align-items: center;
}
.welcome-image image {
width: 100%;
height: 100%;
object-fit: cover;
}
.welcome-content {
background-color: #f8f9fa;
border-radius: 20rpx;
padding: 30rpx;
line-height: 1.8;
font-size: 28rpx;
color: #333;
box-shadow: inset 0 0 10rpx rgba(0, 0, 0, 0.05);
margin-bottom: 30rpx;
}
.welcome-text {
display: block;
margin-bottom: 20rpx;
}
.accept-box {
display: flex;
justify-content: center;
align-items: center;
padding: 25rpx;
background-color: #e3f2fd;
border-radius: 20rpx;
cursor: pointer;
transition: all 0.3s ease;
border: 2rpx solid #bbdefb;
box-shadow: 0 4rpx 15rpx rgba(0, 0, 0, 0.1);
}
.accept-box.disabled {
background-color: #f5f5f5;
cursor: not-allowed;
opacity: 0.7;
}
.accept-box .timer {
background-color: #e74c3c;
color: white;
width: 70rpx;
height: 70rpx;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin-left: 20rpx;
font-weight: bold;
font-size: 30rpx;
}
.form-section {
padding: 30rpx;
}
.section-title {
font-size: 34rpx;
color: #2c3e50;
margin-bottom: 30rpx;
padding-bottom: 15rpx;
border-bottom: 2rpx solid #3498db;
display: flex;
align-items: center;
text {
margin-left: 15rpx;
font-weight: bold;
}
}
.form-group {
margin-bottom: 35rpx;
position: relative;
}
.form-row {
&.full-width {
display: flex;
flex-wrap: wrap;
margin: 0 -15rpx;
margin-bottom: 40rpx;
}
}
.form-col {
flex: 1;
padding: 0 15rpx;
min-width: 300rpx;
}
label {
display: block;
margin-bottom: 15rpx;
font-weight: 500;
color: #2c3e50;
font-size: 30rpx;
}
label.required::after {
content: "*";
color: #e74c3c;
margin-left: 8rpx;
}
input, select, textarea, .picker-content {
width: 100%;
padding: 25rpx;
border: 2rpx solid #e0e0e0;
border-radius: 15rpx;
font-size: 28rpx;
transition: all 0.3s ease;
background-color: #fff;
}
input:focus, select:focus, textarea:focus, .picker-content:active {
border-color: #3498db;
outline: none;
box-shadow: 0 0 0 3rpx rgba(52, 152, 219, 0.2);
}
textarea {
min-height: 200rpx;
resize: vertical;
}
/* 新增的内容计数器样式 */
.content-counter {
text-align: right;
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
.picker-content {
display: flex;
align-items: center;
min-height: 80rpx; /* 确保选择器高度与输入框一致 */
&.placeholder {
color: #999;
}
}
.upload-area {
border: 2rpx dashed #3498db;
border-radius: 20rpx;
padding: 40rpx 30rpx;
text-align: center;
background-color: #e3f2fd;
cursor: pointer;
transition: all 0.3s ease;
margin-bottom: 30rpx;
}
.upload-area.disabled {
background-color: #f5f5f5;
border-color: #bdc3c7;
cursor: not-allowed;
}
.upload-area:active:not(.disabled) {
background-color: #bbdefb;
transform: scale(0.98);
}
.upload-icon {
margin-bottom: 20rpx;
}
.upload-text {
color: #2c3e50;
margin-bottom: 20rpx;
font-size: 30rpx;
font-weight: 500;
}
.file-types {
color: #7f8c8d;
font-size: 26rpx;
margin-bottom: 20rpx;
}
.upload-progress {
width: 80%;
margin: 20rpx auto 0;
}
.progress-text {
display: block;
margin-top: 10rpx;
font-size: 26rpx;
color: #3498db;
}
.file-list {
margin-top: 20rpx;
margin-bottom: 30rpx;
}
.file-item {
display: flex;
align-items: center;
padding: 20rpx;
background-color: #f8f9fa;
border-radius: 15rpx;
margin-bottom: 15rpx;
border-left: 4rpx solid #3498db;
}
/* 优化文件信息显示 */
.file-info {
flex: 1;
margin: 0 15rpx;
min-width: 0; /* 允许容器收缩 */
}
.file-name {
display: block;
font-size: 28rpx;
color: #2c3e50;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* 不换行,超出部分显示省略号 */
}
.file-size {
display: block;
color: #7f8c8d;
font-size: 24rpx;
margin-top: 5rpx;
}
.delete-btn {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background-color: #e74c3c;
display: flex;
justify-content: center;
align-items: center;
margin-left: 10rpx;
flex-shrink: 0; /* 确保按钮不被挤压 */
transition: all 0.2s ease;
color: #ffffff;
}
.delete-btn:active {
background-color: #c0392b;
transform: scale(0.9);
}
.error-text {
display: block;
color: #e74c3c;
font-size: 26rpx;
margin-top: 10rpx;
}
input.error, textarea.error, .picker-content.error {
border-color: #e74c3c;
animation: shake 0.5s ease;
}
/* 错误字段高亮动画 */
.error-highlight {
animation: highlight 1s ease;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
20%, 60% { transform: translateX(-5rpx); }
40%, 80% { transform: translateX(5rpx); }
}
@keyframes highlight {
0%, 100% { box-shadow: none; }
50% { box-shadow: 0 0 0 4rpx rgba(231, 76, 60, 0.3); }
}
.privacy-note {
background-color: #f8f9fa;
border-radius: 15rpx;
padding: 25rpx;
margin-top: 30rpx;
font-size: 26rpx;
color: #7f8c8d;
text-align: center;
border: 1rpx solid #e9ecef;
line-height: 1.6;
}
.submit-btn {
background: linear-gradient(to right, #3498db, #2980b9);
color: white;
border: none;
padding: 25rpx 0;
width: 100%;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: 600;
margin-top: 30rpx;
box-shadow: 0 5rpx 20rpx rgba(52, 152, 219, 0.4);
transition: all 0.3s ease;
}
.submit-btn:disabled {
background: #bdc3c7;
box-shadow: none;
opacity: 0.7;
}
.submit-btn:active:not(:disabled) {
transform: translateY(-3rpx);
box-shadow: 0 8rpx 25rpx rgba(52, 152, 219, 0.6);
}
/* 响应式设计 */
@media (min-width: 768px) {
.container {
max-width: 750px;
margin: 0 auto;
padding: 40rpx;
}
.welcome-image {
height: 350rpx;
}
}
.welcome-text.indent{
text-indent: 2em;
}
</style>
上传附件报错:Request URL: http://www.wyqg.top/api/file/upload
Request Method: POST
Status Code: 400 Bad Request
Remote Address: 47.109.65.73:80
Referrer Policy: strict-origin-when-cross-origin
Connection: keep-alive
Content-Length: 0
Date: Mon, 01 Sep 2025 10:00:25 GMT
Server: nginx/1.26.3
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Content-Length: 10485948
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGFsvh0KKYAXIXI27
Host: www.wyqg.top
Origin: http://www.wyqg.top
Referer: http://www.wyqg.top/pages/OnlinComplaint/OnlinComplaint?openid=ohhFX6TzyGvbXFuIL0ZPjEIpsJOo
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1 wechatdevtools/1.06.2504030 MicroMessenger/8.0.5 Language/zh_CN webview/17566896873445375 webdebugger port/57256 token/84cac3393fe84eaa19bae7107a7c7659
file: (binary)
但是我用postman测试接口,用post方法 Body选择 form-data,键file是文件,值上传了一个MP4文件测试没问题