修改
This commit is contained in:
@@ -37,251 +37,196 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
uploadImg
|
||||
} from "@/api/system/user"
|
||||
import {
|
||||
addRecord
|
||||
} from "@/api/inspection/record.js"
|
||||
import {
|
||||
addWatermarkToImage
|
||||
} from "@/utils/watermark.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
inspectionType: 0,
|
||||
inspectorId: this.$store.state.user.nickName,
|
||||
inspectionPoint: "",
|
||||
inspectionRequirements: "",
|
||||
inspectionImg: "",
|
||||
ImgUrl: [],
|
||||
remark: ""
|
||||
},
|
||||
img: [],
|
||||
sourceType: ['camera'],
|
||||
imgFiles: "",
|
||||
msgType: '',
|
||||
messageText: '',
|
||||
isUploading: false,
|
||||
isMobileBrowser: false // 改为更通用的移动浏览器检测标志
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
if (this.isUploading) {
|
||||
this.showMessage('warning', '图片正在上传中,请稍等');
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(this.form.ImgUrl) || this.form.ImgUrl.length === 0) {
|
||||
this.showMessage('error', '请选择要上传的图片');
|
||||
return;
|
||||
}
|
||||
import { addRecord } from "@/api/inspection/record.js"
|
||||
// 如果你已有 uploadImg 封装且内部就是 uni.uploadFile,可以继续用;
|
||||
// 但前提是它支持 H5 直接传 File 对象(不是 URL 字符串)。
|
||||
// 这里我示范“直接用 uni.uploadFile”的写法,更稳妥。
|
||||
import { addWatermarkToImage } from "@/utils/watermark.js"
|
||||
import appConfig from '@/config'
|
||||
const UPLOAD_URL = appConfig.baseUrl + "/common/upload" // 按你后端改
|
||||
|
||||
this.form.inspectionImg = this.joinList();
|
||||
addRecord(this.form).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.showMessage('success', '打卡成功');
|
||||
} else {
|
||||
this.showMessage('error', '打卡失败');
|
||||
}
|
||||
}).catch(err => {
|
||||
this.showMessage('error', `提交失败: ${err.message}`);
|
||||
});
|
||||
},
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
inspectionType: 0,
|
||||
inspectorId: this.$store.state.user.nickName,
|
||||
inspectionPoint: "",
|
||||
inspectionRequirements: "",
|
||||
inspectionImg: "",
|
||||
ImgUrl: [], // 存后端返回的文件名/URL
|
||||
remark: ""
|
||||
},
|
||||
img: [], // 绑定给 uni-file-picker 的预览列表
|
||||
sourceType: ['camera'],
|
||||
msgType: '',
|
||||
messageText: '',
|
||||
isUploading: false,
|
||||
isMobileBrowser: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async submit() {
|
||||
if (this.isUploading) {
|
||||
this.showMessage('warning', '图片正在上传中,请稍等')
|
||||
return
|
||||
}
|
||||
if (!Array.isArray(this.form.ImgUrl) || this.form.ImgUrl.length === 0) {
|
||||
this.showMessage('error', '请选择要上传的图片')
|
||||
return
|
||||
}
|
||||
this.form.inspectionImg = this.joinList()
|
||||
try {
|
||||
const res = await addRecord(this.form)
|
||||
if (res.code === 200) {
|
||||
this.showMessage('success', '打卡成功')
|
||||
} else {
|
||||
this.showMessage('error', '打卡失败')
|
||||
}
|
||||
} catch (err) {
|
||||
this.showMessage('error', `提交失败: ${err.message}`)
|
||||
}
|
||||
},
|
||||
|
||||
deleteImg(e) {
|
||||
const index = this.img.findIndex(f => f.path === e.tempFile.path);
|
||||
if (index !== -1) {
|
||||
this.form.ImgUrl.splice(index, 1);
|
||||
this.img.splice(index, 1);
|
||||
}
|
||||
},
|
||||
// uni-file-picker 删除:e.tempFile 里通常有 {url/path},与你传给 value 的结构需一致
|
||||
deleteImg(e) {
|
||||
const url = e.tempFile?.url || e.tempFile?.path
|
||||
const idx = this.img.findIndex(x => x.url === url)
|
||||
if (idx !== -1) {
|
||||
this.img.splice(idx, 1)
|
||||
// 同步移除已上传结果(按你的业务,可以用同索引移除或按返回名移除)
|
||||
this.form.ImgUrl.splice(idx, 1)
|
||||
}
|
||||
},
|
||||
|
||||
upload(e) {
|
||||
if (e.tempFiles && e.tempFiles.length > 0) {
|
||||
this.handleImageUpload(e.tempFiles[0]);
|
||||
}
|
||||
},
|
||||
// 选择文件(支持多张)
|
||||
async upload(e) {
|
||||
if (!e?.tempFiles?.length) return
|
||||
if (this.isUploading) {
|
||||
this.showMessage('warning', '图片正在上传中,请稍等')
|
||||
return
|
||||
}
|
||||
|
||||
this.isUploading = true
|
||||
try {
|
||||
// 逐张处理
|
||||
for (const tf of e.tempFiles) {
|
||||
await this.handleImageUpload(tf) // 这里传入每个 tempFile
|
||||
}
|
||||
this.showMessage('success', '图片处理/上传完成')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
this.showMessage('error', `图片上传失败:${err.message || err}`)
|
||||
} finally {
|
||||
this.isUploading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 单张处理:加水印 ->(可选)压缩 -> 上传
|
||||
async handleImageUpload(tempFile) {
|
||||
// tempFile.file: H5 下是 File 对象;App/小程序是临时路径
|
||||
const raw = tempFile.file || tempFile // 兼容各端
|
||||
// 生成水印文字
|
||||
const watermarkText = `${this.form.inspectionPoint || '未命名地点'} \n${this.getCurrentDate()}`
|
||||
// 加水印(返回 File/Blob)
|
||||
const watermarked = await addWatermarkToImage(raw, watermarkText)
|
||||
// 可选:移动端压缩(你已有方法,按需启用)
|
||||
// const finalFile = await this.compressImageForMobile(watermarked)
|
||||
|
||||
cancel() {
|
||||
uni.reLaunch({
|
||||
url: '/pages/work/index'
|
||||
});
|
||||
},
|
||||
const finalFile = watermarked
|
||||
|
||||
joinList() {
|
||||
return this.form.ImgUrl.join(',');
|
||||
},
|
||||
// 预览:用本地 URL,仅供前端显示
|
||||
const previewUrl = URL.createObjectURL(finalFile)
|
||||
this.img.push({
|
||||
url: previewUrl, // uni-file-picker 识别 url
|
||||
name: finalFile.name || `image_${Date.now()}.jpg`,
|
||||
extname: 'jpg'
|
||||
})
|
||||
|
||||
handleImageUpload(file) {
|
||||
if (this.isUploading) {
|
||||
this.showMessage('warning', '图片正在上传中,请稍等');
|
||||
return;
|
||||
}
|
||||
|
||||
this.isUploading = true;
|
||||
|
||||
// 添加水印
|
||||
this.addWatermarkToImage(file, (watermarkedFile) => {
|
||||
// 检查是否为移动浏览器且文件大小大于300KB
|
||||
// if (this.checkMobileBrowser() && watermarkedFile.size > 300 * 1024) {
|
||||
// 压缩图片
|
||||
// this.compressImageForMobile(watermarkedFile, (compressedFile) => {
|
||||
// 上传文件
|
||||
// this.uploadFile(compressedFile);
|
||||
// });
|
||||
// } else {
|
||||
// 直接上传
|
||||
this.uploadFile(watermarkedFile);
|
||||
// }
|
||||
});
|
||||
},
|
||||
|
||||
// 真正上传:**不要传 previewUrl 字符串**,而是传二进制 `file`
|
||||
// H5 下:uni.uploadFile 支持传 `file: File`
|
||||
const uploadedName = await this.uploadFileWithUni(finalFile)
|
||||
// 回填后端返回的文件名/URL
|
||||
this.form.ImgUrl.push(uploadedName)
|
||||
},
|
||||
|
||||
|
||||
// 专门为移动浏览器优化的压缩方法(保留兼容性)
|
||||
compressImageForMobile(file, quality = 0.6, maxWidth = 1200, maxHeight = 1200) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = (event) => {
|
||||
img.onload = () => {
|
||||
// 计算压缩比例
|
||||
let width = img.width;
|
||||
let height = img.height;
|
||||
|
||||
// 限制最大尺寸
|
||||
if (width > maxWidth || height > maxHeight) {
|
||||
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
||||
width = Math.floor(width * ratio);
|
||||
height = Math.floor(height * ratio);
|
||||
}
|
||||
|
||||
// 创建canvas
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置更高的压缩质量
|
||||
ctx.imageSmoothingQuality = 'high';
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
|
||||
// 使用toBlob的polyfill保证兼容性
|
||||
if (canvas.toBlob) {
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
if (!blob) {
|
||||
console.warn('压缩失败,返回原始文件');
|
||||
resolve(file);
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建压缩后的文件对象
|
||||
const compressedFile = new File([blob], file.name, {
|
||||
type: 'image/jpeg',
|
||||
lastModified: Date.now()
|
||||
});
|
||||
|
||||
resolve(compressedFile);
|
||||
},
|
||||
'image/jpeg',
|
||||
quality
|
||||
);
|
||||
} else {
|
||||
// 不支持toBlob的浏览器直接返回原文件
|
||||
console.warn('浏览器不支持toBlob方法,无法压缩');
|
||||
resolve(file);
|
||||
}
|
||||
};
|
||||
|
||||
img.onerror = () => {
|
||||
console.warn('图片加载失败,返回原始文件');
|
||||
resolve(file);
|
||||
};
|
||||
|
||||
img.src = event.target.result;
|
||||
};
|
||||
|
||||
reader.onerror = () => {
|
||||
console.warn('文件读取失败,返回原始文件');
|
||||
resolve(file);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
},
|
||||
// 用 uni.uploadFile 直接传二进制
|
||||
uploadFileWithUni(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: UPLOAD_URL,
|
||||
name: 'file', // 后端接收字段名(按你的后端改)
|
||||
file, // H5 直接传 File 对象(重点!)
|
||||
// 如果后端还需要额外字段:
|
||||
// formData: { bizType: 'inspection' },
|
||||
success: (res) => {
|
||||
try {
|
||||
const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
|
||||
if (data.code === 200) {
|
||||
// 假设后端返回 { code:200, fileName: 'xxx.jpg', url:'...' }
|
||||
resolve(data.fileName || data.url)
|
||||
} else {
|
||||
reject(new Error(data.msg || '上传失败'))
|
||||
}
|
||||
} catch (e) {
|
||||
reject(new Error('上传响应解析失败'))
|
||||
}
|
||||
},
|
||||
fail: (err) => reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
async uploadFile(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建预览URL用于显示
|
||||
const previewUrl = URL.createObjectURL(file);
|
||||
|
||||
// 实际上传
|
||||
uploadImg({
|
||||
filePath: previewUrl
|
||||
}).then(res => {
|
||||
this.form.ImgUrl.push(res.fileName);
|
||||
resolve(previewUrl);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
uni.reLaunch({ url: '/pages/work/index' })
|
||||
},
|
||||
|
||||
getCurrentDate() {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const hours = String(now.getHours()).padStart(2, '0');
|
||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
joinList() {
|
||||
return this.form.ImgUrl.join(',')
|
||||
},
|
||||
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
},
|
||||
getCurrentDate() {
|
||||
const now = new Date()
|
||||
const y = now.getFullYear()
|
||||
const m = String(now.getMonth() + 1).padStart(2, '0')
|
||||
const d = String(now.getDate()).padStart(2, '0')
|
||||
const hh = String(now.getHours()).padStart(2, '0')
|
||||
const mm = String(now.getMinutes()).padStart(2, '0')
|
||||
const ss = String(now.getSeconds()).padStart(2, '0')
|
||||
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
|
||||
},
|
||||
|
||||
dialogConfirm() {
|
||||
if (this.msgType == 'success') {
|
||||
uni.reLaunch({
|
||||
url: '/pages/work/index'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
showMessage(type, text) {
|
||||
this.msgType = type;
|
||||
this.messageText = text;
|
||||
this.$refs.alertDialog.open();
|
||||
},
|
||||
|
||||
// 检测移动浏览器环境
|
||||
checkMobileBrowser() {
|
||||
// 更全面的移动设备检测
|
||||
const userAgent = navigator.userAgent.toLowerCase();
|
||||
const isMobile = /iphone|ipod|android|windows phone|mobile|blackberry/.test(userAgent);
|
||||
|
||||
// 如果是通过uni-app的web-view打开,也认为是移动环境
|
||||
this.isMobileBrowser = isMobile || window.__uniAppWebview;
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.form.inspectionPoint = option.inspectionPoint || '';
|
||||
this.form.inspectionRequirements = option.inspectionRequirements || '';
|
||||
this.form.inspectionPointId = option.inspectionPointId || '';
|
||||
},
|
||||
mounted() {
|
||||
this.checkMobileBrowser();
|
||||
}
|
||||
}
|
||||
dialogConfirm() {
|
||||
if (this.msgType === 'success') {
|
||||
uni.reLaunch({ url: '/pages/work/index' })
|
||||
}
|
||||
},
|
||||
|
||||
showMessage(type, text) {
|
||||
this.msgType = type
|
||||
this.messageText = text
|
||||
this.$refs.alertDialog.open()
|
||||
},
|
||||
|
||||
checkMobileBrowser() {
|
||||
const ua = navigator.userAgent.toLowerCase()
|
||||
const isMobile = /iphone|ipod|android|windows phone|mobile|blackberry/.test(ua)
|
||||
this.isMobileBrowser = isMobile || window.__uniAppWebview
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.form.inspectionPoint = option.inspectionPoint || ''
|
||||
this.form.inspectionRequirements = option.inspectionRequirements || ''
|
||||
this.form.inspectionPointId = option.inspectionPointId || ''
|
||||
},
|
||||
mounted() {
|
||||
this.checkMobileBrowser()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
display: flex;
|
||||
|
Reference in New Issue
Block a user