336 lines
8.9 KiB
Vue
336 lines
8.9 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="container" :class="{isActive:isCode}">
|
|||
|
|
<custom-navbar title="资质认证" :showBack="true" backgroundColor="#fff"></custom-navbar>
|
|||
|
|
<view class="nocode" v-if="!isCode">
|
|||
|
|
<view class="node-title"> 输入验证码查看证件信息 </view>
|
|||
|
|
<view class="container-code">
|
|||
|
|
<view class="code-input">
|
|||
|
|
<input class="uni-input" v-model="value" maxlength="4" placeholder="请输入验证码"
|
|||
|
|
placeholder-class="code-input-placeholder" />
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<jp-verification-literalness ref="literalness" :contentWidth="115"
|
|||
|
|
:contentHeight="35"></jp-verification-literalness>
|
|||
|
|
</view>
|
|||
|
|
<view class="node-btn" :class="{ active: value.length == 4 }" @click="submit">
|
|||
|
|
查询
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode" v-if="isCode">
|
|||
|
|
<view class="isCode-title">资质认证</view>
|
|||
|
|
<view class="isCode-card" v-if="syrdetail.health_card">
|
|||
|
|
<view class="isCode-card-title">
|
|||
|
|
<image class="isCode-card-title__img" src="/static/images/syr/card.png" mode="aspectFit" />
|
|||
|
|
健康证
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode-card-card">
|
|||
|
|
<image class="isCode-card-card__img" :src="syrdetail.health_card" mode="widthFix" >
|
|||
|
|
</image>
|
|||
|
|
<wmWatermark text="美融融专用">
|
|||
|
|
</wmWatermark>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode-card" v-if="syrdetail.qualifications[0]">
|
|||
|
|
<view class="isCode-card-title">
|
|||
|
|
<image class="isCode-card-title__img" src="/static/images/syr/card.png" mode="aspectFit" />
|
|||
|
|
资质证书
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode-card-card">
|
|||
|
|
<image class="isCode-card-card__img" :src="syrdetail.qualifications[0]" mode="widthFix">
|
|||
|
|
</image>
|
|||
|
|
<wmWatermark text="美融融专用">
|
|||
|
|
</wmWatermark>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode-card" v-if="syrdetail.uscc_photo">
|
|||
|
|
<view class="isCode-card-title">
|
|||
|
|
<image class="isCode-card-title__img" src="/static/images/syr/card.png" mode="aspectFit" />
|
|||
|
|
营业执照
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode-card-card">
|
|||
|
|
<image class="isCode-card-card__img" :src="syrdetail.uscc_photo" mode="widthFix">
|
|||
|
|
</image>
|
|||
|
|
<wmWatermark text="美融融专用">
|
|||
|
|
</wmWatermark>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode-card" v-if="syrdetail.shop_photo">
|
|||
|
|
<view class="isCode-card-title">
|
|||
|
|
<image class="isCode-card-title__img" src="/static/images/syr/card.png" mode="aspectFit" />
|
|||
|
|
门头照片
|
|||
|
|
</view>
|
|||
|
|
<view class="isCode-card-card">
|
|||
|
|
<image class="isCode-card-card__img" :src="syrdetail.shop_photo" mode="aspectFill">
|
|||
|
|
</image>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<!-- 隐藏的canvas,用于绘制水印 -->
|
|||
|
|
<canvas
|
|||
|
|
canvas-id="watermark-canvas"
|
|||
|
|
style="width: 1px; height: 1px; position: absolute; left: -9999rpx; top: -9999rpx;"
|
|||
|
|
></canvas>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import wmWatermark from "@/components/wm-watermark/wm-watermark.vue";
|
|||
|
|
import request from "../../utils/request";
|
|||
|
|
export default {
|
|||
|
|
components: {
|
|||
|
|
wmWatermark
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
value: "",
|
|||
|
|
syrdetail: {},
|
|||
|
|
id: null,
|
|||
|
|
isCode: false, //验证是否通过
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
props: {
|
|||
|
|
tabsPopList: {
|
|||
|
|
type: Array,
|
|||
|
|
default: () => [],
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
onLoad(options) {
|
|||
|
|
console.log(options);
|
|||
|
|
this.id = options.id;
|
|||
|
|
this.getShopDetail(options.id);
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
// 在页面的 methods 中定义方法
|
|||
|
|
previewWithWatermark(imgUrl) {
|
|||
|
|
uni.downloadFile({
|
|||
|
|
url: imgUrl,
|
|||
|
|
success: (downloadRes) => {
|
|||
|
|
if (downloadRes.statusCode === 200 && downloadRes.tempFilePath) {
|
|||
|
|
// 确认临时路径存在
|
|||
|
|
this.addWatermark(downloadRes.tempFilePath);
|
|||
|
|
} else {
|
|||
|
|
console.error('图片下载失败,状态码:', downloadRes.statusCode);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('下载失败', err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 添加水印并预览
|
|||
|
|
addWatermark(originalImgPath) {
|
|||
|
|
// 获取图片信息(宽高)
|
|||
|
|
uni.getImageInfo({
|
|||
|
|
src: originalImgPath,
|
|||
|
|
success: (imgInfo) => {
|
|||
|
|
const { width, height } = imgInfo; // 原图宽高
|
|||
|
|
|
|||
|
|
// 步骤2:创建canvas(大小与原图一致)
|
|||
|
|
const canvasId = 'watermark-canvas'; // canvas 标识(需在页面中定义对应canvas)
|
|||
|
|
const ctx = uni.createCanvasContext(canvasId, this);
|
|||
|
|
|
|||
|
|
// 步骤3:绘制原图到canvas
|
|||
|
|
ctx.drawImage(originalImgPath, 0, 0, width, height);
|
|||
|
|
|
|||
|
|
// 步骤4:绘制文字水印(可自定义样式)
|
|||
|
|
const watermarkText = '我的水印'; // 水印文字
|
|||
|
|
ctx.setFontSize(20); // 字体大小
|
|||
|
|
ctx.setFillStyle('rgba(255, 255, 255, 0.5)'); // 文字颜色(半透明)
|
|||
|
|
ctx.setTextAlign('center'); // 文字对齐方式
|
|||
|
|
ctx.setTextBaseline('middle'); // 文字基线
|
|||
|
|
|
|||
|
|
// 旋转水印(可选,-30度倾斜)
|
|||
|
|
const rotateAngle = -30 * Math.PI / 180; // 角度转弧度
|
|||
|
|
const gap = 100; // 水印间距
|
|||
|
|
|
|||
|
|
// 重复绘制水印(铺满图片)
|
|||
|
|
for (let y = 0; y < height; y += gap) {
|
|||
|
|
for (let x = 0; x < width; x += gap) {
|
|||
|
|
ctx.save(); // 保存当前状态
|
|||
|
|
ctx.translate(x, y); // 移动到指定位置
|
|||
|
|
ctx.rotate(rotateAngle); // 旋转
|
|||
|
|
ctx.fillText(watermarkText, 0, 0); // 绘制文字
|
|||
|
|
ctx.restore(); // 恢复状态
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 绘制完成后导出图片
|
|||
|
|
ctx.draw(false, () => {
|
|||
|
|
// 步骤5:将canvas转为临时图片路径
|
|||
|
|
uni.canvasToTempFilePath({
|
|||
|
|
canvasId: canvasId,
|
|||
|
|
width: width,
|
|||
|
|
height: height,
|
|||
|
|
destWidth: width, // 输出图片宽度(与原图一致)
|
|||
|
|
destHeight: height, // 输出图片高度(与原图一致)
|
|||
|
|
success: (res) => {
|
|||
|
|
const watermarkImgPath = res.tempFilePath; // 带水印的图片路径
|
|||
|
|
// 步骤6:预览带水印的图片
|
|||
|
|
uni.previewImage({
|
|||
|
|
urls: [watermarkImgPath], // 预览的图片数组
|
|||
|
|
current: 0 // 初始显示第几张
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('canvas转图片失败', err);
|
|||
|
|
}
|
|||
|
|
}, this);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
console.error('获取图片信息失败', err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
// 获取手艺人详情
|
|||
|
|
getShopDetail(id) {
|
|||
|
|
request
|
|||
|
|
.post("/user/syrdetail", {
|
|||
|
|
id,
|
|||
|
|
})
|
|||
|
|
.then((res) => {
|
|||
|
|
this.syrdetail = res.data;
|
|||
|
|
})
|
|||
|
|
.catch((err) => {
|
|||
|
|
console.log(err);
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
submit() {
|
|||
|
|
if (this.value.length == 4) {
|
|||
|
|
this.isCode = this.$refs.literalness.verification(this.value);
|
|||
|
|
if(!this.isCode){
|
|||
|
|
uni.showToast({
|
|||
|
|
title: "验证码错误",
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
console.log(this.isCode);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="less">
|
|||
|
|
.container {
|
|||
|
|
background-color: #fff;
|
|||
|
|
min-height: 100vh;
|
|||
|
|
|
|||
|
|
.nocode {
|
|||
|
|
padding: 0 48rpx;
|
|||
|
|
|
|||
|
|
.node-title {
|
|||
|
|
font-weight: 500;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
line-height: 45rpx;
|
|||
|
|
text-align: center;
|
|||
|
|
font-style: normal;
|
|||
|
|
margin-top: 53rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.container-code {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
padding-bottom: 14rpx;
|
|||
|
|
border-bottom: 2rpx solid rgba(247, 249, 252, 1);
|
|||
|
|
|
|||
|
|
.code-input {
|
|||
|
|
flex: 1;
|
|||
|
|
|
|||
|
|
.code-input-placeholder {
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #c5c5c7;
|
|||
|
|
line-height: 40rpx;
|
|||
|
|
text-align: left;
|
|||
|
|
font-style: normal;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
margin-top: 90rpx;
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: nowrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.node-btn {
|
|||
|
|
width: 644rpx;
|
|||
|
|
height: 96rpx;
|
|||
|
|
background: #f7f9fc;
|
|||
|
|
border-radius: 48rpx;
|
|||
|
|
font-weight: 500;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #8e929f;
|
|||
|
|
line-height: 40rpx;
|
|||
|
|
text-align: left;
|
|||
|
|
font-style: normal;
|
|||
|
|
margin-top: 60rpx;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.node-btn.active {
|
|||
|
|
color: #fff;
|
|||
|
|
background: #ff3344;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.isCode {
|
|||
|
|
.isCode-title {
|
|||
|
|
font-weight: 500;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #000000;
|
|||
|
|
line-height: 45rpx;
|
|||
|
|
text-align: left;
|
|||
|
|
font-style: normal;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.isActive {
|
|||
|
|
background-color: transparent;
|
|||
|
|
padding: 25rpx 20rpx;
|
|||
|
|
.isCode-card{
|
|||
|
|
padding: 30rpx;
|
|||
|
|
background: #fff;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
margin-top: 20rpx;
|
|||
|
|
|
|||
|
|
|
|||
|
|
.isCode-card-title{
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 30rpx;
|
|||
|
|
color: #333333;
|
|||
|
|
line-height: 42rpx;
|
|||
|
|
text-align: left;
|
|||
|
|
font-style: normal;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
&__img{
|
|||
|
|
width: 36rpx;
|
|||
|
|
height: 30rpx;
|
|||
|
|
margin-right: 13rpx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.isCode-card-card{
|
|||
|
|
margin-top: 20rpx;
|
|||
|
|
width: 650rpx;
|
|||
|
|
// height: 300rpx;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
position: relative;
|
|||
|
|
&__img{
|
|||
|
|
width: 650rpx;
|
|||
|
|
// height: 300rpx;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|