修改开发环境API地址并优化租户管理中营业执照上传功能
This commit is contained in:
@@ -3,5 +3,7 @@ ENV = 'development'
|
|||||||
|
|
||||||
# 本地环境接口地址
|
# 本地环境接口地址
|
||||||
# VITE_API_URL = 'http://192.168.3.200:8808/'
|
# VITE_API_URL = 'http://192.168.3.200:8808/'
|
||||||
VITE_API_URL = 'http://localhost:8808/'
|
# VITE_API_URL = 'http://localhost:8808/'
|
||||||
|
VITE_API_URL = 'http://192.168.3.11:8808/'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ const service: AxiosInstance = axios.create({
|
|||||||
const newService: AxiosInstance = axios.create({
|
const newService: AxiosInstance = axios.create({
|
||||||
// baseURL: 'http://192.168.3.95:8000/',
|
// baseURL: 'http://192.168.3.95:8000/',
|
||||||
// baseURL: 'http://192.168.3.49:8000/',
|
// baseURL: 'http://192.168.3.49:8000/',
|
||||||
baseURL: 'http://localhost:8000/',
|
// baseURL: 'http://localhost:8000/',
|
||||||
// baseURL: 'http://192.168.3.200:8000/',
|
// baseURL: 'http://192.168.3.200:8000/',
|
||||||
|
baseURL: 'http://192.168.3.11:8000/',
|
||||||
timeout: 50000,
|
timeout: 50000,
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
paramsSerializer: {
|
paramsSerializer: {
|
||||||
@@ -64,9 +65,9 @@ const performLogout = () => {
|
|||||||
Session.clear();
|
Session.clear();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
isHandlingTokenExpired = false;
|
isHandlingTokenExpired = false;
|
||||||
// 跳转到登录页,确保完全刷新
|
// 跳转到后台管理登录页,确保完全刷新
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/';
|
window.location.href = '/login';
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -74,18 +74,18 @@
|
|||||||
<div class="upload-container">
|
<div class="upload-container">
|
||||||
<el-upload
|
<el-upload
|
||||||
class="avatar-uploader"
|
class="avatar-uploader"
|
||||||
action="#"
|
:http-request="handleImageUpload"
|
||||||
:auto-upload="false"
|
|
||||||
:on-change="handleFileChange"
|
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
:before-upload="beforeAvatarUpload"
|
:before-upload="beforeAvatarUpload"
|
||||||
|
accept="image/*"
|
||||||
>
|
>
|
||||||
<img v-if="ruleForm.businessLicense" :src="getUpFileUrl(ruleForm.businessLicense)" class="avatar" />
|
<img v-if="imagePreview" :src="imagePreview" class="avatar" />
|
||||||
<div v-else class="upload-placeholder">
|
<div v-else class="upload-placeholder">
|
||||||
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
<el-icon class="avatar-uploader-icon"><Plus /></el-icon>
|
||||||
<span class="upload-text">点击上传营业执照</span>
|
<span class="upload-text">点击上传营业执照</span>
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
<el-button v-if="imagePreview" type="danger" text size="small" style="margin-left: 10px" @click="removeImage">删除</el-button>
|
||||||
<div class="upload-tip">支持 jpg、png 格式,文件大小不超过 2MB</div>
|
<div class="upload-tip">支持 jpg、png 格式,文件大小不超过 2MB</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -109,6 +109,7 @@ import { Plus } from '@element-plus/icons-vue';
|
|||||||
import { addTenant, editTenant } from '/@/api/system/tenant';
|
import { addTenant, editTenant } from '/@/api/system/tenant';
|
||||||
import { pcTextArr,provinceAndCityData } from 'element-china-area-data';
|
import { pcTextArr,provinceAndCityData } from 'element-china-area-data';
|
||||||
import { getUpFileUrl } from '/@/utils/gfast';
|
import { getUpFileUrl } from '/@/utils/gfast';
|
||||||
|
import { uploadAssetImage } from '/@/api/assets/asset';
|
||||||
|
|
||||||
// 定义父组件传递的事件
|
// 定义父组件传递的事件
|
||||||
const emit = defineEmits(['getTenantList']);
|
const emit = defineEmits(['getTenantList']);
|
||||||
@@ -118,8 +119,9 @@ const formRef = ref<HTMLElement | null>(null);
|
|||||||
// 省市数据(使用 element-china-area-data)
|
// 省市数据(使用 element-china-area-data)
|
||||||
const cityOptions = ref<any[]>([]);
|
const cityOptions = ref<any[]>([]);
|
||||||
|
|
||||||
// 单独定义文件对象,避免reactive深层代理导致FormData识别错误
|
// 图片上传相关
|
||||||
const fileRaw = ref<any>(null);
|
const fileAddressPrefix = ref('');
|
||||||
|
const imagePreview = ref('');
|
||||||
|
|
||||||
const initCityData = () => {
|
const initCityData = () => {
|
||||||
const data = JSON.parse(JSON.stringify(provinceAndCityData));
|
const data = JSON.parse(JSON.stringify(provinceAndCityData));
|
||||||
@@ -243,6 +245,14 @@ const openDialog = (row?: any) => {
|
|||||||
confirmPassword: '',
|
confirmPassword: '',
|
||||||
businessLicense: row.businessLicense,
|
businessLicense: row.businessLicense,
|
||||||
};
|
};
|
||||||
|
// 图片预览回显
|
||||||
|
if (row.businessLicense) {
|
||||||
|
// 设置 fileAddressPrefix(如果后端返回了)
|
||||||
|
if (row.fileAddressPrefix) {
|
||||||
|
fileAddressPrefix.value = row.fileAddressPrefix;
|
||||||
|
}
|
||||||
|
imagePreview.value = formatImageUrl(row.businessLicense);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
state.isShowDialog = true;
|
state.isShowDialog = true;
|
||||||
};
|
};
|
||||||
@@ -282,37 +292,21 @@ const onSubmit = () => {
|
|||||||
submitForm.cityCode = '';
|
submitForm.cityCode = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换为FormData
|
// 图片已通过 uploadAssetImage 接口上传,businessLicense 存储的是相对路径
|
||||||
const formData = new FormData();
|
// 直接提交 JSON 对象
|
||||||
for (const key in submitForm) {
|
|
||||||
// 如果是文件字段,跳过(后面单独处理)
|
|
||||||
if (key === 'businessLicense') continue;
|
|
||||||
formData.append(key, submitForm[key]);
|
|
||||||
}
|
|
||||||
// 添加文件
|
|
||||||
if (fileRaw.value) {
|
|
||||||
// 【重要】必须append raw file(二进制文件流),不能是element-plus的uploadFile包装对象
|
|
||||||
// 否则后端接收到的会是 { uid: ..., status: ... } 这样的json结构
|
|
||||||
formData.append('businessLicense', fileRaw.value);
|
|
||||||
} else if (submitForm.businessLicense && !submitForm.businessLicense.startsWith('blob:')) {
|
|
||||||
// 如果没有新文件,且原值不是blob预览地址,则传递原url字符串
|
|
||||||
formData.append('businessLicense', submitForm.businessLicense);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.ruleForm.id === 0) {
|
if (state.ruleForm.id === 0) {
|
||||||
addTenant(formData).then(() => {
|
addTenant(submitForm).then(() => {
|
||||||
ElMessage.success('添加成功');
|
ElMessage.success('添加成功');
|
||||||
closeDialog();
|
closeDialog();
|
||||||
emit('getTenantList');
|
emit('getTenantList');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 过滤掉密码字段,或者后端接口决定是否更新密码
|
// 修改时不能修改密码和账号
|
||||||
// 根据需求,修改时不能修改密码
|
delete submitForm.userPassword;
|
||||||
if (formData.has('userPassword')) formData.delete('userPassword');
|
delete submitForm.confirmPassword;
|
||||||
if (formData.has('confirmPassword')) formData.delete('confirmPassword');
|
delete submitForm.userName;
|
||||||
if (formData.has('userName')) formData.delete('userName');
|
|
||||||
|
|
||||||
editTenant(formData).then(() => {
|
editTenant(submitForm).then(() => {
|
||||||
ElMessage.success('修改成功');
|
ElMessage.success('修改成功');
|
||||||
closeDialog();
|
closeDialog();
|
||||||
emit('getTenantList');
|
emit('getTenantList');
|
||||||
@@ -336,23 +330,63 @@ const resetForm = () => {
|
|||||||
businessLicense: '',
|
businessLicense: '',
|
||||||
};
|
};
|
||||||
state.passwordStrength = 0;
|
state.passwordStrength = 0;
|
||||||
fileRaw.value = null;
|
imagePreview.value = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
// 文件改变时触发
|
// 格式化图片 URL
|
||||||
const handleFileChange: UploadProps['onChange'] = (uploadFile) => {
|
const formatImageUrl = (url?: string) => {
|
||||||
if (uploadFile.raw) {
|
if (!url) return '';
|
||||||
fileRaw.value = uploadFile.raw;
|
if (/^https?:\/\//i.test(url)) return url;
|
||||||
state.ruleForm.businessLicense = URL.createObjectURL(uploadFile.raw);
|
if (/^blob:/i.test(url)) return url;
|
||||||
|
return `${fileAddressPrefix.value || ''}${url}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 上传图片并返回URL
|
||||||
|
const uploadImage = async (file: File): Promise<string> => {
|
||||||
|
const res: any = await uploadAssetImage(file);
|
||||||
|
|
||||||
|
// 获取并设置 fileAddressPrefix
|
||||||
|
if (res.fileAddressPrefix) {
|
||||||
|
fileAddressPrefix.value = res.fileAddressPrefix;
|
||||||
|
} else if (res.data && typeof res.data === 'object' && res.data.fileAddressPrefix) {
|
||||||
|
fileAddressPrefix.value = res.data.fileAddressPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取 fileURL
|
||||||
|
if (res.fileURL) return res.fileURL;
|
||||||
|
if (res.data && typeof res.data === 'object') {
|
||||||
|
if (res.data.fileURL) return res.data.fileURL;
|
||||||
|
if (res.data.url) return res.data.url;
|
||||||
|
}
|
||||||
|
if (typeof res.data === 'string') return res.data;
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理图片上传
|
||||||
|
const handleImageUpload = async (options: any) => {
|
||||||
|
try {
|
||||||
|
const url = await uploadImage(options.file);
|
||||||
|
if (url) {
|
||||||
|
state.ruleForm.businessLicense = url;
|
||||||
|
imagePreview.value = formatImageUrl(url);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('图片上传失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除图片
|
||||||
|
const removeImage = () => {
|
||||||
|
state.ruleForm.businessLicense = '';
|
||||||
|
imagePreview.value = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||||
if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
|
if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
|
||||||
ElMessage.error('Avatar picture must be JPG/PNG format!');
|
ElMessage.error('图片格式必须为 JPG/PNG!');
|
||||||
return false;
|
return false;
|
||||||
} else if (rawFile.size / 1024 / 1024 > 2) {
|
} else if (rawFile.size / 1024 / 1024 > 2) {
|
||||||
ElMessage.error('Avatar picture size can not exceed 2MB!');
|
ElMessage.error('图片大小不能超过 2MB!');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user