Reconstruct code completely
This commit is contained in:
parent
fdc1578306
commit
1d81bba201
|
@ -1071,6 +1071,24 @@
|
|||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@cloudbase/adapter-interface": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npm.taobao.org/@cloudbase/adapter-interface/download/@cloudbase/adapter-interface-0.4.0.tgz",
|
||||
"integrity": "sha1-xXk1tQPnv6zksVHfY6h9xWSumQc=",
|
||||
"dev": true
|
||||
},
|
||||
"@cloudbase/database": {
|
||||
"version": "0.9.11-rc.0",
|
||||
"resolved": "https://registry.npm.taobao.org/@cloudbase/database/download/@cloudbase/database-0.9.11-rc.0.tgz",
|
||||
"integrity": "sha1-ev1zOIzpzmct1bbZTm5XCNmRQ70=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bson": "^4.0.2",
|
||||
"lodash.clonedeep": "4.5.0",
|
||||
"lodash.set": "4.3.2",
|
||||
"lodash.unset": "4.5.2"
|
||||
}
|
||||
},
|
||||
"@cnakazawa/watch": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npm.taobao.org/@cnakazawa/watch/download/@cnakazawa/watch-1.0.4.tgz",
|
||||
|
@ -2384,6 +2402,41 @@
|
|||
"resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.9.1.tgz?cache=0&sync_timestamp=1578959055063&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.9.1.tgz",
|
||||
"integrity": "sha1-fjPY99RJs/ZzzXLeuavcVS2+Uo4="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npm.taobao.org/axios/download/axios-0.19.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz",
|
||||
"integrity": "sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz",
|
||||
"integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz?cache=0&sync_timestamp=1585479417937&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"axobject-query": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npm.taobao.org/axobject-query/download/axobject-query-2.1.2.tgz",
|
||||
|
@ -3099,6 +3152,28 @@
|
|||
"node-int64": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npm.taobao.org/bson/download/bson-4.0.4.tgz",
|
||||
"integrity": "sha1-S9os7fKuehjRXLJO4e3ox5f47s8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer": "^5.1.0",
|
||||
"long": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npm.taobao.org/buffer/download/buffer-5.6.0.tgz?cache=0&sync_timestamp=1588706716358&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-5.6.0.tgz",
|
||||
"integrity": "sha1-oxdJ3H2B2E2wir+Te2uMQDP2J4Y=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz",
|
||||
|
@ -3452,6 +3527,15 @@
|
|||
"shallow-clone": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"cloudbase-adapter-wx_mp": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/cloudbase-adapter-wx_mp/download/cloudbase-adapter-wx_mp-0.1.1.tgz",
|
||||
"integrity": "sha1-J1DtgUX4IWhB0lu7XWubSiFLhDg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cloudbase/adapter-interface": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npm.taobao.org/co/download/co-4.6.0.tgz",
|
||||
|
@ -3812,6 +3896,12 @@
|
|||
"randomfill": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-3.3.0.tgz?cache=0&sync_timestamp=1581508591511&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcrypto-js%2Fdownload%2Fcrypto-js-3.3.0.tgz",
|
||||
"integrity": "sha1-hG3RzOL2iqz6FWyFePkmpgm3l2s=",
|
||||
"dev": true
|
||||
},
|
||||
"css": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npm.taobao.org/css/download/css-2.2.4.tgz",
|
||||
|
@ -5565,6 +5655,12 @@
|
|||
"locate-path": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"fingerprintjs2": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npm.taobao.org/fingerprintjs2/download/fingerprintjs2-2.1.0.tgz",
|
||||
"integrity": "sha1-Idw/7ifTsZkFbvjrhz3rzNjgYyM=",
|
||||
"dev": true
|
||||
},
|
||||
"flat-cache": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz",
|
||||
|
@ -8172,11 +8268,23 @@
|
|||
"resolved": "https://registry.npm.taobao.org/lodash._reinterpolate/download/lodash._reinterpolate-3.0.0.tgz",
|
||||
"integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
|
||||
},
|
||||
"lodash.clonedeep": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npm.taobao.org/lodash.clonedeep/download/lodash.clonedeep-4.5.0.tgz",
|
||||
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz",
|
||||
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
|
||||
},
|
||||
"lodash.set": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npm.taobao.org/lodash.set/download/lodash.set-4.3.2.tgz",
|
||||
"integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.sortby": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npm.taobao.org/lodash.sortby/download/lodash.sortby-4.7.0.tgz",
|
||||
|
@ -8204,11 +8312,23 @@
|
|||
"resolved": "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz",
|
||||
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
|
||||
},
|
||||
"lodash.unset": {
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npm.taobao.org/lodash.unset/download/lodash.unset-4.5.2.tgz",
|
||||
"integrity": "sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0=",
|
||||
"dev": true
|
||||
},
|
||||
"loglevel": {
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npm.taobao.org/loglevel/download/loglevel-1.6.8.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Floglevel%2Fdownload%2Floglevel-1.6.8.tgz",
|
||||
"integrity": "sha1-iiX7ddCSIw7NRFcnDYC1TigBEXE="
|
||||
},
|
||||
"long": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/long/download/long-4.0.0.tgz",
|
||||
"integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg=",
|
||||
"dev": true
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz",
|
||||
|
@ -12624,6 +12744,21 @@
|
|||
"resolved": "https://registry.npm.taobao.org/tapable/download/tapable-1.1.3.tgz",
|
||||
"integrity": "sha1-ofzMBrWNth/XpF2i2kT186Pme6I="
|
||||
},
|
||||
"tcb-js-sdk": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npm.taobao.org/tcb-js-sdk/download/tcb-js-sdk-1.6.1.tgz",
|
||||
"integrity": "sha1-jaLnrtwR+iNYqtrr2YcSg4shFUM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cloudbase/adapter-interface": "^0.4.0",
|
||||
"@cloudbase/database": "0.9.11-rc.0",
|
||||
"axios": "^0.19.1",
|
||||
"cloudbase-adapter-wx_mp": "^0.1.0",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"fingerprintjs2": "^2.1.0",
|
||||
"url": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.6.12",
|
||||
"resolved": "https://registry.npm.taobao.org/terser/download/terser-4.6.12.tgz?cache=0&sync_timestamp=1587902079221&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.6.12.tgz",
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
},
|
||||
"homepage": "./",
|
||||
"devDependencies": {
|
||||
"redux-devtools": "^3.5.0"
|
||||
"redux-devtools": "^3.5.0",
|
||||
"tcb-js-sdk": "^1.6.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-165845289-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-165845289-1');
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bp = document.createElement('script');
|
||||
var curProtocol = window.location.protocol.split(':')[0];
|
||||
if (curProtocol === 'https') {
|
||||
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
||||
}
|
||||
else {
|
||||
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
||||
}
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(bp, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<!--<meta name="viewport" content="width=device-width, initial-scale=1" />-->
|
||||
<meta content="yes" name="apple-mobile-web-app-capable">
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="theme-color" content="#000000" />
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
content="QRBTF 参数化二维码生成器 Parametric QR Code Generator"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
|
|
|
@ -5,9 +5,14 @@ export const genQRInfo = text => ({
|
|||
text
|
||||
})
|
||||
|
||||
export const changeStyle = index => ({
|
||||
export const changeStyle = (rendererIndex, rendererType, value) => ({
|
||||
type: actionTypes.CHANGE_STYLE,
|
||||
index
|
||||
rendererIndex, rendererType, value
|
||||
})
|
||||
|
||||
export const changeCorrectLevel = (correctLevel) => ({
|
||||
type: actionTypes.CHANGE_CORRECT_LEVEL,
|
||||
correctLevel
|
||||
})
|
||||
|
||||
export const createParam = (paramInfo, paramValue) => ({
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import * as tcb from 'tcb-js-sdk';
|
||||
|
||||
const app = tcb.init({
|
||||
env: 'qrbtf-1d845d'
|
||||
});
|
||||
const auth = app.auth();
|
||||
|
||||
async function login() {
|
||||
await auth.signInAnonymously();
|
||||
// const loginState = await auth.getLoginState();
|
||||
}
|
||||
|
||||
login();
|
||||
|
||||
const db = app.database();
|
||||
const _ = db.command
|
||||
|
||||
export function increaseDownloadData(value) {
|
||||
db.collection('QRCounter').where({
|
||||
value: _.eq(value)
|
||||
}).get().then(res => {
|
||||
if (res.data.length > 0) {
|
||||
db.collection('QRCounter').where({
|
||||
value: _.eq(value)
|
||||
}).update({
|
||||
count: _.inc(1),
|
||||
date: new Date().toString()
|
||||
}).then(res => {
|
||||
})
|
||||
}
|
||||
else {
|
||||
db.collection('QRCounter').add({
|
||||
value: value,
|
||||
count: 1,
|
||||
date: new Date().toString()
|
||||
}).then(res => {
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function recordDownloadDetail({text, value, type, params, history}) {
|
||||
db.collection('QRDownloadData').add({
|
||||
date: new Date().toString(),
|
||||
text: text,
|
||||
value: value,
|
||||
type: type,
|
||||
params: params,
|
||||
history: history
|
||||
}).then(res => {
|
||||
})
|
||||
}
|
|
@ -84,6 +84,8 @@
|
|||
|
||||
.Qr-item-image {
|
||||
/*padding: 23px;*/
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
background-color: white;
|
||||
width: calc((100vw - 56px) / 2);
|
||||
height: calc((100vw - 56px) / 2);
|
||||
|
@ -105,6 +107,7 @@
|
|||
}
|
||||
|
||||
.Qr-item-image-inner {
|
||||
justify-content: center;
|
||||
-webkit-transition-timing-function: ease-in-out;
|
||||
-moz-transition-timing-function: ease-in-out;
|
||||
transition-timing-function: ease-in-out;
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*eslint-disable*/
|
||||
|
||||
import React from "react";
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import {getQrcodeData} from "../utils/qrcodeHandler";
|
||||
import {saveImg, saveSvg} from "../utils/downloader";
|
||||
import {isWeiXin} from "../utils/util";
|
||||
import './Qrcode.css';
|
||||
import logo from '../qrbtf-logo.svg';
|
||||
|
||||
import Footer from "./footer/Footer";
|
||||
import QrItem from "./QrItem";
|
||||
import QrRendererBase from "./QrRendererBase";
|
||||
import QrRendererRound from "./QrRendererRound";
|
||||
import QrRendererRandRound from "./QrRendererRandRound";
|
||||
import QrRendererBlank from "./QrRendererBlank";
|
||||
import QrRendererRandRect from "./QrRendererRandRect";
|
||||
import QrRendererDSJ from "./QrRendererDSJ";
|
||||
|
||||
class Qrcode extends React.Component {
|
||||
|
||||
downloadSvg = (e) => {
|
||||
const style = styleList[this.state.selectedIndex]
|
||||
const el = React.createElement(style.renderer, {qrcode: this.state.qrcode, params: this.state.paramValue[this.state.selectedIndex]})
|
||||
saveSvg(style.value, ReactDOMServer.renderToString(el))
|
||||
}
|
||||
|
||||
downloadImg = (e) => {
|
||||
const style = styleList[this.state.selectedIndex]
|
||||
const el = React.createElement(style.renderer, {qrcode: this.state.qrcode, params: this.state.paramValue[this.state.selectedIndex]})
|
||||
saveImg(style.value, ReactDOMServer.renderToString(el), 1500, 1500)
|
||||
}
|
||||
}
|
||||
|
||||
export default Qrcode;
|
||||
|
||||
window.onload = function(){
|
||||
if(isWeiXin()){
|
||||
const outer = document.getElementById("wx-message");
|
||||
const inner = document.createElement("div");
|
||||
inner.className = "note-font";
|
||||
inner.id = "wx-message-inner";
|
||||
inner.innerHTML = "当前客户端不支持下载,请在浏览器中打开。";
|
||||
outer.appendChild(inner);
|
||||
}
|
||||
}
|
|
@ -3,25 +3,25 @@ import './App.css';
|
|||
import '../Qrcode.css';
|
||||
import Footer from "../footer/Footer";
|
||||
import Header from "../header/Header";
|
||||
import PartInput from "./PartInput";
|
||||
import PartStyles from "./PartStyles";
|
||||
import PartMore from "./PartMore";
|
||||
import PartParams from "./PartParams";
|
||||
import PartDownload from "./PartDownload";
|
||||
import PartDownloadViewer from "../../containers/app/PartDownloadViewer";
|
||||
import PartStylesViewer from "../../containers/app/PartStylesViewer";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<div className="Layout">
|
||||
<div className="Qr-outer">
|
||||
<Header/>
|
||||
<PartInput/>
|
||||
<PartStyles/>
|
||||
<PartStylesViewer/>
|
||||
<PartParams/>
|
||||
<PartDownload/>
|
||||
<PartDownloadViewer/>
|
||||
<PartMore/>
|
||||
<Footer/>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,20 +1,31 @@
|
|||
import React from 'react';
|
||||
import './App.css';
|
||||
import DownloadSvg from "../../containers/download/DownloadSvg";
|
||||
import DownloadJpg from "../../containers/download/DownloadJpg";
|
||||
import {isWeiXin} from "../../utils/util";
|
||||
|
||||
const PartDownload = () => (
|
||||
const WxMessage = () => {
|
||||
if (isWeiXin()) {
|
||||
return <div className="note-font" id="wx-message-inner">当前客户端不支持下载,请在浏览器中打开。</div>
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const PartDownload = ({ value }) => (
|
||||
<div className="Qr-titled">
|
||||
<div className="Qr-Centered title-margin">
|
||||
<div className="Qr-s-title">Downloads</div>
|
||||
<p className="Qr-s-subtitle">下载二维码</p>
|
||||
<p className="Qr-s-subtitle">下载二维码 — {value}</p>
|
||||
</div>
|
||||
<div className="Qr-Centered">
|
||||
<div className="div-btn">
|
||||
<button className="dl-btn">SVG</button>
|
||||
<button className="dl-btn">JPG</button>
|
||||
<DownloadSvg/>
|
||||
<DownloadJpg/>
|
||||
</div>
|
||||
<div id="wx-message">
|
||||
<WxMessage/>
|
||||
</div>
|
||||
<div id="wx-message"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import React from 'react';
|
||||
import './App.css';
|
||||
import InputText from "../../containers/InputText";
|
||||
|
||||
const PartInput = () => (
|
||||
<div className="Qr-Centered">
|
||||
<InputText/>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default PartInput;
|
|
@ -10,9 +10,13 @@ const PartMore = () => (
|
|||
</div>
|
||||
<div className="Qr-Centered btn-row">
|
||||
<div className="div-btn">
|
||||
<LinkButton href={"https://www.yuque.com/qrbtf/docs"} value={"使用手册"} />
|
||||
<LinkButton href={"https://www.yuque.com/qrbtf/docs/donate"} value={"打赏 & 赞助"} />
|
||||
<LinkButton href={"https://www.yuque.com/qrbtf/topics"} value={"问题反馈"} />
|
||||
</div>
|
||||
<div className="div-btn">
|
||||
<LinkButton href={"https://www.yuque.com/qrbtf/docs/dev"} value={"开发与设计"} />
|
||||
<LinkButton href={"https://www.yuque.com/qrbtf/docs/coop"} value={"商业合作"} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import './App.css';
|
||||
import ParamListViewer from "../../containers/param/ParamListViewer";
|
||||
import ParamCorrectLevelViewer from "../../containers/param/ParamCorrectLevelViewer";
|
||||
|
||||
const PartParams = () => (
|
||||
<div className="Qr-titled-nobg">
|
||||
|
@ -12,22 +13,7 @@ const PartParams = () => (
|
|||
<div className="Qr-div-table">
|
||||
<table className="Qr-table">
|
||||
<tbody>
|
||||
{/*<tr>*/}
|
||||
{/* <td>容错率</td>*/}
|
||||
{/* <td>*/}
|
||||
{/* <select*/}
|
||||
{/* className="Qr-select"*/}
|
||||
{/* value={this.state.correctLevel}*/}
|
||||
{/* onChange={(e) => {*/}
|
||||
{/* this.setState({correctLevel: parseInt(e.target.value)}, () => this.handleCreate())*/}
|
||||
{/* }}>*/}
|
||||
{/* <option value={1}>7%</option>*/}
|
||||
{/* <option value={0}>15%</option>*/}
|
||||
{/* <option value={3}>25%</option>*/}
|
||||
{/* <option value={2}>30%</option>*/}
|
||||
{/* </select>*/}
|
||||
{/* </td>*/}
|
||||
{/*</tr>*/}
|
||||
<ParamCorrectLevelViewer/>
|
||||
<ParamListViewer/>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
import React from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import './App.css';
|
||||
import StyleListViewer from "../../containers/StyleListViewer";
|
||||
import StyleListViewer from "../../containers/style/StyleListViewer";
|
||||
|
||||
const PartStyles = () => (
|
||||
<div className="Qr-titled">
|
||||
const PartStyles = ({ setParamInfo }) => {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
useEffect(() => {
|
||||
setLoaded(true);
|
||||
}, [])
|
||||
const styleList = React.createElement(StyleListViewer({setParamInfo}))
|
||||
|
||||
return (<div className="Qr-titled">
|
||||
<div className="Qr-Centered title-margin">
|
||||
<div className="Qr-s-title">Styles</div>
|
||||
<p className="Qr-s-subtitle">点击选择样式</p>
|
||||
</div>
|
||||
<div className="Qr-s">
|
||||
{React.createElement(StyleListViewer())}
|
||||
{styleList}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
</div>)
|
||||
}
|
||||
|
||||
export default PartStyles;
|
||||
|
|
|
@ -8,14 +8,18 @@ const Footer = () => (
|
|||
<div className="Qr-Centered Qr-footer note-font">
|
||||
<div>
|
||||
<strong>作者</strong> 
|
||||
<a href="https://blog.ciaochaos.com/"
|
||||
<a
|
||||
href="https://blog.ciaochaos.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank">ciaochaos
|
||||
</a> 
|
||||
<a href="https://github.com/CPunisher/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank">CPunisher</a>
|
||||
target="_blank">CPunisher
|
||||
</a> 丨 
|
||||
<a href="https://www.yuque.com/qrbtf/docs/contact" rel="noopener noreferrer" target="_blank">联系我们</a>
|
||||
</div>
|
||||
|
||||
<div className="Gray">
|
||||
Copyright © {currentYear} QRBTF. 保留所有权利。
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from "react";
|
||||
import '../Qrcode.css';
|
||||
import logo from "../../qrbtf-logo.svg";
|
||||
import InputText from "../../containers/InputText";
|
||||
|
||||
const logoStyle = {
|
||||
background: `url(${logo})`,
|
||||
|
@ -13,7 +14,8 @@ const Header = () => (
|
|||
<div style={logoStyle}>
|
||||
<h1 className="Qr-title"> </h1>
|
||||
</div>
|
||||
<p className="Qr-subtitle">参数化二维码生成器</p>
|
||||
<p className="Qr-subtitle">参数化二维码生成器 <sup className="Gray">测试版</sup></p>
|
||||
<InputText/>
|
||||
</div>
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import '../Qrcode.css';
|
||||
|
||||
const ParamCorrectLevel = ({ value, onChange }) => (
|
||||
<tr>
|
||||
<td>容错率</td>
|
||||
<td>
|
||||
<select
|
||||
className="Qr-select"
|
||||
value={value}
|
||||
onChange={onChange}>
|
||||
<option value={1}>7%</option>
|
||||
<option value={0}>15%</option>
|
||||
<option value={3}>25%</option>
|
||||
<option value={2}>30%</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
|
||||
ParamCorrectLevel.propTypes = {
|
||||
value: PropTypes.number.isRequired,
|
||||
onChange: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
export default ParamCorrectLevel;
|
|
@ -9,7 +9,7 @@ const ParamList = ({ rendererIndex, paramInfo }) => (
|
|||
switch (item.type) {
|
||||
case ParamTypes.TEXT_EDITOR: {
|
||||
return (
|
||||
<tr>
|
||||
<tr key={"tr_" + rendererIndex + "_" + paramIndex}>
|
||||
<td>{item.key}</td>
|
||||
<td>
|
||||
<ParamTextViewer rendererIndex={rendererIndex} paramIndex={paramIndex}/>
|
||||
|
@ -19,7 +19,7 @@ const ParamList = ({ rendererIndex, paramInfo }) => (
|
|||
}
|
||||
case ParamTypes.SELECTOR: {
|
||||
return (
|
||||
<tr>
|
||||
<tr key={"tr_" + rendererIndex + "_" + paramIndex}>
|
||||
<td>{item.key}</td>
|
||||
<td>
|
||||
<ParamSelectViewer rendererIndex={rendererIndex} paramIndex={paramIndex}/>
|
||||
|
|
|
@ -59,13 +59,20 @@ function getParamInfo() {
|
|||
];
|
||||
}
|
||||
|
||||
function viewBox(qrcode) {
|
||||
if (!qrcode) return '0 0 0 0';
|
||||
|
||||
const nCount = qrcode.getModuleCount();
|
||||
return String(-nCount) + ' ' + String(-nCount / 2) + ' ' + String(nCount * 2) + ' ' + String(nCount * 2);
|
||||
}
|
||||
|
||||
const Renderer25D = ({ qrcode, params, setParamInfo}) => {
|
||||
useEffect(() => {
|
||||
setParamInfo(getParamInfo());
|
||||
}, [setParamInfo]);
|
||||
|
||||
return (
|
||||
<svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(qrcode)} fill="white"
|
||||
<svg className="Qr-item-svg" width="100%" height="100%" viewBox={viewBox(qrcode)} fill="white"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
||||
{listPoints(qrcode, params)}
|
||||
</svg>
|
||||
|
|
|
@ -17,7 +17,8 @@ function listPoints(qrcode, params) {
|
|||
let posType = params[2];
|
||||
let id = 0;
|
||||
|
||||
if (width2 <= 0) width2 = 80;
|
||||
if (width2 <= 0) width2 = 70;
|
||||
if (width1 <= 0) width1 = 70;
|
||||
|
||||
let available = [];
|
||||
let ava2 = [];
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import React from "react";
|
||||
|
||||
const Renderer = ({ rendererType, ...other }) => (
|
||||
React.createElement(rendererType, other)
|
||||
)
|
||||
|
||||
function areEqual(prevProps, nextProps) {
|
||||
return !(prevProps.selected == true || nextProps.selected == true)
|
||||
}
|
||||
|
||||
export default React.memo(Renderer, areEqual)
|
|
@ -1,6 +1,7 @@
|
|||
export const actionTypes = {
|
||||
GENERATE_QR_INFO: 'GENERATE_QR_INFO',
|
||||
CHANGE_STYLE: 'CHANGE_STYLE',
|
||||
CHANGE_CORRECT_LEVEL: 'CHANGE_CORRECT_LEVEL',
|
||||
CREATE_PARAM: 'CREATE_PARAM',
|
||||
CHANGE_PARAM: 'CHANGE_PARAM'
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export const QRBTF_URL = 'https://qrbtf.com'
|
|
@ -1,16 +1,16 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { genQRInfo } from "../actions";
|
||||
import {connect} from 'react-redux';
|
||||
import {genQRInfo} from "../actions";
|
||||
import React from "react";
|
||||
|
||||
const InputText = ({ dispatch }) => (
|
||||
<div className="Qr-Centered">
|
||||
const InputText = ({dispatch}) => (
|
||||
<input
|
||||
className="Qr-input big-input"
|
||||
placeholder="Input your URL here"
|
||||
onBlur={e => dispatch(genQRInfo(e.target.value))}
|
||||
onKeyPress={(e) => {if(e.key === 'Enter') dispatch(genQRInfo(e.target.value))}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') dispatch(genQRInfo(e.target.value))
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default connect()(InputText);
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
import {connect} from 'react-redux';
|
||||
import * as React from "react";
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
qrcode: state.qrcode,
|
||||
params: state.paramValue[ownProps.index],
|
||||
rendererIndex: ownProps.index
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
setParamInfo: (params) => ownProps.setParamInfo(ownProps.index, params)
|
||||
})
|
||||
|
||||
export default function Renderer(WrappedRenderer) {
|
||||
return connect(mapStateToProps, mapDispatchToProps)(WrappedRenderer)
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
import {connect, useDispatch} from 'react-redux';
|
||||
import {changeStyle, createParam} from "../actions";
|
||||
import StyleList from "../components/style/StyleList";
|
||||
import Renderer from "./Renderer";
|
||||
import RendererBlank from "../components/renderer/RendererBlank";
|
||||
import RendererBase from "../components/renderer/RendererBase";
|
||||
import RendererDSJ from "../components/renderer/RendererDSJ";
|
||||
import RendererRound from "../components/renderer/RendererRound";
|
||||
import RendererRandRound from "../components/renderer/RendererRandRound";
|
||||
import RendererRandRect from "../components/renderer/RendererRandRect";
|
||||
import Renderer25D from "../components/renderer/Renderer25D";
|
||||
import RendererImage from "../components/renderer/RendererImage";
|
||||
import * as React from "react";
|
||||
|
||||
const styles = [
|
||||
{value: "A1", renderer: RendererBase},
|
||||
{value: "A2", renderer: RendererRound},
|
||||
{value: "A3", renderer: RendererRandRound},
|
||||
{value: "SP — 1", renderer: RendererDSJ},
|
||||
{value: "SP — 2", renderer: RendererRandRect},
|
||||
{value: "B1", renderer: Renderer25D},
|
||||
{value: "C1", renderer: RendererImage},
|
||||
{value: "D1", renderer: RendererBlank},
|
||||
]
|
||||
|
||||
const paramInfoBuffer = new Array(16).fill(new Array(16))
|
||||
const paramValueBuffer = new Array(16).fill(new Array(16))
|
||||
|
||||
const setParamInfo = (renderIndex, paramInfo) => {
|
||||
paramInfoBuffer[renderIndex] = paramInfo
|
||||
paramValueBuffer[renderIndex] = paramInfo.map(item => item.default)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
styles: styles.map((style, index) => {
|
||||
return {
|
||||
value: style.value,
|
||||
selected: state.selectedIndex == index,
|
||||
renderer: React.createElement(Renderer(style.renderer), {
|
||||
index: index,
|
||||
setParamInfo: setParamInfo
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onSelected: index => {
|
||||
dispatch(changeStyle(index))
|
||||
}
|
||||
})
|
||||
|
||||
const StyleListViewer = () => {
|
||||
let res = connect(mapStateToProps, mapDispatchToProps)(StyleList)
|
||||
const dispatch = useDispatch()
|
||||
dispatch(createParam(paramInfoBuffer, paramValueBuffer))
|
||||
return res;
|
||||
}
|
||||
|
||||
export default StyleListViewer;
|
|
@ -0,0 +1,8 @@
|
|||
import { connect } from 'react-redux';
|
||||
import PartDownload from "../../components/app/PartDownload";
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
value: state.value
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, null)(PartDownload)
|
|
@ -0,0 +1,9 @@
|
|||
import {connect} from "react-redux";
|
||||
import PartStyles from "../../components/app/PartStyles";
|
||||
import {createParam} from "../../actions";
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setParamInfo: (paramInfo, paramValue) => dispatch(createParam(paramInfo, paramValue))
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps)(PartStyles)
|
|
@ -0,0 +1,34 @@
|
|||
import { connect } from 'react-redux';
|
||||
import React from 'react';
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import DownloadButton from "../../components/download/DownloadButton";
|
||||
import {saveImg} from "../../utils/downloader";
|
||||
import {increaseDownloadData, recordDownloadDetail} from "../../api/db";
|
||||
import {getParamDetailedValue} from "../../utils/util";
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
value: 'JPG',
|
||||
onClick: () => {
|
||||
const el = React.createElement(state.rendererType, {
|
||||
qrcode: state.qrcode,
|
||||
params: state.paramValue[state.selectedIndex],
|
||||
setParamInfo: () => {}
|
||||
});
|
||||
saveImg(state.value, ReactDOMServer.renderToString(el), 1500, 1500);
|
||||
increaseDownloadData(state.value)
|
||||
recordDownloadDetail({
|
||||
text: state.textUrl,
|
||||
value: state.value,
|
||||
type: 'jpg',
|
||||
params: state.paramInfo[state.selectedIndex].map((item, index) => {
|
||||
return {
|
||||
key: item.key,
|
||||
value: getParamDetailedValue(item, state.paramValue[state.selectedIndex][index])
|
||||
}
|
||||
}),
|
||||
history: state.history
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null)(DownloadButton)
|
|
@ -0,0 +1,34 @@
|
|||
import { connect } from 'react-redux';
|
||||
import React from 'react';
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import DownloadButton from "../../components/download/DownloadButton";
|
||||
import {saveSvg} from "../../utils/downloader";
|
||||
import {increaseDownloadData, recordDownloadDetail} from "../../api/db";
|
||||
import {getParamDetailedValue} from "../../utils/util";
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
value: 'SVG',
|
||||
onClick: () => {
|
||||
const el = React.createElement(state.rendererType, {
|
||||
qrcode: state.qrcode,
|
||||
params: state.paramValue[state.selectedIndex],
|
||||
setParamInfo: () => {}
|
||||
});
|
||||
saveSvg(state.value, ReactDOMServer.renderToString(el));
|
||||
increaseDownloadData(state.value)
|
||||
recordDownloadDetail({
|
||||
text: state.textUrl,
|
||||
value: state.value,
|
||||
type: 'svg',
|
||||
params: state.paramInfo[state.selectedIndex].map((item, index) => {
|
||||
return {
|
||||
key: item.key,
|
||||
value: getParamDetailedValue(item, state.paramValue[state.selectedIndex][index])
|
||||
}
|
||||
}),
|
||||
history: state.history
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null)(DownloadButton)
|
|
@ -0,0 +1,15 @@
|
|||
import {changeCorrectLevel} from "../../actions";
|
||||
import ParamCorrectLevel from "../../components/param/ParamCorrectLevel";
|
||||
import {connect} from "react-redux";
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
value: state.correctLevel
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onChange: (e) => {
|
||||
dispatch(changeCorrectLevel(e.target.value));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ParamCorrectLevel)
|
|
@ -5,7 +5,7 @@ import {changeParam} from "../../actions";
|
|||
const mapStateToProps = (state, ownProps) => ({
|
||||
rendererIndex: ownProps.rendererIndex,
|
||||
paramIndex: ownProps.paramIndex,
|
||||
value: state.paramValue[ownProps.rendererIndex][ownProps.paramIndex]
|
||||
value: String(state.paramValue[ownProps.rendererIndex][ownProps.paramIndex])
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import {connect} from 'react-redux';
|
||||
import Renderer from "../../components/style/Renderer";
|
||||
import {fillEmptyWith} from "../../utils/util";
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
rendererType: ownProps.rendererType,
|
||||
rendererIndex: ownProps.index,
|
||||
qrcode: state.qrcode,
|
||||
params: fillEmptyWith(state.paramValue[ownProps.index].slice(), 0),
|
||||
selected: state.selectedIndex == ownProps.index,
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
setParamInfo: (params) => ownProps.setParamInfo(ownProps.index, params)
|
||||
})
|
||||
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Renderer)
|
|
@ -0,0 +1,56 @@
|
|||
import {connect, useDispatch} from 'react-redux';
|
||||
import {changeStyle, createParam} from "../../actions";
|
||||
import StyleList from "../../components/style/StyleList";
|
||||
import RendererViewer from "./RendererViewer";
|
||||
import RendererBlank from "../../components/renderer/RendererBlank";
|
||||
import RendererBase from "../../components/renderer/RendererBase";
|
||||
import RendererDSJ from "../../components/renderer/RendererDSJ";
|
||||
import RendererRound from "../../components/renderer/RendererRound";
|
||||
import RendererRandRound from "../../components/renderer/RendererRandRound";
|
||||
import RendererRandRect from "../../components/renderer/RendererRandRect";
|
||||
import Renderer25D from "../../components/renderer/Renderer25D";
|
||||
import RendererImage from "../../components/renderer/RendererImage";
|
||||
import * as React from "react";
|
||||
|
||||
const styles = [
|
||||
{value: "A1", renderer: RendererBase},
|
||||
{value: "A2", renderer: RendererRound},
|
||||
{value: "A3", renderer: RendererRandRound},
|
||||
{value: "SP — 1", renderer: RendererDSJ},
|
||||
{value: "SP — 2", renderer: RendererRandRect},
|
||||
{value: "B1", renderer: Renderer25D},
|
||||
{value: "C1", renderer: RendererImage},
|
||||
{value: "D1", renderer: RendererBlank},
|
||||
]
|
||||
|
||||
const paramInfoBuffer = new Array(16).fill(new Array(16))
|
||||
const paramValueBuffer = new Array(16).fill(new Array(16))
|
||||
|
||||
const setParamInfo = (renderIndex, paramInfo) => {
|
||||
paramInfoBuffer[renderIndex] = paramInfo
|
||||
paramValueBuffer[renderIndex] = paramInfo.map(item => parseInt(item.default))
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
styles: styles.map((style, index) => {
|
||||
return {
|
||||
value: style.value,
|
||||
selected: state.selectedIndex == index,
|
||||
renderer: <RendererViewer rendererType={style.renderer} index={index} setParamInfo={setParamInfo}/>
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onSelected: rendererIndex => {
|
||||
dispatch(changeStyle(rendererIndex, styles[rendererIndex].renderer, styles[rendererIndex].value))
|
||||
}
|
||||
})
|
||||
|
||||
const StyleListViewer = ({setParamInfo}) => {
|
||||
let res = connect(mapStateToProps, mapDispatchToProps)(StyleList)
|
||||
setParamInfo(paramInfoBuffer, paramValueBuffer);
|
||||
return res;
|
||||
}
|
||||
|
||||
export default StyleListViewer;
|
|
@ -1,25 +1,45 @@
|
|||
import {getQrcodeData} from "../utils/qrcodeHandler";
|
||||
import {actionTypes} from "../constant/ActionTypes";
|
||||
import {QRBTF_URL} from "../constant/References";
|
||||
import RendererBase from "../components/renderer/RendererBase";
|
||||
|
||||
const initialState = {
|
||||
selectedIndex: 0,
|
||||
qrcode: null,
|
||||
value: 'A1',
|
||||
rendererType: RendererBase,
|
||||
correctLevel: 0,
|
||||
textUrl: QRBTF_URL,
|
||||
history: [],
|
||||
qrcode: getQrcodeData({text: QRBTF_URL, correctLevel: 0}),
|
||||
paramInfo: new Array(16).fill(new Array(16)),
|
||||
paramValue: new Array(16).fill(new Array(16))
|
||||
}
|
||||
|
||||
export default function appReducer(state = initialState, action) {
|
||||
console.log(state)
|
||||
switch (action.type) {
|
||||
case actionTypes.GENERATE_QR_INFO: {
|
||||
let text = action.text;
|
||||
if (!text || text.length == 0) text = QRBTF_URL;
|
||||
return Object.assign({}, state, {
|
||||
qrcode: getQrcodeData({text: action.text})
|
||||
textUrl: text,
|
||||
qrcode: getQrcodeData({text: text, correctLevel: state.correctLevel})
|
||||
});
|
||||
}
|
||||
case actionTypes.CHANGE_STYLE: {
|
||||
return Object.assign({}, state, {
|
||||
selectedIndex: action.index
|
||||
value: action.value,
|
||||
rendererType: action.rendererType,
|
||||
selectedIndex: action.rendererIndex,
|
||||
history: state.history.slice().concat(action.value)
|
||||
});
|
||||
}
|
||||
case actionTypes.CHANGE_CORRECT_LEVEL: {
|
||||
return Object.assign({}, state, {
|
||||
correctLevel: parseInt(action.correctLevel),
|
||||
qrcode: getQrcodeData({text: state.textUrl, correctLevel: parseInt(action.correctLevel)})
|
||||
})
|
||||
}
|
||||
case actionTypes.CREATE_PARAM: {
|
||||
return Object.assign({}, state, {
|
||||
paramInfo: action.paramInfo,
|
||||
|
@ -34,7 +54,7 @@ export default function appReducer(state = initialState, action) {
|
|||
}
|
||||
|
||||
const newItem = item.slice();
|
||||
newItem[action.paramIndex] = action.value;
|
||||
newItem[action.paramIndex] = parseInt(action.value);
|
||||
return newItem;
|
||||
})
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import {ParamTypes} from "../constant/ParamTypes";
|
||||
|
||||
let seed = 0;
|
||||
|
||||
export function srand(sd) {
|
||||
|
@ -20,6 +22,12 @@ export function defaultViewBox(qrcode) {
|
|||
return String(-nCount / 5) + ' ' + String(-nCount / 5) + ' ' + String(nCount + nCount / 5 * 2) + ' ' + String(nCount + nCount / 5 * 2);
|
||||
}
|
||||
|
||||
export function fillEmptyWith(arr, value) {
|
||||
for (let i = 0; i < arr.length; i++)
|
||||
if (!arr[i]) arr[i] = value;
|
||||
return arr;
|
||||
}
|
||||
|
||||
export function isWeiXin(){
|
||||
const ua = window.navigator.userAgent.toLowerCase();
|
||||
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
|
||||
|
@ -28,3 +36,8 @@ export function isWeiXin(){
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getParamDetailedValue(item, paramValue) {
|
||||
if (item.type == ParamTypes.SELECTOR) return item.choices[paramValue];
|
||||
return paramValue;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue