程序二维码分享组件, 支持传入color,bgColor,disabled
This commit is contained in:
parent
d89a0a27ef
commit
256f0eefa1
|
|
@ -11,5 +11,8 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
|
|||
url: string;
|
||||
loading?: boolean | undefined;
|
||||
disableDownload?: boolean | undefined;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
}>) => React.ReactElement;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -13,10 +13,13 @@ export default OakComponent({
|
|||
disableDownload: false,
|
||||
onRefresh: undefined,
|
||||
onDownload: undefined,
|
||||
disabled: false,
|
||||
color: '#000000',
|
||||
bgColor: '#ffffff',
|
||||
},
|
||||
lifetimes: {
|
||||
ready() {
|
||||
const { url, size } = this.props;
|
||||
const { url, size, color, bgColor } = this.props;
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp') {
|
||||
const isBase64 = /data:image\/[\w|\W]+(;base64,)[\w|\W]*/.test(url);
|
||||
if (isBase64) {
|
||||
|
|
@ -26,6 +29,8 @@ export default OakComponent({
|
|||
typeNumber: 4, // 密度
|
||||
errorCorrectLevel: 'L', // 纠错等级
|
||||
size: size, // 白色边框
|
||||
color,
|
||||
bgColor
|
||||
});
|
||||
this.setState({
|
||||
qrcodeURL,
|
||||
|
|
|
|||
|
|
@ -7,11 +7,32 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.qrcode {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.image {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
inset-inline-start: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: rgba(0,0,0,0.88);
|
||||
line-height: 1.5;
|
||||
background: rgba(255,255,255,0.96);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.caption {
|
||||
color: @oak-text-color-secondary;
|
||||
font-size: 12px;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,23 @@
|
|||
<view class="qrCodeBox">
|
||||
<block wx:if="{{isBase64}}">
|
||||
<image src="{{url}}" mode="aspectFit" class="image" />
|
||||
<view class="qrcode" >
|
||||
<image src="{{url}}" mode="aspectFit" class="image" style="width: {{size}}px; height: {{size}}px;" />
|
||||
<block wx:if="{{disabled}}">
|
||||
<view class="mask">
|
||||
{{t('disabled')}}
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:elif="{{qrcodeURL}}">
|
||||
<image src="{{qrcodeURL}}" mode="aspectFit" class="image" />
|
||||
<view class="qrcode" >
|
||||
<image src="{{qrcodeURL}}" mode="aspectFit" class="image" style="width: {{size}}px; height: {{size}}px;" />
|
||||
<block wx:if="{{disabled}}">
|
||||
<view class="mask">
|
||||
{{t('disabled')}}
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{expiresAtStr}}">
|
||||
|
|
@ -21,7 +35,7 @@
|
|||
</block>
|
||||
|
||||
<view class="actions">
|
||||
<view wx:if="{{!disableDownload}}" class="action" bind:tap="onDownload" >
|
||||
<view wx:if="{{!disableDownload && !disabled}}" class="action" bind:tap="onDownload" >
|
||||
<l-icon name="download" size="40" />
|
||||
</view>
|
||||
</view>
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@
|
|||
"Album permission denied, please reauthorize": "相册权限被拒绝,请重新授权",
|
||||
"Save fail": "保存失败",
|
||||
"Save successful": "保存成功",
|
||||
"Authorization successful": "授权成功"
|
||||
"Authorization successful": "授权成功",
|
||||
"disabled": "已禁用"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
* @Modified: Pudon
|
||||
* @demoURL: https://github.com/Pudon/weapp-qrcode
|
||||
* @Date: 2018-09-11 14:00:05
|
||||
* @Last Modified by: Pudon
|
||||
* @Last Modified time: 2018-09-12 16:33:19
|
||||
* @Last Modified by: mikey.zhaopeng
|
||||
* @Last Modified time: 2025-09-13 19:22:01
|
||||
*/
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
|
|
@ -448,11 +448,16 @@ var qrcode = function(typeNumber, errorCorrectLevel) {
|
|||
return qrHtml;
|
||||
};
|
||||
|
||||
_this.createImgTag = function(cellSize, margin, size) {
|
||||
_this.createImgTag = function(cellSize, margin, size, foregroundColor, backgroundColor) {
|
||||
|
||||
cellSize = cellSize || 2;
|
||||
margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
|
||||
|
||||
// 设置默认颜色
|
||||
foregroundColor = foregroundColor || '#000000';
|
||||
backgroundColor = backgroundColor || '#ffffff';
|
||||
|
||||
|
||||
var min = margin;
|
||||
var max = _this.getModuleCount() * cellSize + margin;
|
||||
|
||||
|
|
@ -464,7 +469,7 @@ var qrcode = function(typeNumber, errorCorrectLevel) {
|
|||
} else {
|
||||
return 1;
|
||||
}
|
||||
} );
|
||||
}, foregroundColor, backgroundColor );
|
||||
};
|
||||
|
||||
return _this;
|
||||
|
|
@ -1351,7 +1356,10 @@ var base64DecodeInputStream = function(str) {
|
|||
// gifImage (B/W)
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
var gifImage = function(width, height) {
|
||||
var gifImage = function(width, height, foregroundColor, backgroundColor) {
|
||||
// 设置默认颜色
|
||||
foregroundColor = foregroundColor || [0, 0, 0]; // 默认黑色
|
||||
backgroundColor = backgroundColor || [255, 255, 255]; // 默认白色
|
||||
|
||||
var _width = width;
|
||||
var _height = height;
|
||||
|
|
@ -1383,15 +1391,24 @@ var gifImage = function(width, height) {
|
|||
//---------------------------------
|
||||
// Global Color Map
|
||||
|
||||
// /使用自定义的前景色和背景色
|
||||
out.writeByte(foregroundColor[0]);
|
||||
out.writeByte(foregroundColor[1]);
|
||||
out.writeByte(foregroundColor[2]);
|
||||
out.writeByte(backgroundColor[0]);
|
||||
out.writeByte(backgroundColor[1]);
|
||||
out.writeByte(backgroundColor[2]);
|
||||
|
||||
|
||||
// black
|
||||
out.writeByte(0x00);
|
||||
out.writeByte(0x00);
|
||||
out.writeByte(0x00);
|
||||
// out.writeByte(0x00);
|
||||
// out.writeByte(0x00);
|
||||
// out.writeByte(0x00);
|
||||
|
||||
// white
|
||||
out.writeByte(0xff);
|
||||
out.writeByte(0xff);
|
||||
out.writeByte(0xff);
|
||||
// out.writeByte(0xff);
|
||||
// out.writeByte(0xff);
|
||||
// out.writeByte(0xff);
|
||||
|
||||
//---------------------------------
|
||||
// Image Descriptor
|
||||
|
|
@ -1561,9 +1578,20 @@ var gifImage = function(width, height) {
|
|||
return _this;
|
||||
};
|
||||
|
||||
var createImgTag = function(width, height, getPixel, alt) {
|
||||
var createImgTag = function(width, height, getPixel, foregroundColor, backgroundColor) {
|
||||
|
||||
var gif = gifImage(width, height);
|
||||
// 设置默认颜色
|
||||
foregroundColor = foregroundColor || '#000000';
|
||||
backgroundColor = backgroundColor || '#ffffff';
|
||||
|
||||
// 将颜色转换为RGB数组
|
||||
var fgRgb = hexToRgb(foregroundColor);
|
||||
var bgRgb = hexToRgb(backgroundColor);
|
||||
|
||||
if (!fgRgb) fgRgb = [0, 0, 0]; // 默认黑色
|
||||
if (!bgRgb) bgRgb = [255, 255, 255]; // 默认白色
|
||||
|
||||
var gif = gifImage(width, height, fgRgb, bgRgb);
|
||||
for (var y = 0; y < height; y += 1) {
|
||||
for (var x = 0; x < width; x += 1) {
|
||||
gif.setPixel(x, y, getPixel(x, y) );
|
||||
|
|
@ -1587,6 +1615,28 @@ var createImgTag = function(width, height, getPixel, alt) {
|
|||
return img;
|
||||
};
|
||||
|
||||
// 添加十六进制颜色转RGB函数
|
||||
function hexToRgb(hex) {
|
||||
// 移除#号
|
||||
hex = hex.replace('#', '');
|
||||
|
||||
// 处理简写形式 #abc → #aabbcc
|
||||
if (hex.length === 3) {
|
||||
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
||||
}
|
||||
|
||||
// 验证是否为6位十六进制颜色
|
||||
if (!/^[0-9A-F]{6}$/i.test(hex)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var r = parseInt(hex.substring(0, 2), 16);
|
||||
var g = parseInt(hex.substring(2, 4), 16);
|
||||
var b = parseInt(hex.substring(4, 6), 16);
|
||||
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// returns qrcode function.
|
||||
|
||||
|
|
@ -1595,6 +1645,8 @@ var drawImg = function(text, options) {
|
|||
var typeNumber = options.typeNumber || 4;
|
||||
var errorCorrectLevel = options.errorCorrectLevel || 'M';
|
||||
var size = options.size || 500;
|
||||
var foregroundColor = options.color || '#000000';
|
||||
var backgroundColor = options.bgColor || '#ffffff';
|
||||
|
||||
var qr;
|
||||
|
||||
|
|
@ -1609,7 +1661,9 @@ var drawImg = function(text, options) {
|
|||
return drawImg(text, {
|
||||
size: size,
|
||||
errorCorrectLevel: errorCorrectLevel,
|
||||
typeNumber: typeNumber + 1
|
||||
typeNumber: typeNumber + 1,
|
||||
color: foregroundColor,
|
||||
bgColor: backgroundColor
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1618,7 +1672,7 @@ var drawImg = function(text, options) {
|
|||
var cellsize = parseInt(size / qr.getModuleCount());
|
||||
var margin = parseInt((size - qr.getModuleCount() * cellsize) / 2);
|
||||
|
||||
return qr.createImgTag(cellsize, margin, size);
|
||||
return qr.createImgTag(cellsize, margin, size, foregroundColor, backgroundColor);
|
||||
};
|
||||
module.exports = {
|
||||
drawImg: drawImg
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ type IQrCodeProps = {
|
|||
url: string;
|
||||
loading?: boolean;
|
||||
disableDownload?: boolean;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
};
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, IQrCodeProps & {
|
||||
isBase64: boolean;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import './web.less';
|
|||
export default function Render(props) {
|
||||
const { data, methods } = props;
|
||||
const { t } = methods;
|
||||
const { filename = 'qrCode.png', expiresAt, tips, onDownload, onRefresh, size = 280, url, loading = false, disableDownload = false, isBase64, expired, expiresAtStr } = data;
|
||||
const { filename = 'qrCode.png', expiresAt, tips, onDownload, onRefresh, size = 280, url, loading = false, disableDownload = false, disabled = false, isBase64, expired, expiresAtStr, color, bgColor, } = data;
|
||||
const prefixCls = 'oak';
|
||||
let V;
|
||||
if (expiresAtStr) {
|
||||
|
|
@ -24,21 +24,24 @@ export default function Render(props) {
|
|||
}
|
||||
}
|
||||
return (<div id="oakQrCode" className={`${prefixCls}-qrCodeBox`}>
|
||||
<div className={`${prefixCls}-qrCodeBox_imgBox`} style={{
|
||||
width: size,
|
||||
height: size,
|
||||
<div className={`${prefixCls}-qrCodeBox_qrcode`} style={{
|
||||
// width: size,
|
||||
// height: size,
|
||||
marginBottom: 16,
|
||||
marginTop: 16,
|
||||
}}>
|
||||
<Spin spinning={loading}>
|
||||
{isBase64 ? (<img src={url} alt="qrCode" width={size} height={size}/>) : url ? (<QRCodeCanvas value={url} size={size}/>) : null}
|
||||
{isBase64 ? (<img src={url} alt="qrCode" width={size} height={size}/>) : url ? (<QRCodeCanvas value={url} size={size} fgColor={color} bgColor={bgColor}/>) : null}
|
||||
</Spin>
|
||||
{disabled ? <div className={`${prefixCls}-qrCodeBox_mask`}>
|
||||
{t('disabled')}
|
||||
</div> : null}
|
||||
</div>
|
||||
|
||||
{V}
|
||||
{tips}
|
||||
{<Space className={`${prefixCls}-qrCodeBox_actions`}>
|
||||
{!!url && !disableDownload && (<Button type="text" onClick={() => {
|
||||
{!!url && !disableDownload && !disabled && (<Button type="text" onClick={() => {
|
||||
if (typeof onDownload === 'function') {
|
||||
onDownload(url, filename);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -4,12 +4,29 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&_imgBox {
|
||||
&_qrcode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&_mask {
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
inset-inline-start: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: rgba(0,0,0,0.88);
|
||||
line-height: 1.5;
|
||||
background: rgba(255,255,255,0.96);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&_caption {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "wechatQrCode", false, {
|
||||
disableDownload: boolean;
|
||||
size: number;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
}>) => React.ReactElement;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ export default OakComponent({
|
|||
const base64Str = window.btoa(binary);
|
||||
qrCodeUrl = 'data:image/png;base64,' + base64Str;
|
||||
}
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.warn('使用微信api生成二维码,不支持二维码颜色更换[color、bgColor]');
|
||||
}
|
||||
}
|
||||
return {
|
||||
entity: wechatQrCode?.entity,
|
||||
|
|
@ -46,6 +49,9 @@ export default OakComponent({
|
|||
},
|
||||
properties: {
|
||||
disableDownload: false,
|
||||
size: 280
|
||||
size: 280,
|
||||
disabled: false,
|
||||
color: '#000000',
|
||||
bgColor: '#ffffff',
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<l-loading show="{{true}}" type="circle"></l-loading>
|
||||
</block>
|
||||
<block wx:elif="{{url}}">
|
||||
<qrCode url="{{url}}" expiresAt="{{expiresAt}}" disableDownload="{{disableDownload}}" size="{{size}}" />
|
||||
<qrCode url="{{url}}" expiresAt="{{expiresAt}}" disableDownload="{{disableDownload}}" size="{{size}}" disabled="{{disabled}}" color="{{color}}" bgColor="{{bgColor}}" />
|
||||
</block>
|
||||
<block wx:else>
|
||||
</block>
|
||||
|
|
|
|||
|
|
@ -6,4 +6,7 @@ export default function Render(props: WebComponentProps<EntityDict, 'wechatQrCod
|
|||
expiresAt: number;
|
||||
disableDownload: boolean;
|
||||
size: number;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
}, {}>): React.JSX.Element | null;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ import React from 'react';
|
|||
import QrCode from '../../common/qrCode';
|
||||
import { DotLoading } from 'antd-mobile';
|
||||
export default function Render(props) {
|
||||
const { url, expiresAt, oakLoading, disableDownload, size } = props.data;
|
||||
const { url, expiresAt, oakLoading, disableDownload, size, disabled, color, bgColor } = props.data;
|
||||
if (oakLoading) {
|
||||
return <DotLoading color="primary"/>;
|
||||
}
|
||||
if (url) {
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size}/>;
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size} disabled={disabled} color={color} bgColor={bgColor}/>;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,4 +6,7 @@ export default function Render(props: WebComponentProps<EntityDict, 'wechatQrCod
|
|||
expiresAt: number;
|
||||
disableDownload: boolean;
|
||||
size: number;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
}, {}>): React.JSX.Element | null;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ import React from 'react';
|
|||
import QrCode from '../../common/qrCode';
|
||||
import { Spin } from 'antd';
|
||||
export default function Render(props) {
|
||||
const { url, expiresAt, oakLoading, disableDownload, size } = props.data;
|
||||
const { url, expiresAt, oakLoading, disableDownload, size, disabled, color, bgColor } = props.data;
|
||||
if (oakLoading) {
|
||||
return <Spin />;
|
||||
}
|
||||
if (url) {
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size}/>;
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size} disabled={disabled} color={color} bgColor={bgColor}/>;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ const i18ns = [
|
|||
"Album permission denied, please reauthorize": "相册权限被拒绝,请重新授权",
|
||||
"Save fail": "保存失败",
|
||||
"Save successful": "保存成功",
|
||||
"Authorization successful": "授权成功"
|
||||
"Authorization successful": "授权成功",
|
||||
"disabled": "已禁用"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ const i18ns = [
|
|||
"Album permission denied, please reauthorize": "相册权限被拒绝,请重新授权",
|
||||
"Save fail": "保存失败",
|
||||
"Save successful": "保存成功",
|
||||
"Authorization successful": "授权成功"
|
||||
"Authorization successful": "授权成功",
|
||||
"disabled": "已禁用"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,11 +7,32 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.qrcode {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.image {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
inset-inline-start: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: rgba(0,0,0,0.88);
|
||||
line-height: 1.5;
|
||||
background: rgba(255,255,255,0.96);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.caption {
|
||||
color: @oak-text-color-secondary;
|
||||
font-size: 12px;
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ export default OakComponent({
|
|||
onDownload: undefined as
|
||||
| ((qrCodeImage: string, filename?: string) => void)
|
||||
| undefined,
|
||||
disabled: false,
|
||||
color: '#000000',
|
||||
bgColor: '#ffffff',
|
||||
},
|
||||
lifetimes: {
|
||||
ready() {
|
||||
const { url, size } = this.props;
|
||||
const { url, size, color, bgColor } = this.props;
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp') {
|
||||
const isBase64 = /data:image\/[\w|\W]+(;base64,)[\w|\W]*/.test(
|
||||
url!
|
||||
|
|
@ -34,6 +37,8 @@ export default OakComponent({
|
|||
typeNumber: 4, // 密度
|
||||
errorCorrectLevel: 'L', // 纠错等级
|
||||
size: size, // 白色边框
|
||||
color,
|
||||
bgColor
|
||||
});
|
||||
|
||||
this.setState({
|
||||
|
|
@ -221,7 +226,10 @@ export default OakComponent({
|
|||
size?: number;
|
||||
url: string;
|
||||
loading?: boolean;
|
||||
disableDownload?: boolean;
|
||||
disableDownload?: boolean; //下载禁用
|
||||
disabled: boolean; //二维码禁用
|
||||
color: string,
|
||||
bgColor: string,
|
||||
}
|
||||
>
|
||||
) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,23 @@
|
|||
<view class="qrCodeBox">
|
||||
<block wx:if="{{isBase64}}">
|
||||
<image src="{{url}}" mode="aspectFit" class="image" />
|
||||
<view class="qrcode" >
|
||||
<image src="{{url}}" mode="aspectFit" class="image" style="width: {{size}}px; height: {{size}}px;" />
|
||||
<block wx:if="{{disabled}}">
|
||||
<view class="mask">
|
||||
{{t('disabled')}}
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:elif="{{qrcodeURL}}">
|
||||
<image src="{{qrcodeURL}}" mode="aspectFit" class="image" />
|
||||
<view class="qrcode" >
|
||||
<image src="{{qrcodeURL}}" mode="aspectFit" class="image" style="width: {{size}}px; height: {{size}}px;" />
|
||||
<block wx:if="{{disabled}}">
|
||||
<view class="mask">
|
||||
{{t('disabled')}}
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{expiresAtStr}}">
|
||||
|
|
@ -21,7 +35,7 @@
|
|||
</block>
|
||||
|
||||
<view class="actions">
|
||||
<view wx:if="{{!disableDownload}}" class="action" bind:tap="onDownload" >
|
||||
<view wx:if="{{!disableDownload && !disabled}}" class="action" bind:tap="onDownload" >
|
||||
<l-icon name="download" size="40" />
|
||||
</view>
|
||||
</view>
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@
|
|||
"Album permission denied, please reauthorize": "相册权限被拒绝,请重新授权",
|
||||
"Save fail": "保存失败",
|
||||
"Save successful": "保存成功",
|
||||
"Authorization successful": "授权成功"
|
||||
"Authorization successful": "授权成功",
|
||||
"disabled": "已禁用"
|
||||
}
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
* @Modified: Pudon
|
||||
* @demoURL: https://github.com/Pudon/weapp-qrcode
|
||||
* @Date: 2018-09-11 14:00:05
|
||||
* @Last Modified by: Pudon
|
||||
* @Last Modified time: 2018-09-12 16:33:19
|
||||
* @Last Modified by: mikey.zhaopeng
|
||||
* @Last Modified time: 2025-09-13 19:22:01
|
||||
*/
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
|
|
@ -448,11 +448,16 @@ var qrcode = function(typeNumber, errorCorrectLevel) {
|
|||
return qrHtml;
|
||||
};
|
||||
|
||||
_this.createImgTag = function(cellSize, margin, size) {
|
||||
_this.createImgTag = function(cellSize, margin, size, foregroundColor, backgroundColor) {
|
||||
|
||||
cellSize = cellSize || 2;
|
||||
margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
|
||||
|
||||
// 设置默认颜色
|
||||
foregroundColor = foregroundColor || '#000000';
|
||||
backgroundColor = backgroundColor || '#ffffff';
|
||||
|
||||
|
||||
var min = margin;
|
||||
var max = _this.getModuleCount() * cellSize + margin;
|
||||
|
||||
|
|
@ -464,7 +469,7 @@ var qrcode = function(typeNumber, errorCorrectLevel) {
|
|||
} else {
|
||||
return 1;
|
||||
}
|
||||
} );
|
||||
}, foregroundColor, backgroundColor );
|
||||
};
|
||||
|
||||
return _this;
|
||||
|
|
@ -1351,7 +1356,10 @@ var base64DecodeInputStream = function(str) {
|
|||
// gifImage (B/W)
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
var gifImage = function(width, height) {
|
||||
var gifImage = function(width, height, foregroundColor, backgroundColor) {
|
||||
// 设置默认颜色
|
||||
foregroundColor = foregroundColor || [0, 0, 0]; // 默认黑色
|
||||
backgroundColor = backgroundColor || [255, 255, 255]; // 默认白色
|
||||
|
||||
var _width = width;
|
||||
var _height = height;
|
||||
|
|
@ -1383,15 +1391,24 @@ var gifImage = function(width, height) {
|
|||
//---------------------------------
|
||||
// Global Color Map
|
||||
|
||||
// /使用自定义的前景色和背景色
|
||||
out.writeByte(foregroundColor[0]);
|
||||
out.writeByte(foregroundColor[1]);
|
||||
out.writeByte(foregroundColor[2]);
|
||||
out.writeByte(backgroundColor[0]);
|
||||
out.writeByte(backgroundColor[1]);
|
||||
out.writeByte(backgroundColor[2]);
|
||||
|
||||
|
||||
// black
|
||||
out.writeByte(0x00);
|
||||
out.writeByte(0x00);
|
||||
out.writeByte(0x00);
|
||||
// out.writeByte(0x00);
|
||||
// out.writeByte(0x00);
|
||||
// out.writeByte(0x00);
|
||||
|
||||
// white
|
||||
out.writeByte(0xff);
|
||||
out.writeByte(0xff);
|
||||
out.writeByte(0xff);
|
||||
// out.writeByte(0xff);
|
||||
// out.writeByte(0xff);
|
||||
// out.writeByte(0xff);
|
||||
|
||||
//---------------------------------
|
||||
// Image Descriptor
|
||||
|
|
@ -1561,9 +1578,20 @@ var gifImage = function(width, height) {
|
|||
return _this;
|
||||
};
|
||||
|
||||
var createImgTag = function(width, height, getPixel, alt) {
|
||||
var createImgTag = function(width, height, getPixel, foregroundColor, backgroundColor) {
|
||||
|
||||
var gif = gifImage(width, height);
|
||||
// 设置默认颜色
|
||||
foregroundColor = foregroundColor || '#000000';
|
||||
backgroundColor = backgroundColor || '#ffffff';
|
||||
|
||||
// 将颜色转换为RGB数组
|
||||
var fgRgb = hexToRgb(foregroundColor);
|
||||
var bgRgb = hexToRgb(backgroundColor);
|
||||
|
||||
if (!fgRgb) fgRgb = [0, 0, 0]; // 默认黑色
|
||||
if (!bgRgb) bgRgb = [255, 255, 255]; // 默认白色
|
||||
|
||||
var gif = gifImage(width, height, fgRgb, bgRgb);
|
||||
for (var y = 0; y < height; y += 1) {
|
||||
for (var x = 0; x < width; x += 1) {
|
||||
gif.setPixel(x, y, getPixel(x, y) );
|
||||
|
|
@ -1587,6 +1615,28 @@ var createImgTag = function(width, height, getPixel, alt) {
|
|||
return img;
|
||||
};
|
||||
|
||||
// 添加十六进制颜色转RGB函数
|
||||
function hexToRgb(hex) {
|
||||
// 移除#号
|
||||
hex = hex.replace('#', '');
|
||||
|
||||
// 处理简写形式 #abc → #aabbcc
|
||||
if (hex.length === 3) {
|
||||
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
||||
}
|
||||
|
||||
// 验证是否为6位十六进制颜色
|
||||
if (!/^[0-9A-F]{6}$/i.test(hex)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var r = parseInt(hex.substring(0, 2), 16);
|
||||
var g = parseInt(hex.substring(2, 4), 16);
|
||||
var b = parseInt(hex.substring(4, 6), 16);
|
||||
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// returns qrcode function.
|
||||
|
||||
|
|
@ -1595,6 +1645,8 @@ var drawImg = function(text, options) {
|
|||
var typeNumber = options.typeNumber || 4;
|
||||
var errorCorrectLevel = options.errorCorrectLevel || 'M';
|
||||
var size = options.size || 500;
|
||||
var foregroundColor = options.color || '#000000';
|
||||
var backgroundColor = options.bgColor || '#ffffff';
|
||||
|
||||
var qr;
|
||||
|
||||
|
|
@ -1609,7 +1661,9 @@ var drawImg = function(text, options) {
|
|||
return drawImg(text, {
|
||||
size: size,
|
||||
errorCorrectLevel: errorCorrectLevel,
|
||||
typeNumber: typeNumber + 1
|
||||
typeNumber: typeNumber + 1,
|
||||
color: foregroundColor,
|
||||
bgColor: backgroundColor
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1618,7 +1672,7 @@ var drawImg = function(text, options) {
|
|||
var cellsize = parseInt(size / qr.getModuleCount());
|
||||
var margin = parseInt((size - qr.getModuleCount() * cellsize) / 2);
|
||||
|
||||
return qr.createImgTag(cellsize, margin, size);
|
||||
return qr.createImgTag(cellsize, margin, size, foregroundColor, backgroundColor);
|
||||
};
|
||||
module.exports = {
|
||||
drawImg: drawImg
|
||||
|
|
|
|||
|
|
@ -4,12 +4,29 @@
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&_imgBox {
|
||||
&_qrcode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&_mask {
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
inset-inline-start: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: rgba(0,0,0,0.88);
|
||||
line-height: 1.5;
|
||||
background: rgba(255,255,255,0.96);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&_caption {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ type IQrCodeProps = {
|
|||
url: string;
|
||||
loading?: boolean;
|
||||
disableDownload?: boolean;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
};
|
||||
|
||||
export default function Render(
|
||||
|
|
@ -45,9 +48,12 @@ export default function Render(
|
|||
url,
|
||||
loading = false,
|
||||
disableDownload = false,
|
||||
disabled= false,
|
||||
isBase64,
|
||||
expired,
|
||||
expiresAtStr
|
||||
expiresAtStr,
|
||||
color,
|
||||
bgColor,
|
||||
} = data;
|
||||
const prefixCls = 'oak';
|
||||
let V;
|
||||
|
|
@ -72,10 +78,10 @@ export default function Render(
|
|||
return (
|
||||
<div id="oakQrCode" className={`${prefixCls}-qrCodeBox`}>
|
||||
<div
|
||||
className={`${prefixCls}-qrCodeBox_imgBox`}
|
||||
className={`${prefixCls}-qrCodeBox_qrcode`}
|
||||
style={{
|
||||
width: size,
|
||||
height: size,
|
||||
// width: size,
|
||||
// height: size,
|
||||
marginBottom: 16,
|
||||
marginTop: 16,
|
||||
}}
|
||||
|
|
@ -89,16 +95,19 @@ export default function Render(
|
|||
height={size}
|
||||
/>
|
||||
) : url ? (
|
||||
<QRCodeCanvas value={url} size={size} />
|
||||
<QRCodeCanvas value={url} size={size} fgColor={color} bgColor={bgColor} />
|
||||
) : null}
|
||||
</Spin>
|
||||
{disabled ? <div className={`${prefixCls}-qrCodeBox_mask`}>
|
||||
{t('disabled')}
|
||||
</div> : null}
|
||||
</div>
|
||||
|
||||
{V}
|
||||
{tips}
|
||||
{
|
||||
<Space className={`${prefixCls}-qrCodeBox_actions`}>
|
||||
{!!url && !disableDownload && (
|
||||
{!!url && !disableDownload && !disabled && (
|
||||
<Button
|
||||
type="text"
|
||||
onClick={() => {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ export default OakComponent({
|
|||
const base64Str = window.btoa(binary);
|
||||
qrCodeUrl = 'data:image/png;base64,' + base64Str;
|
||||
}
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.warn('使用微信api生成二维码,不支持二维码颜色更换[color、bgColor]')
|
||||
}
|
||||
}
|
||||
return {
|
||||
entity: wechatQrCode?.entity,
|
||||
|
|
@ -47,6 +50,9 @@ export default OakComponent({
|
|||
},
|
||||
properties: {
|
||||
disableDownload: false,
|
||||
size: 280
|
||||
size: 280,
|
||||
disabled: false,
|
||||
color: '#000000',
|
||||
bgColor: '#ffffff',
|
||||
}
|
||||
});
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
<l-loading show="{{true}}" type="circle"></l-loading>
|
||||
</block>
|
||||
<block wx:elif="{{url}}">
|
||||
<qrCode url="{{url}}" expiresAt="{{expiresAt}}" disableDownload="{{disableDownload}}" size="{{size}}" />
|
||||
<qrCode url="{{url}}" expiresAt="{{expiresAt}}" disableDownload="{{disableDownload}}" size="{{size}}" disabled="{{disabled}}" color="{{color}}" bgColor="{{bgColor}}" />
|
||||
</block>
|
||||
<block wx:else>
|
||||
</block>
|
||||
|
|
|
|||
|
|
@ -14,16 +14,19 @@ export default function Render(
|
|||
expiresAt: number;
|
||||
disableDownload: boolean;
|
||||
size: number;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
},
|
||||
{}
|
||||
>
|
||||
) {
|
||||
const { url, expiresAt, oakLoading, disableDownload, size } = props.data;
|
||||
const { url, expiresAt, oakLoading, disableDownload, size, disabled, color, bgColor } = props.data;
|
||||
if (oakLoading) {
|
||||
return <Spin />;
|
||||
}
|
||||
if (url) {
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size} />;
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size} disabled={disabled} color={color} bgColor={bgColor} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -14,16 +14,19 @@ export default function Render(
|
|||
expiresAt: number;
|
||||
disableDownload: boolean;
|
||||
size: number;
|
||||
disabled: boolean;
|
||||
color: string;
|
||||
bgColor: string;
|
||||
},
|
||||
{}
|
||||
>
|
||||
) {
|
||||
const { url, expiresAt, oakLoading, disableDownload, size } = props.data;
|
||||
const { url, expiresAt, oakLoading, disableDownload, size, disabled, color, bgColor } = props.data;
|
||||
if (oakLoading) {
|
||||
return <DotLoading color="primary" />;
|
||||
}
|
||||
if (url) {
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size} />;
|
||||
return <QrCode url={url} expiresAt={expiresAt} disableDownload={disableDownload} size={size} disabled={disabled} color={color} bgColor={bgColor} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ const i18ns: I18n[] = [
|
|||
"Album permission denied, please reauthorize": "相册权限被拒绝,请重新授权",
|
||||
"Save fail": "保存失败",
|
||||
"Save successful": "保存成功",
|
||||
"Authorization successful": "授权成功"
|
||||
"Authorization successful": "授权成功",
|
||||
"disabled": "已禁用"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue