提交
This commit is contained in:
@@ -6,7 +6,8 @@
|
|||||||
<uni-easyinput disabled :value="form.inspectionPoint" placeholder="请输入巡检点"></uni-easyinput>
|
<uni-easyinput disabled :value="form.inspectionPoint" placeholder="请输入巡检点"></uni-easyinput>
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
<uni-forms-item label="巡检要求" name="inspectionRequirements">
|
<uni-forms-item label="巡检要求" name="inspectionRequirements">
|
||||||
<uni-easyinput type="textarea" disabled :value="form.inspectionRequirements" placeholder="请输入巡检要求"></uni-easyinput>
|
<uni-easyinput type="textarea" disabled :value="form.inspectionRequirements"
|
||||||
|
placeholder="请输入巡检要求"></uni-easyinput>
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
<uni-forms-item label="图片上传">
|
<uni-forms-item label="图片上传">
|
||||||
<view class="example-body">
|
<view class="example-body">
|
||||||
@@ -37,15 +38,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { addRecord } from "@/api/inspection/record.js"
|
import {
|
||||||
// 如果你已有 uploadImg 封装且内部就是 uni.uploadFile,可以继续用;
|
addRecord
|
||||||
// 但前提是它支持 H5 直接传 File 对象(不是 URL 字符串)。
|
} from "@/api/inspection/record.js"
|
||||||
// 这里我示范“直接用 uni.uploadFile”的写法,更稳妥。
|
// 如果你已有 uploadImg 封装且内部就是 uni.uploadFile,可以继续用;
|
||||||
import { addWatermarkToImage } from "@/utils/watermark.js"
|
// 但前提是它支持 H5 直接传 File 对象(不是 URL 字符串)。
|
||||||
import appConfig from '@/config'
|
// 这里我示范“直接用 uni.uploadFile”的写法,更稳妥。
|
||||||
const UPLOAD_URL = appConfig.baseUrl + "/common/upload" // 按你后端改
|
import {
|
||||||
|
addWatermarkToImage
|
||||||
|
} from "@/utils/watermark.js"
|
||||||
|
import appConfig from '@/config'
|
||||||
|
const UPLOAD_URL = appConfig.baseUrl + "/common/upload" // 按你后端改
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {
|
form: {
|
||||||
@@ -113,7 +118,7 @@ export default {
|
|||||||
for (const tf of e.tempFiles) {
|
for (const tf of e.tempFiles) {
|
||||||
await this.handleImageUpload(tf) // 这里传入每个 tempFile
|
await this.handleImageUpload(tf) // 这里传入每个 tempFile
|
||||||
}
|
}
|
||||||
this.showMessage('success', '图片处理/上传完成')
|
// this.showMessage('success', '图片处理/上传完成')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
this.showMessage('error', `图片上传失败:${err.message || err}`)
|
this.showMessage('error', `图片上传失败:${err.message || err}`)
|
||||||
@@ -161,7 +166,8 @@ export default {
|
|||||||
// formData: { bizType: 'inspection' },
|
// formData: { bizType: 'inspection' },
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
try {
|
try {
|
||||||
const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
|
const data = typeof res.data === 'string' ? JSON.parse(res.data) : res
|
||||||
|
.data
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
// 假设后端返回 { code:200, fileName: 'xxx.jpg', url:'...' }
|
// 假设后端返回 { code:200, fileName: 'xxx.jpg', url:'...' }
|
||||||
resolve(data.fileName || data.url)
|
resolve(data.fileName || data.url)
|
||||||
@@ -178,7 +184,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
uni.reLaunch({ url: '/pages/work/index' })
|
uni.reLaunch({
|
||||||
|
url: '/pages/work/index'
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
joinList() {
|
joinList() {
|
||||||
@@ -198,7 +206,9 @@ export default {
|
|||||||
|
|
||||||
dialogConfirm() {
|
dialogConfirm() {
|
||||||
if (this.msgType === 'success') {
|
if (this.msgType === 'success') {
|
||||||
uni.reLaunch({ url: '/pages/work/index' })
|
uni.reLaunch({
|
||||||
|
url: '/pages/work/index'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -212,7 +222,133 @@ export default {
|
|||||||
const ua = navigator.userAgent.toLowerCase()
|
const ua = navigator.userAgent.toLowerCase()
|
||||||
const isMobile = /iphone|ipod|android|windows phone|mobile|blackberry/.test(ua)
|
const isMobile = /iphone|ipod|android|windows phone|mobile|blackberry/.test(ua)
|
||||||
this.isMobileBrowser = isMobile || window.__uniAppWebview
|
this.isMobileBrowser = isMobile || window.__uniAppWebview
|
||||||
|
},
|
||||||
|
// 计算目标尺寸
|
||||||
|
calcTargetSize(imgW, imgH, maxW, maxH) {
|
||||||
|
let w = imgW,
|
||||||
|
h = imgH
|
||||||
|
if (w > maxW || h > maxH) {
|
||||||
|
const ratio = Math.min(maxW / w, maxH / h)
|
||||||
|
w = Math.round(w * ratio)
|
||||||
|
h = Math.round(h * ratio)
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
w,
|
||||||
|
h
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// iOS 兼容 toBlob(老 Safari)
|
||||||
|
canvasToBlob(canvas, type, quality) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (canvas.toBlob) {
|
||||||
|
canvas.toBlob((blob) => resolve(blob), type, quality)
|
||||||
|
} else {
|
||||||
|
// fallback: toDataURL -> Blob
|
||||||
|
const dataURL = canvas.toDataURL(type, quality)
|
||||||
|
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)
|
||||||
|
resolve(new Blob([u8arr], {
|
||||||
|
type: mime
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// H5: DataURL -> File
|
||||||
|
blobToFile(blob, filename) {
|
||||||
|
return new File([blob], filename || `img_${Date.now()}.jpg`, {
|
||||||
|
type: blob.type || 'image/jpeg'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩图片(移动端友好)
|
||||||
|
* @param {File|Object|String} input H5: File;小程序/APP:tempFile 对象或临时路径
|
||||||
|
* @param {Object} opts { quality: 0.6, maxWidth: 1200, maxHeight: 1200, mime: 'image/jpeg' }
|
||||||
|
* @returns Promise<File|string> H5 返回 File;小程序/APP 返回压缩后的临时路径
|
||||||
|
*/
|
||||||
|
async compressImageForMobile(input, opts = {}) {
|
||||||
|
const {
|
||||||
|
quality = 0.6,
|
||||||
|
maxWidth = 1200,
|
||||||
|
maxHeight = 1200,
|
||||||
|
mime = 'image/jpeg'
|
||||||
|
} = opts
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
// —— H5:使用 canvas 压缩 —— //
|
||||||
|
const file = input instanceof File ? input : (input?.file instanceof File ? input.file : null)
|
||||||
|
if (!file) return input // 没拿到 File 就直接返回原始值
|
||||||
|
|
||||||
|
// 读取为 dataURL
|
||||||
|
const dataURL = await new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = () => resolve(reader.result)
|
||||||
|
reader.onerror = () => reject(new Error('文件读取失败'))
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 图片加载
|
||||||
|
const img = await new Promise((resolve, reject) => {
|
||||||
|
const image = new Image()
|
||||||
|
image.onload = () => resolve(image)
|
||||||
|
image.onerror = () => reject(new Error('图片加载失败'))
|
||||||
|
image.src = dataURL
|
||||||
|
})
|
||||||
|
|
||||||
|
const {
|
||||||
|
w,
|
||||||
|
h
|
||||||
|
} = this.calcTargetSize(img.width, img.height, maxWidth, maxHeight)
|
||||||
|
// 如果尺寸本来就不大,直接走质量压缩(或原图)
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
canvas.width = w
|
||||||
|
canvas.height = h
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
ctx.imageSmoothingQuality = 'high'
|
||||||
|
ctx.drawImage(img, 0, 0, w, h)
|
||||||
|
|
||||||
|
const blob = await this.canvasToBlob(canvas, mime, quality)
|
||||||
|
if (!blob) return file
|
||||||
|
|
||||||
|
// 若压缩后反而更大,则返回原图
|
||||||
|
if (blob.size > file.size) return file
|
||||||
|
|
||||||
|
return this.blobToFile(blob, file.name)
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN || APP-PLUS
|
||||||
|
// —— 小程序 / APP:使用 uni.compressImage —— //
|
||||||
|
// 允许传入 input 为对象(如 tempFile)或字符串路径
|
||||||
|
const srcPath = typeof input === 'string' ?
|
||||||
|
input :
|
||||||
|
(input?.tempFilePath || input?.path || input?.filePath)
|
||||||
|
|
||||||
|
if (!srcPath) return input
|
||||||
|
|
||||||
|
// uni.compressImage 文档:quality 0-100,部分端支持 width/height
|
||||||
|
const q = Math.max(1, Math.min(100, Math.round(quality * 100)))
|
||||||
|
|
||||||
|
// 尝试带上 width/height(端上不支持也会忽略)
|
||||||
|
const compressed = await new Promise((resolve, reject) => {
|
||||||
|
uni.compressImage({
|
||||||
|
src: srcPath,
|
||||||
|
quality: q,
|
||||||
|
width: maxWidth,
|
||||||
|
height: maxHeight,
|
||||||
|
success: (res) => resolve(res.tempFilePath || res.apFilePath || res.target ||
|
||||||
|
res.path),
|
||||||
|
fail: (err) => reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return compressed
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
},
|
},
|
||||||
onLoad(option) {
|
onLoad(option) {
|
||||||
this.form.inspectionPoint = option.inspectionPoint || ''
|
this.form.inspectionPoint = option.inspectionPoint || ''
|
||||||
@@ -222,7 +358,7 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.checkMobileBrowser()
|
this.checkMobileBrowser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@@ -273,6 +409,4 @@ export default {
|
|||||||
/* 使按钮平分可用空间 */
|
/* 使按钮平分可用空间 */
|
||||||
/* 可能还需要设置一些其他的样式来确保按钮看起来正确,比如 text-align, padding 等 */
|
/* 可能还需要设置一些其他的样式来确保按钮看起来正确,比如 text-align, padding 等 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
Reference in New Issue
Block a user