refactor: 重构多个组件以支持 Vue 3 语法和功能

- 将多个组件转换为 `<script setup>` 语法,提升可读性和性能
- 优化状态管理和事件处理逻辑,简化代码结构
- 更新样式和布局以适应新组件结构
- 添加新功能和修复已知问题,提升用户体验
This commit is contained in:
Yer11214
2026-07-08 18:37:11 +08:00
parent 4d0b0fb5e4
commit 349ffa4f34
189 changed files with 18278 additions and 20758 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div class="index">
<view class="index">
<view v-model="show" class="slot-content">
<image @click="downLoad()" class="img" :src="imgUrl" />
<div class="canvas-hide">
@@ -11,181 +11,153 @@
<!-- #endif -->
</div>
</view>
</div>
</view>
</template>
<script>
<script setup lang="ts">
import { ref, onMounted, getCurrentInstance } from 'vue'
// 引入绘制插件
import DrawPoster from "@/js_sdk/u-draw-poster";
import DrawPoster from "@/js_sdk/u-draw-poster"
// 生成二维码
import uQRCode from '@/components/Sansnn-uQRCode/uqrcode.js';
import logoImg from "@/pages/passport/static/logo-title.png";
import myFaceImg from "@/pages/passport/static/missing-face.png";
import uQRCode from '@/components/Sansnn-uQRCode/uqrcode.js'
import logoImg from "@/pages/passport/static/logo-title.png"
import myFaceImg from "@/pages/passport/static/missing-face.png"
export default {
data: () => ({
imgUrl: "", //绘制出来的图片路径
show: false, //是否展示模态框
dp: {}, //绘制的dp对象用于存储绘制等一些方法。
logo: logoImg, // 本地logo地址
myFace: myFaceImg, // 本地默认头像
sharingLink: '', // 二维码链接
}),
props: {
/**
* 父级传参的数据
*/
res: {
type: null,
default: "",
},
},
onUnload() {},
onReady() {},
methods: {
/** 解决微信小程序中图片模糊问题 */
// #ifdef MP-WEIXIN
st2: (size) => size * 2,
// #endif
const instance = getCurrentInstance()
// #ifndef MP-WEIXIN
st2: (size) => size,
// #endif
const props = defineProps<{
res?: any
}>()
/** 保存图片 */
downLoad() {
uni.saveImageToPhotosAlbum({
filePath: this.imgUrl,
success: function () {
uni.showToast({title: "保存成功!",icon: "none",});
},
fail: function () {
uni.showToast({title: "保存失败,请稍后重试!",icon: "none",});
},
});
},
/** 创建canvas */
async init() {
this.show = true;
this.dp = await DrawPoster.build({
selector: "canvas",
componentThis: this,
loading: true,
debugging: true,
});
let dp = this.dp;
// #ifdef MP-WEIXIN
// 用于微信小程序中画布错乱问题
dp.canvas.width = this.st2(560);
dp.canvas.height = this.st2(800);
// #endif
this.showQRCode(dp);
},
/** 生成二维码 */
async showQRCode(dp){
await uQRCode.make({
canvasId: 'canvas', // canvas画布
componentInstance: this,
text: this.res.bottom.code, // 二维码内容
size: 130, // 二维码大小
margin: 5, // 二维码内边距
backgroundColor: '#ffffff', // 二维码背景颜色
foregroundColor: '#000000', // !二维码色块颜色
fileType: 'jpg',
errorCorrectLevel: 0, // <== 关键 容错率M:0,L:1,H:2,Q:3,
// errorCorrectLevel: uQRCode.errorCorrectLevel.M, // <== 关键 容错率M:0,L:1,H:2,Q:3,
success: res => {
this.sharingLink = res; // res => 图片路径
// 对画布进行绘制
this.draw(dp);
},
fail: res => {
// console.log('失败',res)
}
const imgUrl = ref("")
const show = ref(false)
const dp = ref<any>({})
const logo = logoImg
const myFace = myFaceImg
const sharingLink = ref('')
/** 解决微信小程序中图片模糊问题 */
// #ifdef MP-WEIXIN
const st2 = (size: number) => size * 2
// #endif
// #ifndef MP-WEIXIN
const st2 = (size: number) => size
// #endif
/** 保存图片 */
const downLoad = () => {
uni.saveImageToPhotosAlbum({
filePath: imgUrl.value,
success: function () {
uni.showToast({title: "保存成功!",icon: "none"})
},
fail: function () {
uni.showToast({title: "保存失败,请稍后重试!",icon: "none"})
},
})
}
/** 创建canvas */
const init = async () => {
show.value = true
dp.value = await DrawPoster.build({
selector: "canvas",
componentThis: instance?.proxy,
loading: true,
debugging: true,
})
let dpVal = dp.value
// #ifdef MP-WEIXIN
// 用于微信小程序中画布错乱问题
dpVal.canvas.width = st2(560)
dpVal.canvas.height = st2(800)
// #endif
await showQRCode(dpVal)
}
/** 生成二维码 */
const showQRCode = async (dp: any) => {
await uQRCode.make({
canvasId: 'canvas',
componentInstance: instance?.proxy,
text: props.res.bottom.code,
size: 130,
margin: 5,
backgroundColor: '#ffffff',
foregroundColor: '#000000',
fileType: 'jpg',
errorCorrectLevel: 0,
success: (res: any) => {
sharingLink.value = res
draw(dp)
},
fail: (_res: any) => {
// console.log('失败',res)
}
})
}
const draw = async (dp: any) => {
const { face, nickName, desc } = props.res.memberInfo
const { width, height, background, title } = props.res.container
const { img, price } = props.res.bottom
/** 绘制背景 */
await dp.draw((ctx: any) => {
ctx.fillStyle = background
ctx.fillRoundRect(st2(0), st2(0), st2(width), st2(height), st2(12))
ctx.clip()
})
/** 绘制圆角矩形 */
await dp.draw(async (ctx: any) => {
ctx.fillStyle = "#ffffff"
ctx.strokeStyle = "#ffffff"
ctx.lineWidth = st2(1)
ctx.fillRoundRect(30, 150, 500, 620, 0)
})
/** 绘制图片 */
dp.draw(async (ctx: any) => {
await Promise.all([
ctx.drawImage(face ? face : myFace, st2(30), st2(30), st2(90), st2(90)),
ctx.drawImage(img, st2(60), st2(170), st2(440), st2(440)),
ctx.drawImage(sharingLink.value, st2(375), st2(625), st2(130), st2(130))
])
})
/** 绘制顶部文字(昵称 简述) */
await dp.draw((ctx: any) => {
ctx.fillStyle = "#666"
ctx.font = `${st2(24)}px PingFang SC`
ctx.fillText(nickName, st2(150), st2(65))
ctx.fillStyle = "#666"
ctx.font = `${st2(24)}px PingFang SC`
ctx.fillText(desc, st2(150), st2(105))
})
/** 绘制中间文字(商品名称 价格) */
await dp.draw((ctx: any) => {
ctx.fillStyle = "#333"
ctx.font = `bold ${st2(24)}px PingFang SC`
ctx.textAlign = "left"
ctx.fillWarpText({
text: title,
lineHeight: st2(32),
maxWidth: st2(280),
x: st2(60),
y: st2(710),
layer: 2,
})
},
async draw(dp) {
const { face, nickName, desc } = this.res.memberInfo;
const { width, height, background, title } = this.res.container;
const { code, img, price } = this.res.bottom;
ctx.fillStyle = "#ff3c2a"
ctx.font = `${st2(38)}px PingFang SC`
ctx.textAlign = "left"
ctx.fillText(price, st2(60), st2(665))
})
/** 绘制背景 */
await dp.draw((ctx) => {
ctx.fillStyle = background;
ctx.fillRoundRect( this.st2(0), this.st2(0), this.st2(width), this.st2(height), this.st2(12));
ctx.clip();
});
/** 绘制圆角矩形 */
await dp.draw(async (ctx)=>{
// 设置矩形色彩
ctx.fillStyle = "#ffffff";
// 设置图形轮廓的颜色。默认情况下线条和填充颜色都是黑色CSS 颜色值 #000000
ctx.strokeStyle = "#ffffff";
// 这个属性设置当前绘线的粗细。属性值必须为正数。描述线段宽度的数字。 0、 负数、 Infinity 和 NaN 会被忽略。默认值是1.0。
ctx.lineWidth = this.st2(1);
// 进行绘制
ctx.fillRoundRect(30, 150, 500, 620, 0);
// ctx.strokeRoundRect(30, 150, 500, 620, 0);
// ctx.strokeRect(30, 150, 500, 620, 0);
})
/** 绘制图片 */
dp.draw(async (ctx) => {
await Promise.all([
// 绘制头像face
ctx.drawImage(face?face:this.myFace, this.st2(30), this.st2(30), this.st2(90), this.st2(90)),
// 绘制Logo
// ctx.drawImage( this.logo, this.st2(175), this.st2(0), this.st2(256), this.st2(144)),
// 中间图片
ctx.drawImage(img, this.st2(60), this.st2(170), this.st2(440), this.st2(440)),
// 二维码
ctx.drawImage(this.sharingLink, this.st2(375), this.st2(625), this.st2(130), this.st2(130))
]);
});
/** 绘制顶部文字(昵称 简述) */
await dp.draw((ctx) => {
ctx.fillStyle = "#666";
ctx.font = `${this.st2(24)}px PingFang SC`;
ctx.fillText(nickName, this.st2(150), this.st2(65));
ctx.fillStyle = "#666";
ctx.font = `${this.st2(24)}px PingFang SC`;
ctx.fillText(desc, this.st2(150), this.st2(105));
});
/** 绘制中间文字(商品名称 价格) */
await dp.draw((ctx) => {
ctx.fillStyle = "#333";
ctx.font = `bold ${this.st2(24)}px PingFang SC`;
ctx.textAlign = "left";
ctx.fillWarpText({
text: title,
lineHeight: this.st2(32),
maxWidth: this.st2(280),
x: this.st2(60),
y: this.st2(710),
layer: 2,
});
ctx.fillStyle = "#ff3c2a";
ctx.font = `${this.st2(38)}px PingFang SC`;
ctx.textAlign = "left";
ctx.fillText(price, this.st2(60), this.st2(665));
});
/** 绘制底部文字 */
// await dp.draw((ctx) => {
// ctx.fillStyle = "#666";
// ctx.font = `${this.st2(24)}px PingFang SC`;
// ctx.fillText("长按图片,识别二维码", this.st2(200), this.st2(866));
// ctx.fillStyle = "#666";
// ctx.font = `${this.st2(24)}px PingFang SC`;
// ctx.fillText("查看商品详情", this.st2(200), this.st2(900));
// });
// 绘制生成本地地址
this.imgUrl = await dp.createImagePath();
},
},
// 绘制生成本地地址
imgUrl.value = await dp.createImagePath()
}
async mounted() {
this.init();
},
};
onMounted(() => {
init()
})
</script>
<style lang="scss" scoped>