diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8f3a05b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +"* text=auto eol=lf" diff --git a/config.js b/config.js index 22b61a7..5252cd8 100644 --- a/config.js +++ b/config.js @@ -3,7 +3,7 @@ module.exports = { // baseUrl: 'http://172.16.129.101:8080/dev-api/', //baseUrl: 'http://pasd.gxsdxy.cn/prod-api/', // baseUrl: 'http://172.16.129.101:8080',//172.16.129.101 - //baseUrl: 'http://localhost:8080', + baseUrl: 'http://192.168.100.106:8080', // 应用信息 appInfo: { // 应用名称 diff --git a/manifest.json b/manifest.json index 3faefa6..72e5227 100644 --- a/manifest.json +++ b/manifest.json @@ -1,23 +1,31 @@ { - "name" : "平安水电移动端", - "appid" : "__UNI__3CA192A", - "description" : "", - "versionName" : "1.1.0", - "versionCode" : "100", - "transformPx" : false, - "app-plus" : { - "usingComponents" : true, - "nvueCompiler" : "uni-app", - "splashscreen" : { - "alwaysShowBeforeRender" : true, - "waiting" : true, - "autoclose" : true, - "delay" : 0 + "name": "平安水电移动端", + "appid": "__UNI__3CA192A", + "description": "", + "versionName": "1.1.0", + "versionCode": "100", + "transformPx": false, + "app-plus": { + "usingComponents": true, + "nvueCompiler": "uni-app", + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 }, - "modules" : {}, - "distribute" : { - "android" : { - "permissions" : [ + "modules": {}, + "permission": { + "Camera": { + "description": "需要访问相机以实现扫码功能" + }, + "Flashlight": { + "description": "需要访问闪光灯以支持扫码补光" + } + }, + "distribute": { + "android": { + "permissions": [ "", "", "", @@ -32,38 +40,54 @@ "", "", "", - "" + "", + "", + "" ] }, - "ios" : {}, - "sdkConfigs" : {} + "ios": { + "permissions": { + "Camera": { + "description": "需要访问相机以实现扫码功能" + }, + "PhotoLibraryAdd": { + "description": "需要访问相册以保存图片" + } + } + }, + "sdkConfigs": {} } }, - "quickapp" : {}, - "mp-weixin" : { - "appid" : "wx6caa681653417faa", - "setting" : { - "urlCheck" : false, - "es6" : false, - "minified" : true, - "postcss" : true + "quickapp": {}, + "mp-weixin": { + "appid": "wx6caa681653417faa", + "setting": { + "urlCheck": false, + "es6": false, + "minified": true, + "postcss": true }, - "optimization" : { - "subPackages" : true + "optimization": { + "subPackages": true }, - "usingComponents" : true + "permission": { + "scope.camera": { + "desc": "需要访问相机以实现扫码功能" + } + }, + "usingComponents": true }, - "vueVersion" : "2", - "h5" : { - "template" : "static/index.html", - "devServer" : { - "port" : 9090, - "https" : false + "vueVersion": "2", + "h5": { + "template": "static/index.html", + "devServer": { + "port": 9090, + "https": false }, - "title" : "RuoYi-App", - "router" : { - "mode" : "hash", - "base" : "./" + "title": "RuoYi-App", + "router": { + "mode": "hash", + "base": "./" } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index eed7b9b..e5f82b3 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ ] }, "dependencies": { - "echarts": "^5.5.1" + "@zxing/library": "^0.21.3", + "echarts": "^5.5.1", + "jsqr": "^1.4.0" } } diff --git a/pages/work/inspection/inspectionEx/index.vue b/pages/work/inspection/inspectionEx/index.vue index 742a25d..30800d8 100644 --- a/pages/work/inspection/inspectionEx/index.vue +++ b/pages/work/inspection/inspectionEx/index.vue @@ -20,7 +20,7 @@ - + diff --git a/pages/work/inspection/scanSign/index.vue b/pages/work/inspection/scanSign/index.vue index c6f0ed1..a012896 100644 --- a/pages/work/inspection/scanSign/index.vue +++ b/pages/work/inspection/scanSign/index.vue @@ -16,7 +16,7 @@ - + @@ -47,149 +47,204 @@ addWatermarkToImage } from "@/utils/watermark.js" export default { - // vue data() { return { form: { - inspectionType: 0, //默认常规巡检 - inspectorId: this.$store.state.user.nickName, //巡检人 - // 巡检点 + inspectionType: 0, + inspectorId: this.$store.state.user.nickName, inspectionPoint: "", - // 巡检要求 inspectionRequirements: "", inspectionImg: "", - ImgUrl: [] + ImgUrl: [], + remark: "" }, img: [], sourceType: ['camera'], - //存图片文件 imgFiles: "", - // 消息提示框 msgType: '', messageText: '', - isUploading: false, // 上传中标志 + isUploading: false, + isMobileBrowser: false // 改为更通用的移动浏览器检测标志 } }, methods: { - // 提交 submit() { if (this.isUploading) { - this.msgType = 'warning' - this.messageText = '图片正在上传中,请稍等' - this.$refs.alertDialog.open() + this.showMessage('warning', '图片正在上传中,请稍等'); return; } if (!Array.isArray(this.form.ImgUrl) || this.form.ImgUrl.length === 0) { - this.msgType = 'error' - this.messageText = `请选择要上传的图片` - this.$refs.alertDialog.open() + this.showMessage('error', '请选择要上传的图片'); return; } - this.form.inspectionImg = this.joinList() + this.form.inspectionImg = this.joinList(); addRecord(this.form).then(res => { if (res.code === 200) { - // console.log("sdfsadfsdfsdfsdfsdf"); - this.msgType = 'success' - this.messageText = `打卡成功` - this.$refs.alertDialog.open() - + this.showMessage('success', '打卡成功'); } else { - this.msgType = 'error' - this.messageText = `打卡失败` - this.$refs.alertDialog.open() - + this.showMessage('error', '打卡失败'); } - }) + }).catch(err => { + this.showMessage('error', `提交失败: ${err.message}`); + }); }, - // 图片删除 + deleteImg(e) { - //const index = this.img.findIndex(f => f.uuid === e.tempFile.uuid); // 假设文件通过 url 唯一标识 - const index = this.img.findIndex(f => f.path === e.tempFile.path); // 假设文件通过 url 唯一标识 + 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) + this.form.ImgUrl.splice(index, 1); + this.img.splice(index, 1); } }, - // 上传图片 + upload(e) { - console.log(e); - // this.img.push(e.tempFiles[0]) - // e.tempFilePaths.forEach(item => { - // uploadImg({ - // filePath: item - // }).then(res => { - // this.form.ImgUrl.push(res.fileName) - // }) - // }) - this.handleImageUpload(e.tempFiles[0]); + if (e.tempFiles && e.tempFiles.length > 0) { + this.handleImageUpload(e.tempFiles[0]); + } }, - // 取消 + cancel() { uni.reLaunch({ url: '/pages/work/index' - }) - uni.showToast({ - title: '打卡失败', - icon: 'error', // 成功图标 - duration: 1000 // 持续时间为2000ms }); - }, - // 定义一个方法,用于将list拼接成字符串 + joinList() { - // 使用数组的join方法,以逗号分隔元素 return this.form.ImgUrl.join(','); }, - /** 处理图片上传 --知无涯 */ async handleImageUpload(file) { - this.isUploading = true; // 开始上传 - - const that = this; + this.isUploading = true; + try { - if (!file) { + if (!file || !file.file) { throw new Error('无效的文件对象'); } - // 生成水印文字:巡检地点 + 巡检时间 - const times = this.getCurrentDate(); + // 生成水印文字 + const watermarkText = `${this.form.inspectionPoint || '未命名地点'} \n${this.getCurrentDate()}`; - const watermarkText = `${this.form.inspectionPoint || '未命名地点'} \n${times || '未设置时间'}`; - - // 添加水印 - 水印配置 - // const watermarkedFile = await addWatermarkToImage(file.file, watermarkText, { - // font: 'bold 20px Arial', // 加大字号并加粗 - // color: 'rgba(0, 0, 0, 0.7)' // 黑色,70%不透明度 - // }); - const watermarkedFile = await addWatermarkToImage(file.file, watermarkText); - - // 创建预览URL - const previewUrl = URL.createObjectURL(watermarkedFile); - - // 更新表单数据 - that.imgFiles = { - raw: watermarkedFile, - name: watermarkedFile.name, - url: previewUrl - }; - //上传图片,获取图片路径 - that.img.push(that.imgFiles) - await uploadImg({ - filePath: previewUrl - }).then(res => { - that.form.ImgUrl.push(res.fileName) - // console.log(res); - }) + // 添加水印 + let processedFile = await addWatermarkToImage(file.file, watermarkText); + + // 如果是移动浏览器且文件大于300KB,则进行压缩 + if (this.isMobileBrowser && processedFile.size > 300 * 1024) { + console.log('原始文件大小:', (processedFile.size / 1024).toFixed(2), 'KB'); + processedFile = await this.compressImageForMobile(processedFile); + console.log('压缩后文件大小:', (processedFile.size / 1024).toFixed(2), 'KB'); + } + // 上传处理后的文件 + const fileUrl = await this.uploadFile(processedFile); + + // 更新UI显示 + this.img.push({ + raw: processedFile, + name: processedFile.name, + url: fileUrl + }); + } catch (error) { - console.error("水印处理失败:", error); - proxy.$modal.msgError("图片处理失败: " + error.message); + console.error("图片处理失败:", error); + this.showMessage('error', `图片处理失败: ${error.message}`); } finally { - this.isUploading = false; // 上传完毕 + this.isUploading = false; } }, - // 获取当前时间 + + // 专门为移动浏览器优化的压缩方法 + 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(); @@ -202,34 +257,42 @@ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, - //对话框确定按钮 dialogConfirm() { if (this.msgType == 'success') { uni.reLaunch({ url: '/pages/work/index' - }) - return; - } else { - return; + }); } }, - + + 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; + } }, - // uniapp - //uniapp方法,在最开始的时候拿到传值过来的值 onLoad(option) { - const _this = this - // console.log('传递的值',option) - _this.form.inspectionPoint = option.inspectionPoint - _this.form.inspectionRequirements = option.inspectionRequirements - _this.form.inspectionPointId = option.inspectionPointId + this.form.inspectionPoint = option.inspectionPoint || ''; + this.form.inspectionRequirements = option.inspectionRequirements || ''; + this.form.inspectionPointId = option.inspectionPointId || ''; }, - created() { - // console.log("this.$store.state.user",this.$store.state.user); + mounted() { + this.checkMobileBrowser(); } } + \ No newline at end of file