Files
pasd_app/pages/work/inspection/scanSign/index.vue
2025-09-04 20:45:49 +08:00

333 lines
8.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<view class="example">
<uni-forms ref="dynamicForm" :model="form" label-width="80px">
<uni-forms-item label="巡检点" name="inspectionPoint">
<uni-easyinput disabled :value="form.inspectionPoint" placeholder="请输入巡检点"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="巡检要求" name="inspectionRequirements">
<uni-easyinput type="textarea" disabled :value="form.inspectionRequirements" placeholder="请输入巡检要求"></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="图片上传">
<view class="example-body">
<uni-file-picker limit="3" :sourceType="sourceType" :value="img" title="最多选择3张图片"
file-mediatype="image" @delete="deleteImg" @select="upload"
:auto-upload="false"></uni-file-picker>
</view>
</uni-forms-item>
<!-- 备注 -->
<uni-forms-item label="备注1" name="remark">
<uni-easyinput type="textarea" v-model="form.remark" placeholder="请输入备注"></uni-easyinput>
</uni-forms-item>
</uni-forms>
<view class="button-group">
<button class="btn btn-primary" @click="submit()">提交</button>
<button class="btn btn-cancel" @click="cancel()">取消</button>
</view>
</view>
<!-- 消息提示框 -->
<view>
<uni-popup ref="alertDialog" type="dialog">
<uni-popup-dialog :type="msgType" title="消息" :content="messageText" @confirm="dialogConfirm"
showClose="false"></uni-popup-dialog>
</uni-popup>
</view>
</view>
</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;
}
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}`);
});
},
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);
}
},
upload(e) {
if (e.tempFiles && e.tempFiles.length > 0) {
this.handleImageUpload(e.tempFiles[0]);
}
},
cancel() {
uni.reLaunch({
url: '/pages/work/index'
});
},
joinList() {
return this.form.ImgUrl.join(',');
},
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);
// }
});
},
// 专门为移动浏览器优化的压缩方法(保留兼容性)
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);
});
},
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);
});
});
},
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');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
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();
}
}
</script>
<style lang="scss">
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
height: 90vh;
/* 使页面高度占满整个视口 */
}
.container {
flex: 1;
/* 让 container 占满剩余空间 */
display: flex;
flex-direction: column;
/* 设置为列方向 */
}
.example {
flex: 1;
/* 让 example 占满 container 的剩余空间 */
display: flex;
flex-direction: column;
/* 设置为列方向,确保子元素垂直排列 */
padding: 15px;
background-color: #fff;
}
// 样式沉底
.button-group {
position: fixed;
bottom: 20px;
left: 0;
/* 使用 margin-top: auto 来将按钮组推到 example 容器的底部 */
display: flex;
width: 100%;
justify-content: space-around;
}
.button-group button {
flex: 1;
background: #fff;
color: #000;
/* 使按钮平分可用空间 */
/* 可能还需要设置一些其他的样式来确保按钮看起来正确,比如 text-align, padding 等 */
}
</style>