订单二维码

main
yanzai 1 year ago
parent 1bd55e8373
commit 0e82ab6f48

@ -23,7 +23,7 @@ class OrderController extends Controller
$persons_sfz = DB::table('web_user_person')->where(['user_id' => $user->id, 'is_del' => 0])->pluck('id_number')->toArray();
$OrderList = DB::table('orders')
->select('id', 'title', 'status', 'name', 'appointment_time as time', 'order_number as order',
->select('id', 'title', 'status', 'name', 'appointment_time as time', 'order_number as order','appointment_number',
DB::raw("CASE WHEN type = 1 THEN '个检' WHEN type = 2 THEN '团检' ELSE 'unknown' END as type"),
'price', 'true_price', 'pay_time', 'refund_time', 'created_at')
->where(['web_user_id' => $user->id])

@ -1,393 +1,391 @@
<script setup>
/**
* name
* usersa0ChunLuyu
* date2024年8月14日 20:38:40
*/
import { ref, onMounted, defineEmits } from "vue";
import { $api, $response } from "@/api";
import { onShow } from "@dcloudio/uni-app";
import wx from "weixin-js-sdk";
const $props = defineProps({
info: {
type: Object,
default: () => {
return {
id: 0,
};
},
},
});
/**
* name
* usersa0ChunLuyu
* date2024年8月14日 20:38:40
*/
import {
ref,
onMounted,
defineEmits
} from "vue";
import {
$api,
$response
} from "@/api";
import {
onShow
} from "@dcloudio/uni-app";
import wx from "weixin-js-sdk";
const $props = defineProps({
info: {
type: Object,
default: () => {
return {
id: 0,
};
},
},
});
const order_info = ref(false);
const order_info = ref(false);
const deepInfo = () => {
order_info.value = JSON.parse(JSON.stringify($props.info));
checkStatus();
};
const deepInfo = () => {
order_info.value = JSON.parse(JSON.stringify($props.info));
checkStatus();
};
const countdown = ref(null);
const checkStatus = () => {
if (order_info.value.status === 1) {
countdown.value = setInterval(() => {
countdownRun();
}, 500);
}
};
const count_down_text = ref("限制时间");
const countdownRun = () => {
let seconds = Math.floor(
(order_info.value.end_time - new Date() / 1000) % 60
);
let minutes = Math.floor(
(order_info.value.end_time - new Date() / 1000) / 60
);
count_down_text.value = `${minutes}${seconds}`;
if (order_info.value.end_time <= new Date() / 1000) {
clearInterval(countdown.value);
order_info.value.status = 3;
}
};
const StartPay = async (id) => {
//
uni.showLoading();
const response = await $api("StartPay", {
openid: localStorage.getItem("OPENID"),
id: id,
});
uni.hideLoading();
$response(response, () => {
if (response.status) {
let info = response.data.info;
let p =
"&appid=" +
info.appid +
"&sub_org_code=" +
info.sub_org_code +
"&ghzid=" +
info.ghzid +
"&orderid=" +
info.orderid +
"&order_desc=" +
info.order_desc +
"&amount=" +
info.amount +
"&notify_url=" +
info.notify_url +
"&timestamp=" +
info.timestamp +
"&nonce=" +
info.nonce +
"&signature=" +
info.signature;
console.log(p);
wx.miniProgram.navigateTo({
url:
"/pages/other/entry/index?path=/pages/physical-examination/payment/index" +
p,
});
}
});
};
const countdown = ref(null);
const checkStatus = () => {
if (order_info.value.status === 1) {
countdown.value = setInterval(() => {
countdownRun();
}, 500);
}
};
const count_down_text = ref("限制时间");
const countdownRun = () => {
let seconds = Math.floor(
(order_info.value.end_time - new Date() / 1000) % 60
);
let minutes = Math.floor(
(order_info.value.end_time - new Date() / 1000) / 60
);
count_down_text.value = `${minutes}${seconds}`;
if (order_info.value.end_time <= new Date() / 1000) {
clearInterval(countdown.value);
order_info.value.status = 3;
}
};
const StartPay = async (id) => {
//
uni.showLoading();
const response = await $api("StartPay", {
openid: localStorage.getItem("OPENID"),
id: id,
});
uni.hideLoading();
$response(response, () => {
if (response.status) {
let info = response.data.info;
let p =
"&appid=" +
info.appid +
"&sub_org_code=" +
info.sub_org_code +
"&ghzid=" +
info.ghzid +
"&orderid=" +
info.orderid +
"&order_desc=" +
info.order_desc +
"&amount=" +
info.amount +
"&notify_url=" +
info.notify_url +
"&timestamp=" +
info.timestamp +
"&nonce=" +
info.nonce +
"&signature=" +
info.signature;
console.log(p);
wx.miniProgram.navigateTo({
url: "/pages/other/entry/index?path=/pages/physical-examination/payment/index" +
p,
});
}
});
};
const emit = defineEmits();
const Refound = async (id) => {
uni.showLoading();
const response = await $api("Refund", {
openid: localStorage.getItem("OPENID"),
id: id,
});
uni.hideLoading();
$response(response, () => {
if (response.status) {
uni.showToast({
title: "退款完成",
});
emit("updateValue", "orderUpdate");
}
});
};
const GaiYueClick=(id)=>{
uni.navigateTo({
url:'/pages/main/ctime/ctime?id='+id
})
}
onMounted(() => {
deepInfo();
});
const emit = defineEmits();
const Refound = async (id) => {
uni.showLoading();
const response = await $api("Refund", {
openid: localStorage.getItem("OPENID"),
id: id,
});
uni.hideLoading();
$response(response, () => {
if (response.status) {
uni.showToast({
title: "退款完成",
});
emit("updateValue", "orderUpdate");
}
});
};
const GaiYueClick = (id) => {
uni.navigateTo({
url: '/pages/main/ctime/ctime?id=' + id
})
}
onMounted(() => {
deepInfo();
});
</script>
<template>
<view>
<view v-if="!!order_info" class="order_wrapper">
<view
class="order_status_wrapper"
:class="[`status${order_info.status}`]"
>
<view v-if="[1].includes(order_info.status)"> </view>
<view v-if="[2].includes(order_info.status)"> </view>
<view v-if="[3, 5].includes(order_info.status)"> </view>
<view v-if="[4].includes(order_info.status)"> </view>
</view>
<view class="combo_name_wrapper">{{ order_info.title }}</view>
<view class="order_info_wrapper">
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">体检人</view>
<view class="order_info_line_value_wrapper">{{
order_info.name
}}</view>
</view>
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">预约时间</view>
<view class="order_info_line_value_wrapper">{{
order_info.time
}}</view>
</view>
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">订单号</view>
<view class="order_info_line_value_wrapper">{{
<view>
<view v-if="!!order_info" class="order_wrapper">
<view class="order_status_wrapper" :class="[`status${order_info.status}`]">
<view v-if="[1].includes(order_info.status)"> </view>
<view v-if="[2].includes(order_info.status)"> </view>
<view v-if="[3, 5].includes(order_info.status)"> </view>
<view v-if="[4].includes(order_info.status)"> </view>
</view>
<view class="combo_name_wrapper">{{ order_info.title }}</view>
<view class="order_info_wrapper">
<view style="display: flex;">
<view>
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">体检人</view>
<view class="order_info_line_value_wrapper">{{
order_info.name
}}</view>
</view>
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">预约时间</view>
<view class="order_info_line_value_wrapper">{{
order_info.time
}}</view>
</view>
</view>
<view >
<w-qrcode class="absolute top-80rpx right-15rpx b-1 b-dashed b-#000 p-8rpx"
:options="{
level: 4,
size: 150,
code: order_info.appointment_number,
}"></w-qrcode>
</view>
</view>
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">订单号</view>
<view class="order_info_line_value_wrapper">{{
order_info.order
}}</view>
</view>
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">类型</view>
<view class="order_info_line_value_wrapper">{{
</view>
<view class="order_info_line_wrapper">
<view class="order_info_line_label_wrapper">类型</view>
<view class="order_info_line_value_wrapper">{{
order_info.type
}}</view>
</view>
<view
v-if="[1, 2, 4, 5].includes(order_info.status)"
class="order_price_wrapper"
>
<text v-if="[1].includes(order_info.status)"></text>
<text v-if="[2, 4].includes(order_info.status)"></text>
<text v-if="[5].includes(order_info.status)">退</text>
<text
class="price_true"
v-if="order_info.true_price !== order_info.price"
>(测试:{{ order_info.true_price }})</text
>
<text class="price_text">{{ order_info.price }}</text>
</view>
<view class="order_line_wrapper"></view>
<view v-if="![3].includes(order_info.status)" class="order_pay_wrapper">
<view class="order_pay_time_wrapper">
<view v-if="[1].includes(order_info.status)">
<text>请在</text>
<text class="time_red">{{ count_down_text }}</text>
<text>内完成支付</text>
</view>
<view v-if="[2, 4].includes(order_info.status)">
<view>支付时间</view>
<view>{{ order_info.pay_time }}</view>
</view>
<view v-if="[5].includes(order_info.status)">
<view>退款时间</view>
<view>{{ order_info.refund_time }}</view>
</view>
</view>
<view class="order_pay_button_wrapper">
<view
v-if="[1].includes(order_info.status)"
@click="StartPay(order_info.id)"
class="button_item_wrapper pay_button_wrapper"
>继续付款</view
>
<view v-if="[2].includes(order_info.status)" @click="GaiYueClick(order_info.id)" class="button_item_wrapper change_button_wrapper">
</view>
<view v-if="[1, 2, 4, 5].includes(order_info.status)" class="order_price_wrapper">
<text v-if="[1].includes(order_info.status)"></text>
<text v-if="[2, 4].includes(order_info.status)"></text>
<text v-if="[5].includes(order_info.status)">退</text>
<text class="price_true"
v-if="order_info.true_price !== order_info.price">(测试:{{ order_info.true_price }})</text>
<text class="price_text">{{ order_info.price }}</text>
</view>
<view class="order_line_wrapper"></view>
<view v-if="![3].includes(order_info.status)" class="order_pay_wrapper">
<view class="order_pay_time_wrapper">
<view v-if="[1].includes(order_info.status)">
<text>请在</text>
<text class="time_red">{{ count_down_text }}</text>
<text>内完成支付</text>
</view>
<view v-if="[2, 4].includes(order_info.status)">
<view>支付时间</view>
<view>{{ order_info.pay_time }}</view>
</view>
<view v-if="[5].includes(order_info.status)">
<view>退款时间</view>
<view>{{ order_info.refund_time }}</view>
</view>
</view>
<view class="order_pay_button_wrapper">
<view v-if="[1].includes(order_info.status)" @click="StartPay(order_info.id)"
class="button_item_wrapper pay_button_wrapper">继续付款</view>
<view v-if="[2].includes(order_info.status)" @click="GaiYueClick(order_info.id)"
class="button_item_wrapper change_button_wrapper">
改约</view>
<view
v-if="[2].includes(order_info.status)"
@click="Refound(order_info.id)"
class="button_item_wrapper refund_button_wrapper"
>退款</view
>
<view
v-if="[4].includes(order_info.status) && order_info.report"
class="button_item_wrapper report_button_wrapper"
>
查看报告
</view>
<view
v-if="
<view v-if="[2].includes(order_info.status)" @click="Refound(order_info.id)"
class="button_item_wrapper refund_button_wrapper">退款</view>
<view v-if="[4].includes(order_info.status) && order_info.report"
class="button_item_wrapper report_button_wrapper">
查看报告
</view>
<view v-if="
[4].includes(order_info.status) &&
order_info.report &&
!order_info.decode
"
class="button_item_wrapper decode_button_wrapper"
>报告解读</view
>
</view>
</view>
<view v-else class="order_pay_blank_wrapper"></view>
</view>
</view>
</view>
" class="button_item_wrapper decode_button_wrapper">报告解读</view>
</view>
</view>
<view v-else class="order_pay_blank_wrapper"></view>
</view>
</view>
</view>
</template>
<style scoped>
.order_pay_button_wrapper {
display: flex;
align-items: center;
}
.order_pay_button_wrapper {
display: flex;
align-items: center;
}
.button_item_wrapper {
width: 180rpx;
height: 60rpx;
border-radius: 30rpx;
line-height: 60rpx;
text-align: center;
font-weight: 400;
font-size: 24rpx;
margin-left: 20rpx;
}
.button_item_wrapper {
width: 180rpx;
height: 60rpx;
border-radius: 30rpx;
line-height: 60rpx;
text-align: center;
font-weight: 400;
font-size: 24rpx;
margin-left: 20rpx;
}
.pay_button_wrapper {
background: #239ea3;
color: #ffffff;
}
.pay_button_wrapper {
background: #239ea3;
color: #ffffff;
}
.change_button_wrapper {
background: #e1ecee;
color: #239ea3;
}
.change_button_wrapper {
background: #e1ecee;
color: #239ea3;
}
.refund_button_wrapper {
background: #239ea3;
color: #ffffff;
}
.refund_button_wrapper {
background: #239ea3;
color: #ffffff;
}
.report_button_wrapper {
background: #e1ecee;
color: #239ea3;
}
.report_button_wrapper {
background: #e1ecee;
color: #239ea3;
}
.decode_button_wrapper {
background: #239ea3;
color: #ffffff;
}
.decode_button_wrapper {
background: #239ea3;
color: #ffffff;
}
.order_pay_blank_wrapper {
height: 30rpx;
}
.order_pay_blank_wrapper {
height: 30rpx;
}
.order_pay_time_wrapper {
font-weight: 500;
font-size: 20rpx;
color: #8b8b8b;
line-height: 26rpx;
}
.order_pay_time_wrapper {
font-weight: 500;
font-size: 20rpx;
color: #8b8b8b;
line-height: 26rpx;
}
.time_red {
color: #ec4d15;
margin: 0 5rpx;
}
.time_red {
color: #ec4d15;
margin: 0 5rpx;
}
.order_pay_wrapper {
display: flex;
align-items: center;
justify-content: space-between;
width: calc(100% - 60rpx);
margin: 0 auto;
height: 100rpx;
}
.order_pay_wrapper {
display: flex;
align-items: center;
justify-content: space-between;
width: calc(100% - 60rpx);
margin: 0 auto;
height: 100rpx;
}
.order_line_wrapper {
width: 660rpx;
height: 1rpx;
background: #ebeaea;
margin: 19rpx auto 0;
}
.order_line_wrapper {
width: 660rpx;
height: 1rpx;
background: #ebeaea;
margin: 19rpx auto 0;
}
.order_price_wrapper {
font-weight: 400;
color: #111111;
line-height: 1;
margin-top: 28rpx;
text-align: right;
margin-right: 30rpx;
font-size: 26rpx;
}
.order_price_wrapper {
font-weight: 400;
color: #111111;
line-height: 1;
margin-top: 28rpx;
text-align: right;
margin-right: 30rpx;
font-size: 26rpx;
}
.price_text {
margin-left: 10rpx;
}
.price_text {
margin-left: 10rpx;
}
.price_true {
font-size: 12rpx;
}
.price_true {
font-size: 12rpx;
}
.order_info_wrapper {
margin-top: 14rpx;
}
.order_info_wrapper {
margin-top: 14rpx;
}
.order_info_line_wrapper {
display: flex;
align-items: center;
margin-top: 24rpx;
}
.order_info_line_wrapper {
display: flex;
align-items: center;
margin-top: 24rpx;
}
.order_info_line_label_wrapper {
width: 120rpx;
font-weight: 400;
font-size: 24rpx;
color: #8b8b8b;
line-height: 1;
margin-left: 30rpx;
}
.order_info_line_label_wrapper {
width: 120rpx;
font-weight: 400;
font-size: 24rpx;
color: #8b8b8b;
line-height: 1;
margin-left: 30rpx;
}
.order_info_line_value_wrapper {
font-weight: 400;
font-size: 24rpx;
color: #333333;
line-height: 1;
margin-left: 10rpx;
}
.order_info_line_value_wrapper {
font-weight: 400;
font-size: 24rpx;
color: #333333;
line-height: 1;
margin-left: 10rpx;
}
.combo_name_wrapper {
width: calc(550rpx - 30rpx);
font-weight: bold;
font-size: 32rpx;
color: #0e0e0e;
line-height: 1;
margin-left: 30rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.combo_name_wrapper {
width: calc(550rpx - 30rpx);
font-weight: bold;
font-size: 32rpx;
color: #0e0e0e;
line-height: 1;
margin-left: 30rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.order_status_wrapper {
position: absolute;
top: 30rpx;
right: 27rpx;
font-size: 26rpx;
}
.order_status_wrapper {
position: absolute;
top: 30rpx;
right: 27rpx;
font-size: 26rpx;
}
.order_status_wrapper.status1 {
color: #ec4d15;
}
.order_status_wrapper.status1 {
color: #ec4d15;
}
.order_status_wrapper.status2 {
color: #239ea3;
}
.order_status_wrapper.status2 {
color: #239ea3;
}
.order_status_wrapper.status3 {
color: #ec4d15;
}
.order_status_wrapper.status3 {
color: #ec4d15;
}
.order_status_wrapper.status4 {
color: #131313;
}
.order_status_wrapper.status4 {
color: #131313;
}
.order_status_wrapper.status5 {
color: #ec4d15;
}
.order_status_wrapper.status5 {
color: #ec4d15;
}
.order_wrapper {
position: relative;
width: 710rpx;
background: #ffffff;
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(0, 0, 0, 0.05);
border-radius: 10rpx;
margin: 0 auto;
padding-top: 35rpx;
margin-top: 16rpx;
}
</style>
.order_wrapper {
position: relative;
width: 710rpx;
background: #ffffff;
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(0, 0, 0, 0.05);
border-radius: 10rpx;
margin: 0 auto;
padding-top: 35rpx;
margin-top: 16rpx;
}
</style>

@ -0,0 +1,84 @@
<a href="https://meet-ui.com" target="_blank">
<h1 align="center">文档地址</h1>
</a>
<h1 align="center">https://meet-ui.com/#/</h1>
<p align="center">为了能够第一时间解决问题,为了不影响各位在项目中使用特此提供微信群交流</p>
<center>
<img src="https://img.lovewmf.com/2022-10-19.png"/>
<img src="https://img.lovewmf.com/2022-05-10.png"/>
</center>
# 温馨提示
如果使用cli创建的应用请在`vue.config.js`里面添加如下配置
```
module.exports = {
transpileDependencies: [
/[/\\]node_modules[/\\](.+?)?@uni-ui(.*)[/\\]code-plugs/,
/[/\\]node_modules[/\\](.+?)?@uni-ui(.*)[/\\]code-ui/
]
}
```
# 微信小程序特别说明
如果在弹窗里面使用,并且弹窗有动画 当弹窗显示的时候二维码会发生偏移或抖动
因为微信小程序的canvas在真机预览渲染的是原生组件并不是 h5的canavas 所以在开发工具里面没问题但是真机会有问题
解决方案:
1. 如果是使用uView组件的弹窗 请关闭动画
2. 如果是使用uni-popup组件 关闭动画无效 因为uni的弹窗动画关闭 其实是动画时长为0并且是包含在uni-transition详情请查看uni-popup代码
## 如果是使用uni_modules而非Npm
在`pages.json`里面配置如下
```js
"easycom": {
"^w-(.*)": "@/uni_modules/wmf-code/components/w-$1/w-$1.vue"//二维码条形码的配置 如果是uni_modules
},
"pages": [
//...
]
```
## 如果是使用npm而非uni_modules
在`pages.json`里面配置如下
```js
"easycom": {
"^w-(.*)": "@uni-ui/code-ui/components/w-$1/index.vue"//二维码条形码的配置 如果是npm方式使用
},
"pages": [
//...
]
```
## 条形码支持添加文字
<img src="https://img.lovewmf.com/WeChat315bd9b33217fabb1beaaa0d65421bee.png" style="margin-bottom: 10px;" />
<img src="https://img.lovewmf.com/WeChat9e319e9cd08e96369c09099f2863bff5.png" style="margin-bottom: 10px;" />
<center>
<figure>
<img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/07d4381cff624fc79ab28cdd1bf3cc6a~tplv-k3u1fbpfcp-watermark.image" style="margin-bottom: 10px;" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/71d7c20e8c91495c81d245ccfc83d7e7~tplv-k3u1fbpfcp-watermark.image" style="margin-bottom: 10px;" />
</figure>
</center>
#
<center>
<figure>
<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bfe9eb88cea44007b2627bb640343dcc~tplv-k3u1fbpfcp-watermark.image" style="margin-bottom: 10px;" />
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b625254802404a9b84bd699e67b03db4~tplv-k3u1fbpfcp-watermark.image" style="margin-bottom: 10px;" />
</figure>
</center>
#
<center>
<figure>
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f84328d92b104edbad4c34a8665b4c72~tplv-k3u1fbpfcp-watermark.image" style="margin-bottom: 10px;" />
<img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1548ccd6c944bbe90ef288817077b8c~tplv-k3u1fbpfcp-watermark.image" style="margin-bottom: 10px;" />
</figure>
</center>

@ -0,0 +1,108 @@
## 1.6.22022-10-24
* 修复已知问题
## 1.6.12022-10-19
* 支付宝小程序适配问题
* 修改文档
## 1.6.02022-07-27
* 修改条形码bug
## 1.5.92022-07-26
* 修复条形码保存图片部分黑底问题
## 1.5.82022-07-26
* 修复支付宝小程序图片保存缺失问题
## 1.5.72022-07-09
* 修复条形码保存缺失问题
## 1.5.62022-07-01
修改引入错误
## 1.5.52022-07-01
* 修复vue3无法通过ref获取保存图片方法
## 1.5.42022-06-01
* 条形码支持添加文字
## 1.5.32022-05-31
* 修复二维码有时候无法识别问题
* 建议使用npm方式
## 1.5.22022-05-31
修改条形码垂直方向生成图片 参数互换
## 1.5.12022-05-31
条形码增加垂直方向 默认水平方向
## 1.5.02022-05-30
修改uni_modules引入错误
## 1.4.92022-05-25
支持vue3
## 1.4.82021-12-06
* 百度小程序不支持canvas的arcTo方法 如果在百度小程序中不支持的全部默认值
* 小程序平台绘制文字不支持渐变 取color数组第一个
## 1.4.72021-12-05
* 修复已知问题
## 1.4.52021-12-05
* 修复已知问题
## 1.4.42021-11-30
* level默认值修改为2
## 1.4.32021-11-30
* 修复引用js_sdk引用路径
## 1.4.22021-11-29
* 修复设置画布大小时没有带单位px导致显示不全
## 1.4.12021-11-29
1. 修复在高分辨率屏幕上支付宝小程序显示模糊问题
2. 修复保存相册图片模糊问题
## 1.4.02021-11-23
1. 使用TS重构
2. 新增二维码文字绘制
3. 新增二维码padding
4. 新增二维码中间图片圆角 圆形
5. 新增长按事件
6. 二维码边框支持透明
7. 颜色最多支持10中颜色渐变
## 1.3.72021-11-08
修改引入
## 1.3.62021-11-02
修改引用路径
## 1.3.52021-10-19
canvas 增加 type="2d"
## 1.3.42021-10-14
1. 修改百度小程序修改参数无法重新渲染问题
2. 修改纯中文无法识别问题
## 1.3.32021-09-04
修改uni_module引用路径
## 1.3.22021-09-03
* 【重要】多个条形码或者二维码同时渲染
* 增加示例
## 1.3.12021-08-31
uni_modules支持组件方式
## 1.3.02021-08-31
支持纯文字以及文字数字 字母的混合
## 1.2.92021-08-30
新增二维码创建成功回调方法中返回生成的二维码图片
## 1.2.82021-08-20
支持vue3
## 1.2.72021-08-20
修改版本号
## 1.2.62021-06-28
1. 修改自定义组件时微信小程序无法显示二维码的问题
2. 统一二维码的大小单位为rpx
## 1.2.52021-06-25
二维码logo大小增加默认值30
## 1.2.42021-06-24
1. nvue 二维码支持渐变色
## 1.2.32021-06-23
1. 修改app不支持颜色渐变问题
2. 修改判断方式Object.prototype.toString.call()
## 1.2.22021-06-23
修改插件描述
## 1.2.12021-06-23
修改return 错误
## 1.1.22021-06-23
修改文档
## 1.1.12021-06-23
二维码支持渐变色
## 1.0.82021-06-22
兼容nvue
## 1.0.72021-06-09
1. 修改保存二维码图片的方法名以及传参方式
2. 修改微信小程序保存二维码时显示为黑色
3. 二维码增加参数
## 1.0.62021-06-04
修改 description说明
## 1.0.52021-06-04
修改文档展示名称
## 1.0.42021-06-04
修改符合uni_modules规范

@ -0,0 +1,105 @@
// 判断arr是否为一个数组返回一个bool值
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
// 深度克隆
function deepClone(obj) {
// 对常见的“非”值,直接返回原来值
if ([null, undefined, NaN, false].includes(obj)) return obj;
if (typeof obj !== "object" && typeof obj !== 'function') {
//原始类型直接返回
return obj;
}
var o = isArray(obj) ? [] : {};
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
}
}
return o;
}
function getUUid(len = 32, firstU = true, radix = null) {
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
let uuid = [];
radix = radix || chars.length;
if (len) {
// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
} else {
let r;
// rfc4122标准要求返回的uuid中,某些位为固定的字符
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
for (let i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random() * 16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
if (firstU) {
uuid.shift();
return 'u' + uuid.join('');
} else {
return uuid.join('');
}
}
function platform () {
let val = null;
// #ifdef VUE3
val = 'VUE3'
// #endif
// #ifdef APP-PLUS
val = 'APP-PLUS'
// #endif
// #ifdef APP-PLUS-NVUE || APP-NVUE
val = 'NVUE'
// #endif
// #ifdef H5
val = 'H5'
// #endif
// #ifdef MP-WEIXIN
val = 'MP-WEIXIN'
// #endif
// #ifdef MP-ALIPAY
val = 'MP-ALIPAY'
// #endif
// #ifdef MP-BAIDU
val = 'MP-BAIDU'
// #endif
// #ifdef MP-TOUTIAO
val = 'MP-TOUTIAO'
// #endif
// #ifdef MP-LARK
val = 'MP-LARK'
// #endif
// #ifdef MP-TOUTIAO
val = 'MP-QQ'
// #endif
// #ifdef MP-KUAISHOU
val = 'MP-KUAISHOU'
// #endif
// #ifdef MP-360
val = 'MP-360'
// #endif
// #ifdef QUICKAPP-WEBVIEW
val = 'QUICKAPP-WEBVIEW'
// #endif
// #ifdef QUICKAPP-WEBVIEW-UNION
val = 'QUICKAPP-WEBVIEW-UNION'
// #endif
// #ifdef QUICKAPP-WEBVIEW-HUAWEI
val = 'QUICKAPP-WEBVIEW-HUAWEI'
// #endif
return val;
}
export {
deepClone,
getUUid,
platform
};

@ -0,0 +1,204 @@
<template>
<view @longtap.stop="longtap">
<canvas
:width="info.orient == 'vertical' ? info.destHeight : info.destWidth "
:height="info.orient == 'vertical' ? info.destWidth : info.destHeight"
:canvas-id="item.id"
:id="item.id"
:style="{width:info.orient == 'vertical' ? info.height : info.width,height: info.orient == 'vertical' ? info.width : info.height}"
v-for="item in info.listCode"
:key="item.id"
@error="handleError"></canvas>
</view>
</template>
<!-- #ifdef VUE3 -->
<script setup name="WBarcode">
import {
reactive,
watch,
onMounted,
nextTick,
getCurrentInstance,
defineExpose
} from 'vue';
import {
BarCode,
GetImg,
GetPixelRatio,
GetPx ,
} from '../../js_sdk/index.js';
import {
getUUid,
deepClone,
platform,
} from '../../common/helper.js'
//props
const props = defineProps({
options:{
type: Object,
required: true,
default: () =>{
return {}
}
}
});
const emits = defineEmits(['generate','press','error'])
const opt = props.options;
const that = getCurrentInstance();
const HSize = opt.text ? opt.text.size || 40 + opt.text.padding || 20 : 0;
let info = reactive({
id: getUUid(),
destWidth: GetPixelRatio() * GetPx(opt.width) + 'px',
destHeight: GetPixelRatio() * GetPx(opt.height + HSize) + 'px',
width: GetPx(opt.width) + 'px',
height: GetPx(opt.height + HSize) + 'px',
orient: opt.orient || 'horizontal',
listCode: []
})
onMounted(()=>{
SpecialTreatment(opt);
nextTick(()=>{
generateCode(opt)
})
});
watch(()=>props.options,(val)=>{
SpecialTreatment(val);
const HSize = val.text ? val.text.size || 40 + val.text.padding || 20 : 0;
info.destWidth= GetPixelRatio() * GetPx(val.width) + 'px',
info.destHeight= GetPixelRatio() * GetPx(val.height + HSize) + 'px',
info.orient = val.orient || 'horizontal',
info.width= GetPx(val.width) + 'px',
info.height= GetPx(val.height + HSize) + 'px',
setTimeout(()=>{
generateCode(val)
},100)
},{ deep: true })
const generateCode = (val)=> {
try{
const parameter = {...val,orient: info.orient,source: platform(),id: info.id,ctx: that};
BarCode(parameter,(res)=>{
emits('generate',res)
})
}catch(err){console.warn(err)}
}
const GetCodeImg = async ()=> {
try{
return await GetImg({id: info.id,source: platform(),width: opt.orient == 'vertical' ? opt.height : opt.width,height: opt.orient == 'vertical' ? opt.width : opt.height,ctx: that});
}catch(e){console.warn(e)}
};
const SpecialTreatment = (val) => {//canvas
let obj = deepClone(val);
obj.id = info.id;
info.listCode = [obj];
};
//
const longtap = (e)=>{
emits('press',e)
}
// canvas
const handleError = (e)=>{
emits('error',e.detail)
}
defineExpose({
GetCodeImg
})
</script>
<!-- #endif -->
<!-- #ifndef VUE3 -->
<script>
import { BarCode, GetImg,GetPixelRatio,GetPx } from '../../js_sdk/index.js';
import { getUUid, deepClone,platform } from '../../common/helper.js'
export default {
name: 'WBarcode',
props:{
options:{
type: Object,
required: true,
default: () =>{
return {
}
}
}
},
data () {
return {
info:{
destHeight: 0,
destWidth: 0,
width: 0,
height: 0,
listCode: [],
orient: 'horizontal'
},
id: getUUid()
}
},
mounted() {
const HSize = this.options.text ? ((this.options.text.size || 40) + ( this.options.text.padding || 20)) : 0;
this.info.height = GetPx(this.options.height + HSize) + 'px';
this.info.orient = this.options.orient || 'horizontal';
this.info.width = GetPx(this.options.width) + 'px';
this.info.destHeight = GetPx(this.options.height + HSize) * GetPixelRatio() + 'px';
this.info.destWidth = GetPx(this.options.width) * GetPixelRatio() + 'px';
this.SpecialTreatment(this.options)
this.$nextTick(()=>{
this.generateCode();
})
},
watch: {
options:{
deep: true,
handler (val) {
const HSize = val.text ? val.text.size || 40 + val.text.padding || 20 : 0;
this.info.height = GetPx(val.height + HSize) + 'px';
this.info.width = GetPx(val.width) + 'px';
this.info.destHeight = GetPx(val.height + HSize) * GetPixelRatio() + 'px';
this.info.destWidth = GetPx(val.width) * GetPixelRatio() + 'px';
this.info.orient = val.orient || 'horizontal'
this.SpecialTreatment(val)
setTimeout(()=>{// h5canvas
this.generateCode();
},100)
}
}
},
methods: {
longtap (e){
this.$emit('press',e)
},
handleError (e) {// error
this.$emit('error',e.detail)
},
SpecialTreatment (val) {//canvas
let obj = deepClone(val);
obj.id = this.id;
this.info.listCode = [obj]
},
generateCode () {
try{
const parameter = {...this.options,orient: this.info.orient,source: platform(),id: this.id,ctx: this};
console.log(parameter)
BarCode(parameter,(res)=>{
this.$emit('generate',res)
})
}catch(err){console.log(err)}
},
async GetCodeImg (){
try{
const pars = {
id: this.id,
source: platform(),
width: this.options.orient == 'vertical' ? this.info.height : this.info.width,
height: this.options.orient == 'vertical' ? this.info.width : this.info.height,
ctx: this,
}
return await GetImg(pars);
}catch(e){console.warn(e)}
}
}
}
</script>
<!-- #endif -->

@ -0,0 +1,175 @@
<template>
<view @longtap.stop="longtap">
<canvas
:width="info.destWidth"
:height="info.destHeight"
:canvas-id="item.id"
:id="item.id"
:style="{width:info.width,height: info.height}"
v-for="item in info.listCode"
:key="item.id"
@error="handleError"></canvas>
</view>
</template>
<!-- #ifdef VUE3 -->
<script setup name="WQrcode">
import {reactive, watch,onMounted,nextTick,getCurrentInstance ,defineExpose } from 'vue';
import { QRCode, GetImg,GetPixelRatio,GetPx } from '@/uni_modules/wmf-code/js_sdk/index.js';
import { getUUid, deepClone,platform } from '../../common/helper.js'
//props
const props = defineProps({
options:{
type: Object,
required: true,
default: () =>{
return {}
}
}
});
const emits = defineEmits(['generate','press','error'])
const opt = props.options;
const that = getCurrentInstance();
const SIZE = GetPx(opt.size);
let info = reactive({
destHeight: SIZE * GetPixelRatio() + 'px',
destWidth: SIZE * GetPixelRatio() + 'px',
width: SIZE + 'px',
height: SIZE + 'px',
listCode:[],
id: getUUid(),
})
onMounted(()=>{
SpecialTreatment(opt);
nextTick(()=>{
generateCode(opt)
})
});
watch(()=>props.options,(val)=>{
SpecialTreatment(val);
const SIZE_Dynamic = GetPx(val.size);
info.destWidth= GetPixelRatio() * SIZE_Dynamic + 'px',
info.destHeight= GetPixelRatio() * SIZE_Dynamic + 'px',
info.width= SIZE_Dynamic + 'px',
info.height= SIZE_Dynamic + 'px',
setTimeout(()=>{
generateCode(val)
},50)
},{ deep: true })
const SpecialTreatment =(val)=> {//canvas
let obj = deepClone(val);
obj.id = info.id;
info.listCode = [obj]
};
const generateCode = (val)=>{
try{
const parameter = {...val,source: platform(),id: info.id,ctx: that};
QRCode(parameter,(res)=>{
emits('generate',res)
})
}catch(err){console.warn(err)}
};
const GetCodeImg = async ()=> {
try{
return await GetImg({id: info.id,source: platform(),width: opt.width,height: opt.height,ctx: that});
}catch(e){console.warn(e)}
};
//
const longtap = (e)=>{
emits('press',e)
}
// canvas
const handleError = (e)=>{
emits('error',e.detail)
}
defineExpose({
GetCodeImg
})
</script>
<!-- #endif -->
<!-- #ifndef VUE3 -->
<script>
import { QRCode, GetImg,GetPixelRatio,GetPx } from '@/uni_modules/wmf-code/js_sdk/index.js';
import { getUUid, deepClone,platform } from '../../common/helper.js'
export default {
name: 'WQrcode',
props:{
options:{
type: Object,
required: true,
default: () =>{
return {
}
}
}
},
data () {
return {
info:{
destHeight: 0,
destWidth: 0,
width: 0,
height: 0,
listCode:[],
},
destHeight: 0,
destWidth: 0,
width: 0,
height: 0,
listCode:[],
id: getUUid(),
}
},
mounted() {
this.info.height = this.info.width = GetPx(this.options.size) + 'px';
this.info.destHeight = this.info.destWidth = GetPx(this.options.size) * GetPixelRatio() + 'px';
this.SpecialTreatment(this.options)
this.$nextTick(()=>{
this.generateCode();
})
},
watch: {
options:{
deep: true,
handler (val) {
this.info.height = this.info.width = GetPx(val.size) + 'px';
this.info.destHeight = this.info.destWidth = GetPx(val.size) * GetPixelRatio() + 'px';
this.SpecialTreatment(val)
setTimeout(()=>{// h5canvas
this.generateCode();
},50)
}
}
},
methods: {
longtap (e){//
this.$emit('press',e);
},
handleError (e) {// error
this.$emit('error',e.detail)
},
SpecialTreatment (val) {//canvas
let obj = deepClone(val);
obj.id = this.id;
this.info.listCode = [obj]
},
//
generateCode () {
try{
const parameter = {...this.options,source: platform(),id: this.id,ctx: this};
QRCode(parameter,(res)=>{
this.$emit('generate',res)
})
}catch(err){console.warn(err)}
},
//
async GetCodeImg (){
try{
return await GetImg({id: this.id,source: platform(),width: this.options.size,height: this.options.size,ctx: this});
}catch(e){console.warn(e)}
}
}
}
</script>
<!-- #endif -->

File diff suppressed because one or more lines are too long

@ -0,0 +1,77 @@
{
"id": "wmf-code",
"displayName": "二维码 条形码生成 支持链接 支持nvue 支持纯文字",
"version": "1.6.2",
"description": "二维码 条形码生成,支持渐变色边框 保存二维码图片,支持链接 ,支持nvue 支持纯文字",
"keywords": [
"二维码",
"条形码"
],
"repository": "https://github.com/lovewmf/uni-code",
"engines": {
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无 ",
"permissions": "无 "
},
"npmurl": "https://www.npmjs.com/package/@uni-ui/code-ui",
"type": "sdk-js"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"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",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
Loading…
Cancel
Save