巡检点位页面上传图片添加水印
This commit is contained in:
parent
54d8eb1bd2
commit
fd4dc74849
@ -1,344 +0,0 @@
|
||||
<template>
|
||||
<view class="points">
|
||||
<view class="info-card">
|
||||
<view class="info-box">
|
||||
<view class="info-item" v-for="(item, index) in infoData" :key="index">
|
||||
<view><text class="grey">{{ item.key }}:</text>{{ item.value }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view
|
||||
scroll-x="true"
|
||||
class="content-scroll"
|
||||
:show-scrollbar="false"
|
||||
enable-flex
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in positionData"
|
||||
:key="index"
|
||||
:class="navCurIndex == index ? 'active' : ''"
|
||||
class="control-item"
|
||||
@click="changeTitle(index)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="collapse-box">
|
||||
<uni-collapse ref="collapseRef" v-model="collapseValue" accordion @change="changeCollapse">
|
||||
<uni-collapse-item v-for="(val, collapseIndex) in collapseData" :key="collapseIndex">
|
||||
<template v-slot:title>
|
||||
<uni-section class="section" :title="val.title" type="line"></uni-section>
|
||||
</template>
|
||||
<view class="content">
|
||||
<view class="content-item" v-for="(item, itemIndex) in val.children" :key="itemIndex">
|
||||
<view class="title">
|
||||
<view>{{ item.title }}</view>
|
||||
<uni-tag :inverted="true" :text="item.tag" :type="item.tag == '重点关注' ? 'error' : 'warning'" />
|
||||
</view>
|
||||
<view class="btn">
|
||||
<button size="mini" type="primary" @click="standard(item.standard)">巡检标准</button>
|
||||
<button size="mini" type="primary" @click="history(item.history)">巡检历史</button>
|
||||
</view>
|
||||
<view :class="item.selectedImg ? '' : 'input'" v-if="item.tag">
|
||||
<uni-easyinput class="textarea" type="textarea" v-model="item.described" placeholder="请输入" />
|
||||
<uni-file-picker class="picker" mode="grid" :sourceType="['camera']" file-mediatype="image" limit="9" v-model="item.imageValue" @progress="progress" @select="(e) => selectImg(item, e, collapseIndex, itemIndex)" @delete="deleteImg(item, $event)"><uni-icons type="camera-filled" color="#004894" size="50"></uni-icons></uni-file-picker>
|
||||
<!-- <WaterMarker :ref="el => { if (el) waterMarkRefs[`waterMarkRef_${collapseIndex}_${itemIndex}`] = el }"/> -->
|
||||
<hpy-watermark :ref="el => { if (el) waterMarkRefs[`waterMarkRef_${collapseIndex}_${itemIndex}`] = el }" @waterMark="(path) => waterMark(item, path)"></hpy-watermark>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="state"><text>状态:</text><uni-data-checkbox class="checkbox" mode="button" v-model="item.radio" :localdata="localdata"></uni-data-checkbox></view>
|
||||
<view v-if="item.radio != 0">
|
||||
<view class="described">描述:<uni-easyinput class="textarea" type="textarea" v-model="item.described" placeholder="请输入" /></view>
|
||||
<view>照片:<uni-file-picker class="picker" mode="grid" :sourceType="['camera']" file-mediatype="image" limit="9" v-model="item.imageValue" @select="selectImg(item,$event)" @delete="deleteImg(item, $event)"><uni-icons type="camera-filled" color="#004894" size="50"></uni-icons></uni-file-picker></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-collapse-item>
|
||||
</uni-collapse>
|
||||
</view>
|
||||
<uni-popup ref="alertDialog" type="dialog">
|
||||
<uni-popup-dialog type="warning" cancelText="关闭" confirmText="同意" title="通知" content="欢迎使用 uni-popup!" @confirm="dialogConfirm"
|
||||
@close="dialogClose"></uni-popup-dialog>
|
||||
</uni-popup>
|
||||
<uni-popup ref="popup" background-color="#fff" @change="changePopup">
|
||||
<view class="popup-content"><text class="text">{{ popValue }}</text></view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick, getCurrentInstance } from 'vue';
|
||||
import ImageWatermarkPicker from "@/components/image-watermark-picker.vue"
|
||||
import WaterMarker from '@/components/waterMarker.vue'
|
||||
import HpyWatermark from '@/uni_modules/hpy-watermark/components/hpy-watermark/hpy-watermark.vue'
|
||||
|
||||
let waterMarkRefs = reactive({})
|
||||
|
||||
// 弹出框内容
|
||||
let popValue = ref(null)
|
||||
let alertDialog = ref(null)
|
||||
|
||||
let navCurIndex = ref(0)
|
||||
// 详情信息
|
||||
let infoData = reactive([
|
||||
{ key: '点位名称', value: '厂外0.4KV供电点' },
|
||||
{ key: '点位编码', value: '' },
|
||||
])
|
||||
|
||||
// 标题信息
|
||||
let positionData = reactive([
|
||||
{ id: 1, title: "左岸" },
|
||||
{ id: 2, title: "右岸" },
|
||||
{ id: 3, title: "大坝" }
|
||||
])
|
||||
let collapseRef = ref(null)
|
||||
// 手风琴折叠面板默认展开内容
|
||||
let collapseValue = ref('0')
|
||||
// 手风琴数据
|
||||
let collapseData = reactive([
|
||||
{ id: 1, title: '左岸进水口配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
{ id: 2, title: '左岸排风竖井配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
{ id: 3, title: '左岸尾水管配电系统(南端)', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
{ id: 4, title: '左岸尾水管配电系统(北端)', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
{ id: 5, title: '左岸尾水洞出口配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
{ id: 6, title: '左岸水垫塘渗漏排水配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
{ id: 7, title: '左岸水垫塘检修排水配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
{ id: 8, title: '控制管理楼及左岸出线场配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
] },
|
||||
])
|
||||
|
||||
// 单选数据
|
||||
let localdata = reactive([
|
||||
{ text: '正常', value: 0 },
|
||||
{ text: '待观察', value: 1 },
|
||||
{ text: '异常', value: 2 }
|
||||
])
|
||||
|
||||
// 切换标题
|
||||
const changeTitle = (index) => {
|
||||
navCurIndex.value = index
|
||||
}
|
||||
|
||||
// 切换手风琴面板
|
||||
const changeCollapse = () => {
|
||||
// alertDialog.value.open()
|
||||
}
|
||||
|
||||
// 弹出框
|
||||
const changePopup = () => {
|
||||
|
||||
}
|
||||
|
||||
// 确认
|
||||
const dialogConfirm = () => {
|
||||
|
||||
}
|
||||
|
||||
// 取消
|
||||
const dialogClose = () => {
|
||||
|
||||
}
|
||||
|
||||
const waterMark = (item, path) => {
|
||||
console.log(path);
|
||||
item.imageValue.push({ url: path });
|
||||
console.log(item.imageValue);
|
||||
};
|
||||
|
||||
// 选择图片
|
||||
const selectImg = (item, e, collapseIndex, itemIndex) => {
|
||||
item.selectedImg = true
|
||||
// 获取对应的ref key
|
||||
const refKey = `waterMarkRef_${collapseIndex}_${itemIndex}`
|
||||
const waterMarkerInstance = waterMarkRefs[refKey]
|
||||
console.log(waterMarkerInstance);
|
||||
|
||||
if (waterMarkerInstance) {
|
||||
// const imgFileArr = waterMarkerInstance.callAddWaterMark(e.tempFilePaths);
|
||||
// imgFileArr.forEach((el) => {
|
||||
// item.imageValue.push({
|
||||
// url: el,
|
||||
// extname: el.substring(el.lastIndexOf(".") + 1),
|
||||
// name: el,
|
||||
// });
|
||||
// })
|
||||
console.log(waterMarkerInstance);
|
||||
|
||||
var fillTexts = ["人员:张三", "地址:广东省珠海市香洲区XXX"];
|
||||
fillTexts.push("时间:");
|
||||
// 添加水印
|
||||
waterMarkerInstance.addWaterMark({
|
||||
filePaths: e.tempFilePaths,
|
||||
fillTexts
|
||||
});
|
||||
} else {
|
||||
console.warn('未找到对应的WaterMarker实例或方法未暴露', refKey, waterMarkerInstance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const progress = (item, index) => {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: item.map((o) => o.url),
|
||||
});
|
||||
}
|
||||
|
||||
// 删除选择的图片
|
||||
const deleteImg = (item,e) => {
|
||||
item.imageValue.splice(e.index, 1)
|
||||
console.log(item, e)
|
||||
|
||||
if (item.imageValue.length == 0) {
|
||||
item.selectedImg = false
|
||||
}
|
||||
}
|
||||
|
||||
// 巡检标准
|
||||
const standard = (val) => {
|
||||
popup.value.open()
|
||||
popValue.value = val
|
||||
}
|
||||
|
||||
// 巡检历史
|
||||
const history = (val) => {
|
||||
popup.value.open()
|
||||
popValue.value = val
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.points {
|
||||
.content-scroll {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
white-space: nowrap;
|
||||
.control-item {
|
||||
width: 160rpx;
|
||||
height: 35rpx;
|
||||
line-height: 35rpx;
|
||||
display: inline-block;
|
||||
padding: 0 20rpx;
|
||||
margin-left: 30rpx;
|
||||
position: relative;
|
||||
&.active {
|
||||
padding: 15rpx 20rpx!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.collapse-box {
|
||||
margin: 10rpx 30rpx;
|
||||
border-radius: 10rpx;
|
||||
padding: 10rpx;
|
||||
background: #fff;
|
||||
:deep(.uni-icons) {
|
||||
color: #1464BB!important;
|
||||
}
|
||||
}
|
||||
|
||||
.content-item {
|
||||
padding: 20rpx;
|
||||
margin: 0 20rpx 20rpx;
|
||||
background: #F1F7FD;
|
||||
border-radius: 10rpx;
|
||||
.title, .btn, .input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.title {
|
||||
color: #004895;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.btn {
|
||||
:deep(uni-button) {
|
||||
margin:30rpx 20rpx 30rpx 0!important;
|
||||
}
|
||||
}
|
||||
.input {
|
||||
.textarea {
|
||||
width: 400rpx;
|
||||
flex: none!important;
|
||||
}
|
||||
.picker {
|
||||
margin-left: 10rpx;
|
||||
:deep(.uni-file-picker__container) {
|
||||
width: 580rpx;
|
||||
height: 200rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
// .warp {
|
||||
// display: block !important;
|
||||
// :deep(.uni-file-picker__container) {
|
||||
// width: auto !important;
|
||||
// height: auto !important;
|
||||
// }
|
||||
// }
|
||||
.state {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.checkbox {
|
||||
:deep(.uni-label-pointer) {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.described {
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
.textarea, .picker {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -18,7 +18,7 @@
|
||||
<uni-icons type="camera-filled" color="#004894" size="50"></uni-icons>
|
||||
</view>
|
||||
</uni-file-picker>
|
||||
<view class="watermark-canvas">
|
||||
<view class="watermark-canvas" v-if="canvasWidth !== '0px' && canvasHeight !== '0px'">
|
||||
<canvas
|
||||
id="watermark-canvas"
|
||||
:style="{ width: canvasWidth, height: canvasHeight }"
|
||||
@ -56,6 +56,10 @@ export default {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
watermarkTexts: {
|
||||
type: [Array, String],
|
||||
default: null
|
||||
},
|
||||
// #ifdef VUE3
|
||||
modelValue: {
|
||||
type: Array,
|
||||
@ -74,12 +78,12 @@ export default {
|
||||
},
|
||||
// #endif
|
||||
},
|
||||
emits: ['input', 'update:modelValue'],
|
||||
emits: ['input', 'update:modelValue', 'change', 'selectImg'],
|
||||
data() {
|
||||
return {
|
||||
imageValue: [],
|
||||
canvasWidth: '1080px',
|
||||
canvasHeight: '2160px',
|
||||
canvasWidth: '0px', // 初始为0,页面加载不渲染canvas
|
||||
canvasHeight: '0px',
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -90,7 +94,7 @@ export default {
|
||||
// #ifndef VUE3
|
||||
this.$emit('input', newVal)
|
||||
// #endif
|
||||
// this.$emit('change', newVal)
|
||||
this.$emit('change', newVal)
|
||||
},
|
||||
// #ifndef VUE3
|
||||
value: {
|
||||
@ -139,7 +143,22 @@ export default {
|
||||
})
|
||||
},
|
||||
async select(e) {
|
||||
this.$emit('selectImg', true)
|
||||
|
||||
for (let tempFile of e.tempFiles) {
|
||||
// 先压缩图片
|
||||
let compressedPath = tempFile.path;
|
||||
try {
|
||||
const compressRes = await uni.compressImage({
|
||||
src: tempFile.path,
|
||||
quality: 60, // 你可以根据实际情况调整
|
||||
width: 500, // 限制宽度
|
||||
height: 500 // 限制高度
|
||||
});
|
||||
compressedPath = compressRes.tempFilePath;
|
||||
} catch (err) {
|
||||
// 压缩失败就用原图
|
||||
}
|
||||
await this.watermarkProcess(tempFile)
|
||||
}
|
||||
},
|
||||
@ -173,23 +192,29 @@ export default {
|
||||
// 设置画布高度和宽度
|
||||
this.canvasWidth = `${res.width}px`
|
||||
this.canvasHeight = `${res.height}px`
|
||||
await this.sleep(1000) // 某些平台 canvas 渲染慢,需要等待
|
||||
this.$nextTick(() => {
|
||||
await this.sleep(200) // 某些平台 canvas 渲染慢,需要等待
|
||||
const ctx = uni.createCanvasContext('watermark-canvas', this)
|
||||
|
||||
ctx.clearRect(0, 0, res.width, res.height)
|
||||
ctx.beginPath()
|
||||
ctx.drawImage(tempFilePath, 0, 0, res.width, res.height)
|
||||
|
||||
// 水印 字体大小,颜色,内容,位置
|
||||
ctx.beginPath()
|
||||
ctx.setFontSize(24)
|
||||
ctx.setFillStyle('rgba(250,250,250,0.8)')
|
||||
ctx.fillText('我是水印1', 60, res.height - 90)
|
||||
ctx.fillText('我是水印2', 60, res.height - 60)
|
||||
// 动态绘制水印内容
|
||||
if (Array.isArray(this.watermarkTexts)) {
|
||||
this.watermarkTexts.forEach((text, idx) => {
|
||||
ctx.fillText(text, 60, res.height - 90 + idx * 30)
|
||||
})
|
||||
} else if (typeof this.watermarkTexts === 'string') {
|
||||
ctx.fillText('拍摄人:'+this.watermarkTexts, 60, res.height - 90)
|
||||
}
|
||||
ctx.fillText('拍摄时间:'+this.getCurrentDateTime(), 60, res.height - 60)
|
||||
|
||||
// 开始绘制 (canvas -> 临时文件路径)
|
||||
ctx.draw(false, async () => {
|
||||
await this.sleep(1000) // 某些平台 canvas 渲染慢,需要等待
|
||||
|
||||
await this.sleep(300) // 某些平台 canvas 渲染慢,需要等待
|
||||
|
||||
uni.canvasToTempFilePath(
|
||||
{
|
||||
@ -246,6 +271,18 @@ export default {
|
||||
setTimeout(resolve, millisecond)
|
||||
})
|
||||
},
|
||||
// 获取当前日期时间,格式:2025-06-09 14:30:15
|
||||
getCurrentDateTime() {
|
||||
const now = new Date();
|
||||
const pad = n => n.toString().padStart(2, '0');
|
||||
const year = now.getFullYear();
|
||||
const month = pad(now.getMonth() + 1);
|
||||
const day = pad(now.getDate());
|
||||
const hour = pad(now.getHours());
|
||||
const minute = pad(now.getMinutes());
|
||||
const second = pad(now.getSeconds());
|
||||
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -254,13 +291,13 @@ export default {
|
||||
.image-picker {
|
||||
position: relative;
|
||||
|
||||
.form-item-column-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
// .form-item-column-center {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// flex: 1;
|
||||
// flex-direction: column;
|
||||
// }
|
||||
|
||||
.watermark-canvas {
|
||||
position: absolute;
|
||||
|
@ -1,147 +0,0 @@
|
||||
<!--
|
||||
* @Author: XHC
|
||||
* @Date: 2025-06-06 15:36:04
|
||||
* @LastEditors: XHC
|
||||
* @LastEditTime: 2025-06-06 16:38:39
|
||||
* @Description:
|
||||
-->
|
||||
<template>
|
||||
<canvas v-show="waterMarkParams.display" canvas-id="waterMarkCanvas" :style="canvasStyle" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, computed, nextTick, defineExpose } from 'vue';
|
||||
|
||||
let waterMarkParams = reactive({
|
||||
display: false, // 控制 canvas 创建与销毁
|
||||
canvasWidth: 300, // 默认宽度
|
||||
canvasHeight: 225, // 默认高度
|
||||
contentHeight: 170, // 将要被绘制到图像中的矩形的高度(px)
|
||||
})
|
||||
let username= ref("YourUsername") // 假设的用户名
|
||||
// 画布
|
||||
const canvasStyle = computed(() => {
|
||||
return {
|
||||
position: "fixed", // 移除到屏幕外
|
||||
left: "9999px",
|
||||
width: waterMarkParams.canvasWidth + "px",
|
||||
height: waterMarkParams.canvasHeight + "px",
|
||||
}
|
||||
|
||||
})
|
||||
// 因为有可能在相册中选择多个图片,所以这里要依次生成水印
|
||||
async function callAddWaterMark(imgPathArr) {
|
||||
let results = [];
|
||||
if (imgPathArr.length > 0) {
|
||||
let addIndex = 0;
|
||||
while (addIndex < imgPathArr.length) {
|
||||
const tempFilePath = await addWaterMark(imgPathArr[addIndex]);
|
||||
results.push(tempFilePath);
|
||||
addIndex = addIndex + 1;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
// 添加水印
|
||||
function addWaterMark(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 获取图片信息,配置 canvas 尺寸
|
||||
uni.getImageInfo({
|
||||
src,
|
||||
success: (res) => {
|
||||
// 修复部分手机(如红米9)手机屏幕比较窄拍摄出来的图片水印压缩着覆盖的问题
|
||||
waterMarkParams.canvasWidth = Math.max(res.width, 886);
|
||||
waterMarkParams.canvasHeight = res.height;
|
||||
waterMarkParams.display = true;
|
||||
console.log("当前图片信息waterMarkParams:", waterMarkParams);
|
||||
// 等待 canvas 元素创建
|
||||
nextTick(() => {
|
||||
let context = uni.createCanvasContext("waterMarkCanvas", this);
|
||||
/* 绘制 */
|
||||
const {
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
contentHeight
|
||||
} =
|
||||
waterMarkParams;
|
||||
// 绘制前清空画布
|
||||
context.clearRect(0, 0, canvasWidth, canvasHeight);
|
||||
// 将图片src放到cancas内,宽高必须为图片大小
|
||||
context.drawImage(
|
||||
src,
|
||||
0,
|
||||
0,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
canvasWidth,
|
||||
canvasHeight
|
||||
);
|
||||
// 设置边框的透明度
|
||||
context.setGlobalAlpha(0.3);
|
||||
context.beginPath();
|
||||
// 绘制底部的白色背景
|
||||
context.rect(
|
||||
0,
|
||||
canvasHeight - contentHeight,
|
||||
canvasWidth,
|
||||
contentHeight
|
||||
);
|
||||
// context.setFillStyle("white"); // 白色背景
|
||||
context.fill();
|
||||
// 设置文字的透明度
|
||||
context.setGlobalAlpha(1);
|
||||
// 3.绘制底部的文字
|
||||
context.setFontSize(32);
|
||||
context.setTextAlign("left");
|
||||
context.setFillStyle("white"); // 显示字为白色
|
||||
context.fillText(`拍摄人:${username.value}`, 50, canvasHeight -
|
||||
120);
|
||||
context.fillText(
|
||||
`拍摄时间:${new Date()
|
||||
}`,
|
||||
50,
|
||||
canvasHeight - 70
|
||||
);
|
||||
// 一定要加上一个定时器否则进入到页面第一次可能会无法正常拍照,后几次才正常
|
||||
setTimeout(() => {
|
||||
// 本次绘画完重开开始绘画,并且在绘画完毕之后再保存图片,不然页面可能会出现白屏等情况
|
||||
context.draw(false, () => {
|
||||
console.log("!!!!!开始绘画", canvasWidth,
|
||||
canvasHeight);
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: "waterMarkCanvas",
|
||||
fileType: "jpg",
|
||||
width: canvasWidth,
|
||||
height: canvasHeight,
|
||||
destWidth: canvasWidth,
|
||||
destHeight: canvasHeight,
|
||||
success: ({
|
||||
tempFilePath
|
||||
}) => {
|
||||
console.log("绘制成功",
|
||||
tempFilePath
|
||||
);
|
||||
waterMarkParams
|
||||
.display =
|
||||
false;
|
||||
resolve(
|
||||
tempFilePath
|
||||
);
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
console.log(err);
|
||||
},
|
||||
},
|
||||
this
|
||||
);
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 暴露方法给父组件调用
|
||||
defineExpose({ callAddWaterMark })
|
||||
</script>
|
@ -2,7 +2,7 @@
|
||||
* @Author: XHC
|
||||
* @Date: 2025-05-19 11:07:37
|
||||
* @LastEditors: XHC
|
||||
* @LastEditTime: 2025-06-06 17:40:38
|
||||
* @LastEditTime: 2025-06-09 09:40:25
|
||||
* @Description: 首页
|
||||
-->
|
||||
<template>
|
||||
@ -199,7 +199,6 @@ onReachBottom(() => {
|
||||
|
||||
// 根据滚动距离以推断是否有显示返回顶部功能
|
||||
onPageScroll((e) => {
|
||||
console.log('Scroll position:', e.scrollTop);
|
||||
isShow.value = e.scrollTop >= 200
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @Author: XHC
|
||||
* @Date: 2025-05-19 15:19:14
|
||||
* @LastEditors: XHC
|
||||
* @LastEditTime: 2025-06-03 09:23:19
|
||||
* @LastEditTime: 2025-06-09 15:57:18
|
||||
* @Description: 我的
|
||||
-->
|
||||
<template>
|
||||
@ -83,9 +83,9 @@ const goToPages = (index) => {
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
uni.navigateTo({
|
||||
url: '/pages/points/points'
|
||||
});
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/points/points'
|
||||
// });
|
||||
break
|
||||
default:
|
||||
break;
|
||||
|
@ -42,15 +42,13 @@
|
||||
</view>
|
||||
<view :class="item.selectedImg ? '' : 'input'" v-if="item.tag">
|
||||
<uni-easyinput class="textarea" type="textarea" v-model="item.described" placeholder="请输入" />
|
||||
<uni-file-picker class="picker" mode="grid" :sourceType="['camera']" file-mediatype="image" limit="9" v-model="item.imageValue" @progress="progress" @select="(e) => selectImg(item, e, collapseIndex, itemIndex)" @delete="deleteImg(item, $event)"><uni-icons type="camera-filled" color="#004894" size="50"></uni-icons></uni-file-picker>
|
||||
<!-- <WaterMarker :ref="el => { if (el) waterMarkRefs[`waterMarkRef_${collapseIndex}_${itemIndex}`] = el }"/> -->
|
||||
<hpy-watermark :ref="el => { if (el) waterMarkRefs[`waterMarkRef_${collapseIndex}_${itemIndex}`] = el }" @waterMark="(path) => waterMark(item, path)"></hpy-watermark>
|
||||
<ImageWatermarkPicker class="picker" v-model="item.imageValue" limit="9" @selectImg="selectImg($event,item)" @change="changeImg($event, item)" :watermark-texts="item.watermarkTexts"></ImageWatermarkPicker>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="state"><text>状态:</text><uni-data-checkbox class="checkbox" mode="button" v-model="item.radio" :localdata="localdata"></uni-data-checkbox></view>
|
||||
<view v-if="item.radio != 0">
|
||||
<view class="described">描述:<uni-easyinput class="textarea" type="textarea" v-model="item.described" placeholder="请输入" /></view>
|
||||
<view>照片:<uni-file-picker class="picker" mode="grid" :sourceType="['camera']" file-mediatype="image" limit="9" v-model="item.imageValue" @select="selectImg(item,$event)" @delete="deleteImg(item, $event)"><uni-icons type="camera-filled" color="#004894" size="50"></uni-icons></uni-file-picker></view>
|
||||
<view>照片:<ImageWatermarkPicker class="picker" v-model="item.imageValue" limit="9" @selectImg="selectImg($event,item)" @change="changeImg($event, item)" :watermark-texts="item.watermarkTexts"></ImageWatermarkPicker></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -71,10 +69,6 @@
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick, getCurrentInstance } from 'vue';
|
||||
import ImageWatermarkPicker from "@/components/image-watermark-picker.vue"
|
||||
import WaterMarker from '@/components/waterMarker.vue'
|
||||
import HpyWatermark from '@/uni_modules/hpy-watermark/components/hpy-watermark/hpy-watermark.vue'
|
||||
|
||||
let waterMarkRefs = reactive({})
|
||||
|
||||
// 弹出框内容
|
||||
let popValue = ref(null)
|
||||
@ -97,62 +91,62 @@ let collapseRef = ref(null)
|
||||
// 手风琴折叠面板默认展开内容
|
||||
let collapseValue = ref('0')
|
||||
// 手风琴数据
|
||||
let collapseData = reactive([
|
||||
let collapseData = ref([
|
||||
{ id: 1, title: '左岸进水口配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六'},
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
{ id: 2, title: '左岸排风竖井配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六' },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
{ id: 3, title: '左岸尾水管配电系统(南端)', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六' },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
{ id: 4, title: '左岸尾水管配电系统(北端)', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六' },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
{ id: 5, title: '左岸尾水洞出口配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六' },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
{ id: 6, title: '左岸水垫塘渗漏排水配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六' },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
{ id: 7, title: '左岸水垫塘检修排水配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六' },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
{ id: 8, title: '控制管理楼及左岸出线场配电系统', children: [
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [] }
|
||||
{ title: '环境温湿度(°C/%)', tag: '重点关注', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '张三' },
|
||||
{ title: 'Ⅰ段干式变三相绕组温度', tag: '请确认', described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], selectedImg: false, watermarkTexts: '李四' },
|
||||
{ title: '带电显示装置及电磁锁正常;铁芯端部无散片、流胶;', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '王五' },
|
||||
{ title: '盘柜无异常声音、气味;无放电、过热现象外观正常;开关状态及指示灯正常',radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '赵六' },
|
||||
{ title: '备自投及指示灯正常', radio: 0, described: '', standard: '巡检标准', history: '巡检历史', imageValue: [], watermarkTexts: '张三' }
|
||||
] },
|
||||
])
|
||||
|
||||
@ -188,64 +182,18 @@ const dialogClose = () => {
|
||||
|
||||
}
|
||||
|
||||
const waterMark = (item, path) => {
|
||||
console.log(path);
|
||||
item.imageValue.push({
|
||||
name:"file.png",
|
||||
extname:"png",
|
||||
url: path,
|
||||
// ...
|
||||
});
|
||||
console.log(item.imageValue);
|
||||
};
|
||||
|
||||
// 选择图片
|
||||
const selectImg = (item, e, collapseIndex, itemIndex) => {
|
||||
item.selectedImg = true
|
||||
// 获取对应的ref key
|
||||
const refKey = `waterMarkRef_${collapseIndex}_${itemIndex}`
|
||||
const waterMarkerInstance = waterMarkRefs[refKey]
|
||||
if (waterMarkerInstance) {
|
||||
// const imgFileArr = waterMarkerInstance.callAddWaterMark(e.tempFilePaths);
|
||||
// imgFileArr.forEach((el) => {
|
||||
// item.imageValue.push({
|
||||
// url: el,
|
||||
// extname: el.substring(el.lastIndexOf(".") + 1),
|
||||
// name: el,
|
||||
// });
|
||||
// })
|
||||
console.log(waterMarkerInstance);
|
||||
|
||||
var fillTexts = ["人员:张三", "地址:广东省珠海市香洲区XXX"];
|
||||
fillTexts.push("时间:");
|
||||
// 添加水印
|
||||
waterMarkerInstance.addWaterMark({
|
||||
filePaths: e.tempFilePaths,
|
||||
fillTexts
|
||||
});
|
||||
} else {
|
||||
console.warn('未找到对应的WaterMarker实例或方法未暴露', refKey, waterMarkerInstance)
|
||||
}
|
||||
const selectImg = (e, item) => {
|
||||
console.log(e);
|
||||
item.selectedImg = e
|
||||
}
|
||||
|
||||
|
||||
const progress = (item, index) => {
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: item.map((o) => o.url),
|
||||
});
|
||||
}
|
||||
|
||||
// 删除选择的图片
|
||||
const deleteImg = (item,e) => {
|
||||
item.imageValue.splice(e.index, 1)
|
||||
console.log(item, e)
|
||||
|
||||
if (item.imageValue.length == 0) {
|
||||
item.selectedImg = false
|
||||
}
|
||||
// 上传图片发生变化
|
||||
const changeImg = (e, item) => {
|
||||
if (!e.length) item.selectedImg = false
|
||||
}
|
||||
|
||||
|
||||
// 巡检标准
|
||||
const standard = (val) => {
|
||||
popup.value.open()
|
||||
|
@ -1,5 +0,0 @@
|
||||
## 1.0.6(2023-04-08)
|
||||
去掉无用依赖
|
||||
## 1.0.5(2023-04-08)
|
||||
- 修复H5有些图片出现半截空白
|
||||
- 有问题请描述使用场景,最好能把图片贴出来,以便更好的优化兼容性
|
@ -1,198 +0,0 @@
|
||||
<template>
|
||||
<view class="watermark-content">
|
||||
<canvas canvas-id="watermarkCanvas" id="watermarkCanvas" :style="{width:canvasWidth + 'px', height:canvasHeight + 'px'}"></canvas>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// export default {
|
||||
// name:'hpy-watermark',
|
||||
import { ref } from "vue";
|
||||
|
||||
const emit = defineEmits(['waterMark'])
|
||||
const props = defineProps({
|
||||
/**
|
||||
* 文字文字位置(默认:左下角)可选值:左上角:topLeft、右上角:topRight、左下角:bottomLeft、右下角:bottomRight
|
||||
*/
|
||||
markAlign:{
|
||||
type:String,
|
||||
default:function(){
|
||||
return 'bottomLeft'
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 设置文本的水平对齐方式,默认:start,文本在指定的位置开始。
|
||||
* end 文本在指定的位置结束。
|
||||
* center 文本的中心被放置在指定的位置。
|
||||
* left 文本左对齐。
|
||||
* right 文本右对齐。
|
||||
*/
|
||||
textAlign:{
|
||||
type:String,
|
||||
default:function(){
|
||||
return 'start';
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 设置文本的垂直对齐方式,默认:alphabetic文本基线是普通的字母基线。
|
||||
* top 文本基线是 em 方框的顶端。
|
||||
* hanging 文本基线是悬挂基线。
|
||||
* middle 文本基线是 em 方框的正中。
|
||||
* ideographic 文本基线是表意基线。
|
||||
* bottom 文本基线是 em 方框的底端。
|
||||
*/
|
||||
textBaseline:{
|
||||
type:String,
|
||||
default:function(){
|
||||
return 'alphabetic';
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 文字大小
|
||||
*/
|
||||
fontSize:{
|
||||
type:[Number, String],
|
||||
default:40
|
||||
},
|
||||
/**
|
||||
* 文字颜色
|
||||
*/
|
||||
fontColor:{
|
||||
type:String,
|
||||
default:function(){
|
||||
return '#FFFFFF'
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 阴影颜色
|
||||
*/
|
||||
shadowColor:{
|
||||
type:String,
|
||||
default:function(){
|
||||
return 'rgba(0, 0, 0, 1.0)';
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 阴影边框大小
|
||||
*/
|
||||
shadowWidth:{
|
||||
type:[Number, String],
|
||||
default:2
|
||||
},
|
||||
/**
|
||||
* 图片的质量,取值范围为 (0, 1],不在范围内时当作1处理
|
||||
*/
|
||||
quality:{
|
||||
type:[Number, String],
|
||||
default:1
|
||||
},
|
||||
/**
|
||||
* 目标文件的类型,只支持 'jpg' 或 'png'。默认为 'png'
|
||||
*/
|
||||
fileType:{
|
||||
type:String,
|
||||
default:function(){
|
||||
return 'png'
|
||||
}
|
||||
}
|
||||
})
|
||||
let canvasWidth = ref(0)
|
||||
let canvasHeight = ref(0)
|
||||
/**
|
||||
* 增加水印
|
||||
* @param {Object} {filePaths:['图片地址1', '图片地址2'], fillTexts:['水印1', '水印2']}
|
||||
*/
|
||||
async function addWaterMark({ filePaths = [], fillTexts = [] }) {
|
||||
console.log('开始添加水印', filePaths, fillTexts);
|
||||
|
||||
uni.showLoading({title:'图片处理中···'});
|
||||
try{
|
||||
for (const filePath of filePaths) {
|
||||
await drawImage(filePath, fillTexts.reverse());
|
||||
}
|
||||
}catch(e){
|
||||
// TODO handle the exception
|
||||
}finally{
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 绘制单个图片
|
||||
*/
|
||||
async function drawImage(filePath, fillTexts){
|
||||
const ctx = uni.createCanvasContext('watermarkCanvas', this);
|
||||
return new Promise(resolve => {
|
||||
uni.getImageInfo({
|
||||
src: filePath,
|
||||
success: (image) => {
|
||||
console.log(image);
|
||||
|
||||
canvasWidth.value = image.width;
|
||||
canvasHeight.value = image.height;
|
||||
ctx.clearRect(0, 0, image.width, image.height);
|
||||
setTimeout(()=>{
|
||||
ctx.drawImage(image.path, 0, 0, image.width, image.height);
|
||||
ctx.setFontSize(props.fontSize);
|
||||
ctx.setFillStyle(props.fontColor);
|
||||
// 设置阴影
|
||||
let shadowWidth = Number(props.shadowWidth + "");
|
||||
if(shadowWidth > 0){
|
||||
ctx.shadowColor = props.shadowColor;
|
||||
ctx.shadowOffsetX = shadowWidth;
|
||||
ctx.shadowOffsetY = shadowWidth;
|
||||
}
|
||||
// 设置水平对齐方式
|
||||
ctx.textAlign = props.textAlign;
|
||||
// 设置垂直对齐方式
|
||||
ctx.textBaseline = props.textBaseline;
|
||||
const maxText = fillTexts.reduce((text, val) => {
|
||||
return text.length >= val.length ? text : val;
|
||||
});
|
||||
fillTexts.forEach((mark, index) => {
|
||||
if(props.markAlign == "bottomRight"){
|
||||
ctx.fillText(mark, image.width - (ctx.measureText(maxText).width+60), image.height - (index*60+60));
|
||||
}else if(props.markAlign == "topLeft"){
|
||||
ctx.fillText(mark, 20, (index*60+60));
|
||||
}else if(props.markAlign == "topRight"){
|
||||
ctx.fillText(mark, image.width - (ctx.measureText(maxText).width+60), (index*60+60));
|
||||
}else{
|
||||
ctx.fillText(mark, 20, image.height - (index*60+60));
|
||||
}
|
||||
});
|
||||
ctx.draw(false, (() => {
|
||||
setTimeout(()=>{
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'watermarkCanvas',
|
||||
fileType:props.fileType,
|
||||
quality:Number(props.quality + "" || "1"),
|
||||
success: (res) => {
|
||||
console.log(res);
|
||||
|
||||
emit('waterMark', res.tempFilePath);
|
||||
},
|
||||
fail:(err) => {
|
||||
console.log(err)
|
||||
},
|
||||
complete: () => {
|
||||
resolve();
|
||||
}
|
||||
}, this);
|
||||
}, 300);
|
||||
})());
|
||||
}, 200);
|
||||
},
|
||||
fail: (e) => {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
addWaterMark
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.watermark-content{width: 0;height: 0;overflow: hidden;}
|
||||
</style>
|
@ -1,83 +0,0 @@
|
||||
{
|
||||
"id": "hpy-watermark",
|
||||
"displayName": "文字水印",
|
||||
"version": "1.0.6",
|
||||
"description": "图片增加文字水印,支持拍照和相册选取多张",
|
||||
"keywords": [
|
||||
"水印",
|
||||
"图片水印",
|
||||
"文字水印",
|
||||
"watermark"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": ""
|
||||
},
|
||||
"dcloudext": {
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "",
|
||||
"type": "component-vue"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,201 +0,0 @@
|
||||
|
||||
## 图片增加文字水印
|
||||
|
||||
> **组件名:hpy-watermark
|
||||
> 图片增加文字水印,支持拍照和相册选取多张
|
||||
|
||||
## API
|
||||
|
||||
## Props
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>属性名</th>
|
||||
<th>类型</th>
|
||||
<th>默认值</th>
|
||||
<th>说明</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>markAlign</td>
|
||||
<td>String</td>
|
||||
<td>左下角</td>
|
||||
<td>文字文字位置(默认:左下角)可选值:左上角:topLeft、右上角:topRight、左下角:bottomLeft、右下角:bottomRight</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>fontSize</td>
|
||||
<td>Number</td>
|
||||
<td>40</td>
|
||||
<td>文字大小,默认:40</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>fontColor</td>
|
||||
<td>String</td>
|
||||
<td>白色</td>
|
||||
<td>文字颜色,默认:#FFFFFF</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>quality</td>
|
||||
<td>Number</td>
|
||||
<td>1</td>
|
||||
<td>图片的质量,取值范围为 (0, 1],不在范围内时当作1.0处理</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>fileType</td>
|
||||
<td>String</td>
|
||||
<td>jpg</td>
|
||||
<td>目标文件的类型,只支持 'jpg' 或 'png'。默认为 'jpg'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>shadowColor</td>
|
||||
<td>String</td>
|
||||
<td>黑色</td>
|
||||
<td>阴影颜色,默认:rgba(0, 0, 0, 1.0)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>shadowWidth</td>
|
||||
<td>Number</td>
|
||||
<td>2</td>
|
||||
<td>阴影边框大小,默认:2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>textAlign</td>
|
||||
<td>String</td>
|
||||
<td>start</td>
|
||||
<td>设置文本的水平对齐方式,默认:start,文本在指定的位置开始。 start、end、center、left、right</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>textBaseline</td>
|
||||
<td>String</td>
|
||||
<td>alphabetic</td>
|
||||
<td>设置文本的垂直对齐方式,默认:alphabetic文本基线是普通的字母基线。top、hanging、middle、ideographic、bottom</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
## methods
|
||||
<table>
|
||||
<tr>
|
||||
<th>参数名</th>
|
||||
<th>类型</th>
|
||||
<th>说明</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>addWaterMark</td>
|
||||
<td>Object</td>
|
||||
<td>{filePaths:['图片地址1', '图片地址2'], fillTexts:['水印文字1', '水印文字2']}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 使用示例
|
||||
|
||||
```html
|
||||
<template>
|
||||
<view>
|
||||
<button @click="chooseImage">选择照片</button>
|
||||
<!-- 增加水印 -->
|
||||
<hpy-watermark ref="watermark" @waterMark="waterMark"></hpy-watermark>
|
||||
<view class="ul">
|
||||
<view class="li" v-for="(item, index) in imageList" :key="index">
|
||||
<image :src="item" class="img" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
|
||||
```javascript
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
imageList:[]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 选择图片
|
||||
chooseImage() {
|
||||
uni.chooseImage({
|
||||
count: this.limit, // 限制的图片数量
|
||||
sizeType: ['compressed'], // original 原图,compressed 压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'],// album 从相册选图,camera 使用相机,默认二者都有
|
||||
success: (res) => {
|
||||
var imgPathList = res.tempFilePaths;
|
||||
if(imgPathList.length > 0){
|
||||
this.addImages(imgPathList);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('chooseImage fail', err)
|
||||
if("chooseImage:fail cancel" == err.errMsg){
|
||||
uni.showToast({
|
||||
icon:'none',
|
||||
title:'取消了选择'
|
||||
});
|
||||
}else{
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.album'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: '系统上传需要从您的相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加图片
|
||||
addImages(filePaths){
|
||||
if(filePaths.length > 0){
|
||||
var fillTexts = ["人员:张三", "地址:广东省珠海市香洲区XXX"];
|
||||
fillTexts.push("时间:" + this.getNowTime());
|
||||
// 添加水印
|
||||
this.$refs.watermark.addWaterMark({
|
||||
filePaths,
|
||||
fillTexts
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 水印添加回调,在H5平台下,filePath 为 base64
|
||||
*/
|
||||
waterMark(filePath){
|
||||
this.imageList.push(filePath);
|
||||
},
|
||||
/**
|
||||
* 获取当前时间
|
||||
*/
|
||||
getNowTime(){
|
||||
var date = new Date(),
|
||||
year = date.getFullYear(),
|
||||
month = date.getMonth() + 1,
|
||||
day = date.getDate(),
|
||||
hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(),
|
||||
minute = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(),
|
||||
second = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
month >= 1 && month <= 9 ? (month = "0" + month) : "";
|
||||
day >= 0 && day <= 9 ? (day = "0" + day) : "";
|
||||
return (year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
```
|
||||
|
||||
```style
|
||||
<style scoped>
|
||||
.ul{border: rgb(221, 221, 221) solid 1px; text-align: center; margin-right: 12px; position: relative }
|
||||
.ul .li .img{display:block; width: 80px; height: 80px;}
|
||||
</style>
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user