Compare commits

...
Author SHA1 Message Date
zlf 7b9c281191 临时去除 wechatId 2026-07-31 10:46:37 +08:00
zxl 35d5085702 去除VConsole 2026-07-22 15:11:43 +08:00
zxl 778bb4e82c CRM_26-07-21#story#8995,调度app上传行驶证自动压缩 2026-07-22 15:11:42 +08:00
zxl 247ac7b130 添加VConsole 2026-07-22 15:11:40 +08:00
zxl 4874d92b3c 添加VConsole 2026-07-22 15:11:38 +08:00
zxl 46b14bba62 添加VConsole 2026-07-22 15:11:36 +08:00
zxl 3c74b44931 CRM_26-07-21#story#8995,调度app上传行驶证自动压缩 2026-07-22 15:11:34 +08:00
zlf d39b64f807 潜在服务商修改 2026-07-20 15:58:37 +08:00
3 changed files with 215 additions and 36 deletions
+7 -4
View File
@@ -41,6 +41,7 @@
const cached = localStorage.getItem('supplierAddForm'); const cached = localStorage.getItem('supplierAddForm');
if (cached) { if (cached) {
this.formPayload = JSON.parse(cached); this.formPayload = JSON.parse(cached);
this.wechatId = this.formPayload.wechatId;
this.name = this.formPayload.name; this.name = this.formPayload.name;
} }
if (this.name) { if (this.name) {
@@ -70,12 +71,14 @@
}, },
async nextStep() { async nextStep() {
if (!this.clickFlag) return; if (!this.clickFlag) return;
let res = await getContactQrCodeResult({ configId: this.configId }); if(!this.wechatId) {
this.wechatId = res?.data?.wechatId; let res = await getContactQrCodeResult({ configId: this.configId });
if (!this.wechatId) { this.wechatId = res?.data?.wechatId;
}
/* if (!this.wechatId) {
Toast('请先添加企微再继续'); Toast('请先添加企微再继续');
return; return;
} }*/
try { try {
this.clickFlag = false; this.clickFlag = false;
const res = await saveSupplier({ const res = await saveSupplier({
+1
View File
@@ -312,6 +312,7 @@
accountUrl: this.licensePhoto, accountUrl: this.licensePhoto,
service: this.$refs.tree.getCheckedKeys().join(','), service: this.$refs.tree.getCheckedKeys().join(','),
serviceAreaCode: checkArr.join(','), serviceAreaCode: checkArr.join(','),
wechatId: this.wechatId,
}; };
localStorage.setItem('supplierAddForm', JSON.stringify(payload)); localStorage.setItem('supplierAddForm', JSON.stringify(payload));
this.goPage('addWechat', { potentialFlag: 1 }); this.goPage('addWechat', { potentialFlag: 1 });
+207 -32
View File
@@ -21,11 +21,9 @@
v-model="vehicleLicenseFrontList" v-model="vehicleLicenseFrontList"
:after-read="vehicleLicenseFrontHandler" :after-read="vehicleLicenseFrontHandler"
@delete="vehicleLicenseFrontDelete" @delete="vehicleLicenseFrontDelete"
@oversize="onOversize"
:max-size="5 * 1024 * 1024"
max-count="1" max-count="1"
:preview-size="54" :preview-size="54"
accept="image " accept="image/*"
/> />
</div> </div>
<div class="itemContent"> <div class="itemContent">
@@ -37,11 +35,9 @@
v-model="vehicleLicenseBackList" v-model="vehicleLicenseBackList"
:after-read="vehicleLicenseBackHandler" :after-read="vehicleLicenseBackHandler"
@delete="vehicleLicenseBackDelete" @delete="vehicleLicenseBackDelete"
@oversize="onOversize"
:max-size="5 * 1024 * 1024"
max-count="1" max-count="1"
:preview-size="54" :preview-size="54"
accept="image " accept="image/*"
/> />
</div> </div>
<div class="itemContent"> <div class="itemContent">
@@ -53,11 +49,9 @@
v-model="vehicleLicenseCarPhotoList" v-model="vehicleLicenseCarPhotoList"
:after-read="vehicleLicenseCarHandler" :after-read="vehicleLicenseCarHandler"
@delete="vehicleLicenseCarPhotoDelete" @delete="vehicleLicenseCarPhotoDelete"
@oversize="onOversize"
:max-size="5 * 1024 * 1024"
max-count="1" max-count="1"
:preview-size="54" :preview-size="54"
accept="image " accept="image/*"
/> />
</div> </div>
<div class="itemContent"> <div class="itemContent">
@@ -69,11 +63,9 @@
v-model="vehicleFrontPhotoList" v-model="vehicleFrontPhotoList"
:after-read="vehicleFrontPhotoHandler" :after-read="vehicleFrontPhotoHandler"
@delete="vehicleFrontPhotoDelete" @delete="vehicleFrontPhotoDelete"
@oversize="onOversize"
:max-size="5 * 1024 * 1024"
max-count="1" max-count="1"
:preview-size="54" :preview-size="54"
accept="image " accept="image/*"
/> />
</div> </div>
@@ -803,33 +795,216 @@ export default {
onOversize() { onOversize() {
this.$toast(`文件大小不能超过5M`) this.$toast(`文件大小不能超过5M`)
}, },
// 将 base64 dataURL 转为 Blob,用于 APP WebView 只返回 content 的场景
dataURLToBlob(dataURL) {
const arr = dataURL.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
},
blobToDataURL(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => resolve(e.target.result);
reader.onerror = () => reject(new Error('读取压缩图片失败'));
reader.readAsDataURL(blob);
});
},
compressImage(file, maxSize = 5 * 1024 * 1024) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const originWidth = img.width;
const originHeight = img.height;
const tryQuality = (quality = 0.9) => {
canvas.width = originWidth;
canvas.height = originHeight;
ctx.clearRect(0, 0, originWidth, originHeight);
ctx.drawImage(img, 0, 0, originWidth, originHeight);
canvas.toBlob((blob) => {
if (!blob) return reject(new Error('压缩失败'));
if (blob.size <= maxSize || quality <= 0.1) {
if (blob.size <= maxSize) {
resolve(blob);
} else {
tryResolution();
}
return;
}
tryQuality(quality - 0.1);
}, 'image/jpeg', quality);
};
const tryResolution = (scale = 0.9, quality = 0.8) => {
const width = Math.floor(originWidth * scale);
const height = Math.floor(originHeight * scale);
canvas.width = width;
canvas.height = height;
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob((blob) => {
if (!blob) return reject(new Error('压缩失败'));
if (blob.size <= maxSize || scale <= 0.1) {
if (blob.size <= maxSize) {
resolve(blob);
} else {
reject(new Error('超过5M'));
}
return;
}
tryResolution(scale - 0.1, quality);
}, 'image/jpeg', quality);
};
tryQuality();
};
img.onerror = () => reject(new Error('图片加载失败'));
img.src = e.target.result;
};
reader.onerror = () => reject(new Error('文件读取失败'));
reader.readAsDataURL(file);
});
},
async compressFileItem(fileItem, maxSize = 5 * 1024 * 1024) {
let rawFile = fileItem?.file;
const rawContent = fileItem?.content;
// 打印可序列化的基础信息,VConsole 中对象会显示为空,但 name/size/type 能看到
console.log('rawFile info:', {
name: rawFile?.name,
size: rawFile?.size,
type: rawFile?.type,
constructor: rawFile?.constructor?.name
});
console.log('rawContent prefix:', typeof rawContent === 'string' ? rawContent.slice(0, 60) : rawContent);
// 部分 APP WebView 返回的文件对象异常或为空,但 content 是 base64,此时用 content 兜底
if ((!rawFile || !(rawFile instanceof File) || rawFile.size === 0) &&
typeof rawContent === 'string' && rawContent.startsWith('data:')) {
try {
const blob = this.dataURLToBlob(rawContent);
const ext = blob.type === 'image/png' ? 'png' : 'jpg';
rawFile = new File([blob], `upload_${Date.now()}.${ext}`, { type: blob.type || 'image/jpeg' });
console.log('fallback file from content, size:', rawFile.size);
} catch (e) {
console.error('content to file error:', e);
throw new Error('文件解析失败,请重新上传');
}
}
if (!rawFile) {
throw new Error('未获取到文件,请重新上传');
}
if (rawFile.size <= maxSize) return rawFile;
const blob = await this.compressImage(rawFile, maxSize);
if (blob.size > maxSize) {
throw new Error('超过5M');
}
const fileName = (rawFile.name || 'image').replace(/\.[^.]+$/, '') + '.jpg';
const compressedFile = new File([blob], fileName, { type: 'image/jpeg' });
fileItem.file = compressedFile;
fileItem.size = compressedFile.size;
fileItem.content = await this.blobToDataURL(blob);
const mb1 = (compressedFile.size / 1024 / 1024).toFixed(2);
console.log(`压缩后为:${mb1}M`)
return compressedFile;
},
async vehicleLicenseFrontHandler(file) { // 上传 行驶证首页 async vehicleLicenseFrontHandler(file) { // 上传 行驶证首页
const formData = new FormData(); console.log('file',file)
formData.append("file" , file.file); try {
let res = await uploadImage(formData) const uploadFile = await this.compressFileItem(file);
this.vehicleLicenseFront = res.data; console.log('uploadFile',uploadFile)
await this.vehicleOcrHandler(); if (uploadFile.size > 5 * 1024 * 1024) {
this.onOversize();
return;
}
const formData = new FormData();
formData.append("file" , uploadFile);
let res = await uploadImage(formData)
this.vehicleLicenseFront = res.data;
await this.vehicleOcrHandler();
} catch (e) {
console.error('upload compress error:', e);
if (e && e.message === '超过5M') {
this.onOversize();
} else {
this.$toast(e && e.message ? e.message : '上传失败,请重试');
}
}
}, },
async vehicleLicenseBackHandler(file) { // 上传 行驶证副页 async vehicleLicenseBackHandler(file) { // 上传 行驶证副页
this.vehicleLicenseBackOcrFlag = true; try {
const formData = new FormData(); this.vehicleLicenseBackOcrFlag = true;
formData.append("file" , file.file); const uploadFile = await this.compressFileItem(file);
let res = await uploadImage(formData); if (uploadFile.size > 5 * 1024 * 1024) {
this.vehicleLicenseBack = res.data; this.onOversize();
await this.vehicleBackOcrHandler(); return;
}
const formData = new FormData();
formData.append("file" , uploadFile);
let res = await uploadImage(formData);
this.vehicleLicenseBack = res.data;
await this.vehicleBackOcrHandler();
} catch (e) {
console.error('upload compress error:', e);
if (e && e.message === '超过5M') {
this.onOversize();
} else {
this.$toast(e && e.message ? e.message : '上传失败,请重试');
}
}
}, },
async vehicleLicenseCarHandler(file) { // 上传 行驶证车辆照片 async vehicleLicenseCarHandler(file) { // 上传 行驶证车辆照片
const formData = new FormData(); try {
formData.append("file" , file.file); const uploadFile = await this.compressFileItem(file);
let res = await uploadImage(formData); if (uploadFile.size > 5 * 1024 * 1024) {
this.vehicleLicenseCarPhoto = res.data; this.onOversize();
return;
}
const formData = new FormData();
formData.append("file" , uploadFile);
let res = await uploadImage(formData);
this.vehicleLicenseCarPhoto = res.data;
} catch (e) {
console.error('upload compress error:', e);
if (e && e.message === '超过5M') {
this.onOversize();
} else {
this.$toast(e && e.message ? e.message : '上传失败,请重试');
}
}
}, },
async vehicleFrontPhotoHandler(file) { // 上传 车头照 async vehicleFrontPhotoHandler(file) { // 上传 车头照
const formData = new FormData(); try {
formData.append("file" , file.file); const uploadFile = await this.compressFileItem(file);
let res = await uploadImage(formData); if (uploadFile.size > 5 * 1024 * 1024) {
this.vehicleFrontPhoto = res.data; this.onOversize();
await this.ocrCarFrontHandler() return;
}
const formData = new FormData();
formData.append("file" , uploadFile);
let res = await uploadImage(formData);
this.vehicleFrontPhoto = res.data;
await this.ocrCarFrontHandler()
} catch (e) {
console.error('upload compress error:', e);
if (e && e.message === '超过5M') {
this.onOversize();
} else {
this.$toast(e && e.message ? e.message : '上传失败,请重试');
}
}
}, },
vehicleLicenseFrontDelete() { // 删除 行驶证首页 vehicleLicenseFrontDelete() { // 删除 行驶证首页
this.vehicleLicenseFront = ''; this.vehicleLicenseFront = '';