Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
CPunisher | c7e9efb7c8 | |
CPunisher | effe43a91c | |
CPunisher | 006fee6490 | |
CPunisher | 6fed952a22 | |
CPunisher | f06f2c9b2a |
|
@ -0,0 +1,15 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="p-id" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
|
@ -0,0 +1 @@
|
||||||
|
[0113/225246.323:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
|
|
@ -7,6 +7,7 @@
|
||||||
"@testing-library/react": "^9.3.2",
|
"@testing-library/react": "^9.3.2",
|
||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^7.1.2",
|
||||||
"jsqr": "^1.3.1",
|
"jsqr": "^1.3.1",
|
||||||
|
"jszip": "^3.7.1",
|
||||||
"medium-zoom": "^1.0.5",
|
"medium-zoom": "^1.0.5",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
"react-github-btn": "^1.2.0",
|
"react-github-btn": "^1.2.0",
|
||||||
"react-indiana-drag-scroll": "^1.6.1",
|
"react-indiana-drag-scroll": "^1.6.1",
|
||||||
"react-lazy-load": "^3.0.13",
|
"react-lazy-load": "^3.0.13",
|
||||||
|
"react-modal": "^3.12.1",
|
||||||
"react-redux": "^7.2.0",
|
"react-redux": "^7.2.0",
|
||||||
"react-scripts": "3.4.1",
|
"react-scripts": "3.4.1",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
|
|
|
@ -1,16 +1,25 @@
|
||||||
import {actionTypes} from "../constant/ActionTypes";
|
import {actionTypes} from "../constant/ActionTypes";
|
||||||
import {handleStyle} from "../utils/gaHelper";
|
import {handleStyle} from "../utils/gaHelper";
|
||||||
|
|
||||||
export const genQRInfo = text => ({
|
export const genQRInfo = text => {
|
||||||
|
if (Array.isArray(text)) {
|
||||||
|
return {
|
||||||
|
type: actionTypes.GENERATE_QR_INFO,
|
||||||
|
text: text[0],
|
||||||
|
textArray: text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
type: actionTypes.GENERATE_QR_INFO,
|
type: actionTypes.GENERATE_QR_INFO,
|
||||||
text
|
text
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const changeStyle = (rendererIndex, rendererType, value) => {
|
export const changeStyle = (rendererIndex, value) => {
|
||||||
handleStyle(value);
|
handleStyle(value);
|
||||||
return {
|
return {
|
||||||
type: actionTypes.CHANGE_STYLE,
|
type: actionTypes.CHANGE_STYLE,
|
||||||
rendererIndex, rendererType, value
|
rendererIndex, value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -318,7 +318,7 @@ td {
|
||||||
.Qr-input-upload {
|
.Qr-input-upload {
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: calc(100vw - 46px);
|
max-width: calc(100vw - 46px);
|
||||||
width: 20em;
|
width: 22em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Qr-input-upload-div {
|
.Qr-input-upload-div {
|
||||||
|
@ -360,7 +360,7 @@ td {
|
||||||
height: calc(2em + 6px);
|
height: calc(2em + 6px);
|
||||||
font-size: calc(10px + 2vmin);
|
font-size: calc(10px + 2vmin);
|
||||||
border: var(--border-color) solid 2px;
|
border: var(--border-color) solid 2px;
|
||||||
margin-left: 10px;
|
margin: 0 10px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +372,7 @@ td {
|
||||||
|
|
||||||
.Qr-upload {
|
.Qr-upload {
|
||||||
color: var(--upload-color);
|
color: var(--upload-color);
|
||||||
|
fill: var(--upload-color);
|
||||||
font-size: calc(10px + 2vmin);
|
font-size: calc(10px + 2vmin);
|
||||||
border: var(--border-color) solid 2px;
|
border: var(--border-color) solid 2px;
|
||||||
width: calc(2em + 6px)!important;
|
width: calc(2em + 6px)!important;
|
||||||
|
@ -409,6 +410,7 @@ td {
|
||||||
.Qr-upload:hover {
|
.Qr-upload:hover {
|
||||||
border-color: var(--border-color-focus);
|
border-color: var(--border-color-focus);
|
||||||
color: var(--border-color-focus);
|
color: var(--border-color-focus);
|
||||||
|
fill: var(--border-color-focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Qr-upload:active {
|
.Qr-upload:active {
|
||||||
|
@ -417,6 +419,7 @@ td {
|
||||||
-moz-transition-duration: 0s;
|
-moz-transition-duration: 0s;
|
||||||
border-color: #3BBC9F;
|
border-color: #3BBC9F;
|
||||||
color: #3BBC9F;
|
color: #3BBC9F;
|
||||||
|
fill: #3BBC9F;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Qr-upload-svg {
|
.Qr-upload-svg {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, {useState} from 'react';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {isWeiXin} from "../../utils/navigatorUtils";
|
import {isWeiXin} from "../../utils/navigatorUtils";
|
||||||
|
import PresetModalViewer from "../../containers/preset/PresetModalViewer";
|
||||||
|
|
||||||
const CountComponent = ({ value }) => {
|
const CountComponent = ({ value }) => {
|
||||||
if (isNaN(value)) return null;
|
if (isNaN(value)) return null;
|
||||||
|
@ -34,24 +35,31 @@ const ImgBox = ({ imgData }) => {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const PartDownload = ({ value, downloadCount, onSvgDownload, onImgDownload }) => {
|
const PartDownload = ({ value, batchMode, downloadCount, onSvgDownload, onImgDownload, savePreset }) => {
|
||||||
const [imgData, setImgData] = useState('');
|
const [imgData, setImgData] = useState('');
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Qr-titled">
|
<div className="Qr-titled">
|
||||||
<div className="Qr-Centered title-margin">
|
<div className="Qr-Centered title-margin">
|
||||||
<div className="Qr-s-title">Downloads</div>
|
<div className="Qr-s-title">Downloads</div>
|
||||||
<p className="Qr-s-subtitle">
|
<p className="Qr-s-subtitle">
|
||||||
<span>下载二维码 — {value}</span>
|
<span>下载二维码</span>
|
||||||
|
<span>({batchMode ? "批量模式" : "单文件模式"})</span>
|
||||||
|
<span> — {value}</span>
|
||||||
<CountComponent value={downloadCount} />
|
<CountComponent value={downloadCount} />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="Qr-Centered">
|
<div className="Qr-Centered">
|
||||||
|
<PresetModalViewer visible={visible} onClose={() => setVisible(false)} />
|
||||||
<div className="btn-row">
|
<div className="btn-row">
|
||||||
<div className="div-btn img-dl-btn">
|
<div className="div-btn img-dl-btn">
|
||||||
<button className="dl-btn" onClick={() => {onImgDownload("jpg").then(res => setImgData(res));}}>JPG</button>
|
<button className="dl-btn" onClick={() => {onImgDownload("jpg").then(res => setImgData(res));}}>JPG</button>
|
||||||
<button className="dl-btn" onClick={() => {onImgDownload("png").then(res => setImgData(res));}}>PNG</button>
|
<button className="dl-btn" onClick={() => {onImgDownload("png").then(res => setImgData(res));}}>PNG</button>
|
||||||
<button className="dl-btn" onClick={onSvgDownload}>SVG</button>
|
<button className="dl-btn" onClick={onSvgDownload}>SVG</button>
|
||||||
|
|
||||||
|
<button className="dl-btn" onClick={() => setVisible(true)}>管理预设</button>
|
||||||
|
<button className="dl-btn" onClick={savePreset}>保存预设</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="wx-message">
|
<div id="wx-message">
|
||||||
|
|
|
@ -51,6 +51,7 @@ const PartMore = () => {
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
<div className="Qr-Centered">
|
<div className="Qr-Centered">
|
||||||
<h2>最新消息</h2>
|
<h2>最新消息</h2>
|
||||||
|
<p><b>2021.10.5</b><br/>新增批量生成二维码。</p>
|
||||||
<p><b>2020.9.1</b><br/>新增 C3 样式、图标插入、 PNG 下载。</p>
|
<p><b>2020.9.1</b><br/>新增 C3 样式、图标插入、 PNG 下载。</p>
|
||||||
<p><b>2020.6.29</b><br/>新的反馈渠道!我们开始征集好玩的二维码设计啦,可以是推送尾图、海报等等,快来上传吧。<LinkTrace
|
<p><b>2020.6.29</b><br/>新的反馈渠道!我们开始征集好玩的二维码设计啦,可以是推送尾图、海报等等,快来上传吧。<LinkTrace
|
||||||
href='https://qrbtf-com.mikecrm.com/J2wjEEq' rel="noopener noreferrer"
|
href='https://qrbtf-com.mikecrm.com/J2wjEEq' rel="noopener noreferrer"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import '../Qrcode.css';
|
import '../Qrcode.css';
|
||||||
|
|
||||||
const FrameworkParam = ({ paramName, children, ...other }) => (
|
const FrameworkParam = ({ paramName, children, ...other }) => (
|
||||||
|
|
|
@ -9,7 +9,7 @@ const IconParams = ({ icon, onBlur, onKeyPress }) => {
|
||||||
const { enabled, src, scale } = icon;
|
const { enabled, src, scale } = icon;
|
||||||
const components = [];
|
const components = [];
|
||||||
|
|
||||||
if (getExactValue(enabled, 0) == 1) {
|
if (getExactValue(enabled, 0) === 1) {
|
||||||
components.push(
|
components.push(
|
||||||
<FrameworkParam paramName={"图标源"}>
|
<FrameworkParam paramName={"图标源"}>
|
||||||
<ParamIconSrcViewer icon={icon} onChange={onBlur}/>
|
<ParamIconSrcViewer icon={icon} onChange={onBlur}/>
|
||||||
|
@ -17,7 +17,7 @@ const IconParams = ({ icon, onBlur, onKeyPress }) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getExactValue(enabled, 0) != 0) {
|
if (getExactValue(enabled, 0) !== 0) {
|
||||||
components.push(
|
components.push(
|
||||||
<FrameworkParam paramName={"图标缩放"}>
|
<FrameworkParam paramName={"图标缩放"}>
|
||||||
<input
|
<input
|
||||||
|
@ -38,7 +38,7 @@ const ParamIcon = ({icon, onBlur, onKeyPress}) => (
|
||||||
<FrameworkParam paramName={"图标"}>
|
<FrameworkParam paramName={"图标"}>
|
||||||
<select
|
<select
|
||||||
className="Qr-select"
|
className="Qr-select"
|
||||||
defaultValue={icon.enabled}
|
value={icon.enabled}
|
||||||
onChange={(e) => onBlur({...icon, enabled: e.target.value})}>
|
onChange={(e) => onBlur({...icon, enabled: e.target.value})}>
|
||||||
<option value={0}>无</option>
|
<option value={0}>无</option>
|
||||||
<option value={1}>自定义</option>
|
<option value={1}>自定义</option>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
.ReactModal__Overlay {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReactModal__Overlay--after-open{
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReactModal__Overlay--before-close{
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Qr-preset-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Qr-preset-side {
|
||||||
|
width: 70%;
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Qr-preset-detail {
|
||||||
|
width: 40%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import React from "react";
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const PresetCard = ({ preset }) => (
|
||||||
|
<div className="Qr-Centered">
|
||||||
|
<div className="Qr-item-image">
|
||||||
|
<div className="Qr-item-image-inner">
|
||||||
|
<img id="dl-image-inner-jpg" src={preset.preview}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="Qr-item-detail">
|
||||||
|
{preset.name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
PresetCard.propTypes = {
|
||||||
|
preset: PropTypes.shape({
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
styleName: PropTypes.string.isRequired,
|
||||||
|
preview: PropTypes.string.isRequired,
|
||||||
|
params: PropTypes.array.isRequired,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PresetCard;
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React from "react";
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const ParamLabel = ({ params, label }) => (
|
||||||
|
params.map((param, index) => {
|
||||||
|
if (param.value.length > 30) return null;
|
||||||
|
return (
|
||||||
|
<table key={label + '_' + index} className="Qr-table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{param.name}</td>
|
||||||
|
<td>{param.value}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const PresetDetail = ({ preset }) => (
|
||||||
|
<div className="Qr-Centered">
|
||||||
|
<div id="dl-image">
|
||||||
|
<div id="dl-image-inner">
|
||||||
|
<img id="dl-image-inner-jpg" src={preset.preview}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table className="Qr-table">
|
||||||
|
<tbody><tr>
|
||||||
|
<td>样式名</td>
|
||||||
|
<td>{preset.styleName}</td>
|
||||||
|
</tr></tbody>
|
||||||
|
</table>
|
||||||
|
<ParamLabel params={preset.params} label="preset_param"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
PresetDetail.propTypes = {
|
||||||
|
preset: PropTypes.shape({
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
styleName: PropTypes.string.isRequired,
|
||||||
|
preview: PropTypes.string.isRequired,
|
||||||
|
globalParams: PropTypes.array.isRequired,
|
||||||
|
params: PropTypes.array.isRequired,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PresetDetail;
|
|
@ -0,0 +1,80 @@
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import Modal from "react-modal";
|
||||||
|
import './Preset.css';
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import PresetCard from "./PresetCard";
|
||||||
|
import PresetDetail from "./PresetDetail";
|
||||||
|
import ScrollContainer from "react-indiana-drag-scroll";
|
||||||
|
import {getPresets, removePreset} from "../../utils/storageUtils";
|
||||||
|
|
||||||
|
function calClassName(selected) {
|
||||||
|
if (selected === true) return 'Qr-item Qr-item-selected';
|
||||||
|
return 'Qr-item';
|
||||||
|
}
|
||||||
|
|
||||||
|
const customStyles = {
|
||||||
|
content: {
|
||||||
|
inset: '40px 60px 40px 60px',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PresetModal = ({ visible, onClose, loadPreset }) => {
|
||||||
|
const storedPresets = getPresets();
|
||||||
|
const [selected, setSelected] = useState(0);
|
||||||
|
const [presets, setPresets] = useState(storedPresets);
|
||||||
|
if (presets.length !== storedPresets.length) setPresets(storedPresets);
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
appElement={document.getElementById("root")}
|
||||||
|
closeTimeoutMS={100}
|
||||||
|
isOpen={visible}
|
||||||
|
onRequestClose={onClose}
|
||||||
|
style={customStyles}>
|
||||||
|
<div className="Qr-preset-container">
|
||||||
|
<ScrollContainer
|
||||||
|
className="Qr-div-table Qr-preset-side"
|
||||||
|
vertical={true}
|
||||||
|
horizontal={false}
|
||||||
|
hideScrollbars={false}>
|
||||||
|
{
|
||||||
|
presets.map((preset, index) => (
|
||||||
|
<div
|
||||||
|
key={'preset_' + index}
|
||||||
|
className={calClassName(selected === index)}
|
||||||
|
onClick={() => setSelected(index)}>
|
||||||
|
<PresetCard preset={preset}/>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ScrollContainer>
|
||||||
|
<div className="Qr-preset-detail">
|
||||||
|
{presets[selected] ? <PresetDetail preset={presets[selected]}/> : null}
|
||||||
|
<div>
|
||||||
|
<button className="dl-btn" onClick={() => {
|
||||||
|
if (presets[selected]) {
|
||||||
|
loadPreset(presets[selected]);
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
}}>加载预设</button>
|
||||||
|
<button className="dl-btn" onClick={() => {
|
||||||
|
if (presets[selected]) {
|
||||||
|
removePreset(selected);
|
||||||
|
setPresets(getPresets())
|
||||||
|
}
|
||||||
|
}}>删除预设</button>
|
||||||
|
<button className="dl-btn" onClick={onClose}>取消</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PresetModal.propTypes = {
|
||||||
|
visible: PropTypes.bool,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
presetArray: PropTypes.array.isRequired,
|
||||||
|
loadPreset: PropTypes.func.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PresetModal;
|
|
@ -34,13 +34,13 @@ function listPoints({ qrcode, params, icon }) {
|
||||||
if (qrcode.isDark(x, y) === false) continue;
|
if (qrcode.isDark(x, y) === false) continue;
|
||||||
else if (typeTable[x][y] === QRPointType.POS_OTHER || typeTable[x][y] === QRPointType.POS_CENTER) {
|
else if (typeTable[x][y] === QRPointType.POS_OTHER || typeTable[x][y] === QRPointType.POS_CENTER) {
|
||||||
pointList.push(<rect width={size2} height={size2} key={id++} fill={upColor} x={x + (1 - size2)/2} y={y + (1 - size2)/2} transform={matrixString}/>);
|
pointList.push(<rect width={size2} height={size2} key={id++} fill={upColor} x={x + (1 - size2)/2} y={y + (1 - size2)/2} transform={matrixString}/>);
|
||||||
pointList.push(<rect width={height2} height={size2} key={id++} fill={leftColor} x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size2)/2 + size2)+','+String(y + (1 - size2)/2)+') '+'skewY(45) '}/>);
|
pointList.push(<rect width={height2} height={size2} key={id++} fill={leftColor} x={0} y={0} transform={`${matrixString} translate(${x + (1 - size2)/2 + size2}, ${y + (1 - size2)/2}) skewY(45)`}/>);
|
||||||
pointList.push(<rect width={size2} height={height2} key={id++} fill={rightColor} x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size2)/2)+','+String(y + size2 + (1 - size2)/2)+') '+'skewX(45) '}/>);
|
pointList.push(<rect width={size2} height={height2} key={id++} fill={rightColor} x={0} y={0} transform={`${matrixString} translate(${x + (1 - size2)/2}, ${y + size2 + (1 - size2)/2}) skewX(45)`}/>);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pointList.push(<rect width={size} height={size} key={id++} fill={upColor} x={x + (1 - size)/2} y={y + (1 - size)/2} transform={matrixString}/>);
|
pointList.push(<rect width={size} height={size} key={id++} fill={upColor} x={x + (1 - size)/2} y={y + (1 - size)/2} transform={matrixString}/>);
|
||||||
pointList.push(<rect width={height} height={size} key={id++} fill={leftColor} x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size)/2 + size)+','+String(y + (1 - size)/2)+') '+'skewY(45) '}/>);
|
pointList.push(<rect width={height} height={size} key={id++} fill={leftColor} x={0} y={0} transform={`${matrixString} translate(${x + (1 - size)/2 + size}, ${y + (1 - size)/2}) skewY(45)`}/>);
|
||||||
pointList.push(<rect width={size} height={height} key={id++} fill={rightColor} x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size)/2)+','+String(y + size + (1 - size)/2)+') '+'skewX(45) '}/>);
|
pointList.push(<rect width={size} height={height} key={id++} fill={rightColor} x={0} y={0} transform={`${matrixString} translate(${x + (1 - size)/2}, ${y + size + (1 - size)/2}) skewX(45)`}/>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,13 +100,14 @@ let defaultDrawIcon = function ({ qrcode, params, title, icon }) {
|
||||||
const randomIdClips = getIdNum();
|
const randomIdClips = getIdNum();
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g transform={matrixString}>
|
<g transform={matrixString}>
|
||||||
<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} />
|
<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />
|
||||||
</g>
|
</g>
|
||||||
);
|
);
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g key={id++} transform={matrixString}>
|
<g key={id++} transform={matrixString}>
|
||||||
<defs>
|
<defs>
|
||||||
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} /> </defs>
|
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />
|
||||||
|
</defs>
|
||||||
<clipPath id={"clip-path" + randomIdClips}>
|
<clipPath id={"clip-path" + randomIdClips}>
|
||||||
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
|
@ -184,18 +185,19 @@ let builtinDrawIcon = function ({ qrcode, params, title, icon }) {
|
||||||
const randomIdClips = getIdNum();
|
const randomIdClips = getIdNum();
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g transform={matrixString}>
|
<g transform={matrixString}>
|
||||||
<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} />
|
<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />
|
||||||
</g>
|
</g>
|
||||||
);
|
);
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g key={id++} transform={matrixString}>
|
<g key={id++} transform={matrixString}>
|
||||||
<defs>
|
<defs>
|
||||||
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} /> </defs>
|
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />
|
||||||
|
</defs>
|
||||||
<clipPath id={"clip-path" + randomIdClips}>
|
<clipPath id={"clip-path" + randomIdClips}>
|
||||||
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
<g clipPath={"url(#clip-path" + randomIdClips + ")"}>
|
<g clipPath={"url(#clip-path" + randomIdClips + ")"}>
|
||||||
<g transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} >
|
<g transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} >
|
||||||
{builtinIcon()}
|
{builtinIcon()}
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {ParamTypes} from "../../constant/ParamTypes";
|
import {ParamTypes} from "../../constant/ParamTypes";
|
||||||
import {getTypeTable, QRPointType} from "../../utils/qrcodeHandler";
|
import {getTypeTable, QRPointType} from "../../utils/qrcodeHandler";
|
||||||
import {createRenderer, defaultDrawIcon} from "../style/Renderer";
|
import {createRenderer} from "../style/Renderer";
|
||||||
import {getExactValue, rand} from "../../utils/util";
|
import {getExactValue, rand} from "../../utils/util";
|
||||||
import LinkTrace from "../link/LinkTrace";
|
import LinkTrace from "../link/LinkTrace";
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ function listPoints({ qrcode, params, icon }) {
|
||||||
const {src, scale} = icon;
|
const {src, scale} = icon;
|
||||||
|
|
||||||
const iconSize = Number(nCount * (scale > .33 ? .33 : scale));
|
const iconSize = Number(nCount * (scale > .33 ? .33 : scale));
|
||||||
const iconXY = (nCount - iconSize) / 2;
|
// const iconXY = (nCount - iconSize) / 2;
|
||||||
|
|
||||||
function nearIcon(x, y) {
|
function nearIcon(x, y) {
|
||||||
return Math.pow((nCount - 1) / 2 - x, 2) + Math.pow((nCount - 1) / 2 - y, 2) < Math.pow(iconSize / 2, 2);
|
return Math.pow((nCount - 1) / 2 - x, 2) + Math.pow((nCount - 1) / 2 - y, 2) < Math.pow(iconSize / 2, 2);
|
||||||
|
@ -67,7 +67,7 @@ function listPoints({ qrcode, params, icon }) {
|
||||||
}
|
}
|
||||||
} else if (posType === 3) {
|
} else if (posType === 3) {
|
||||||
pointList.push(<circle key={id++} fill={posColor} cx={x + 0.5} cy={y + 0.5} r={1.5} />)
|
pointList.push(<circle key={id++} fill={posColor} cx={x + 0.5} cy={y + 0.5} r={1.5} />)
|
||||||
pointList.push(<path key={id++} d={sq25} stroke={posColor} strokeWidth={100/6 * (1 - (1 - size) * 0.75)} fill="none" transform={'translate('+String(x - 2.5)+','+String(y - 2.5)+') ' + 'scale(' + String(6/100) + ',' + String(6/100) + ')'} />)
|
pointList.push(<path key={id++} d={sq25} stroke={posColor} strokeWidth={100/6 * (1 - (1 - size) * 0.75)} fill="none" transform={`translate(${x - 2.5}, ${y - 2.5}) scale(0.06, 0.06)`} />)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (typeTable[x][y] === QRPointType.POS_OTHER) {
|
else if (typeTable[x][y] === QRPointType.POS_OTHER) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ function listPoints({ qrcode, params, icon }) {
|
||||||
}
|
}
|
||||||
} else if (posType === 3) {
|
} else if (posType === 3) {
|
||||||
pointList.push(<circle key={id++} fill={posColor} cx={x + 0.5} cy={y + 0.5} r={1.5} />)
|
pointList.push(<circle key={id++} fill={posColor} cx={x + 0.5} cy={y + 0.5} r={1.5} />)
|
||||||
pointList.push(<path key={id++} d={sq25} stroke={posColor} strokeWidth={100/6 * (1 - (1 - 0.8) * 0.75)} fill="none" transform={'translate('+String(x - 2.5)+','+String(y - 2.5)+') ' + 'scale(' + String(6/100) + ',' + String(6/100) + ')'} />)
|
pointList.push(<path key={id++} d={sq25} stroke={posColor} strokeWidth={100/6 * (1 - (1 - 0.8) * 0.75)} fill="none" transform={`translate(${x - 2.5}, ${y - 2.5}) scale(0.06, 0.06)`} />)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (qrcode.isDark(x, y) && typeTable[x][y] === QRPointType.POS_OTHER) {
|
else if (qrcode.isDark(x, y) && typeTable[x][y] === QRPointType.POS_OTHER) {
|
||||||
|
@ -76,7 +76,7 @@ function listPoints({ qrcode, params, icon }) {
|
||||||
if (funcType === 1) {
|
if (funcType === 1) {
|
||||||
let sizeF = 0
|
let sizeF = 0
|
||||||
let colorF = otherColor
|
let colorF = otherColor
|
||||||
let fillF = colorF
|
// let fillF = colorF
|
||||||
let opacityF = Number(qrcode.isDark(x, y));
|
let opacityF = Number(qrcode.isDark(x, y));
|
||||||
if (dist > 5/20 && dist < 8/20) {
|
if (dist > 5/20 && dist < 8/20) {
|
||||||
sizeF = 5/10
|
sizeF = 5/10
|
||||||
|
|
|
@ -58,7 +58,7 @@ function listPoints({ qrcode, params, icon }) {
|
||||||
}
|
}
|
||||||
} else if (posType === 3) {
|
} else if (posType === 3) {
|
||||||
pointList.push(<circle key={id++} fill={posColor} cx={x + 0.5} cy={y + 0.5} r={1.5} />)
|
pointList.push(<circle key={id++} fill={posColor} cx={x + 0.5} cy={y + 0.5} r={1.5} />)
|
||||||
pointList.push(<path key={id++} d={sq25} stroke={posColor} strokeWidth={100/6 * (1 - (1 - size) * 0.75)} fill="none" transform={'translate('+String(x - 2.5)+','+String(y - 2.5)+') ' + 'scale(' + String(6/100) + ',' + String(6/100) + ')'} />)
|
pointList.push(<path key={id++} d={sq25} stroke={posColor} strokeWidth={100/6 * (1 - (1 - size) * 0.75)} fill="none" transform={`translate(${x - 2.5}, ${y - 2.5}) scale(0.06, 0.06)`}/>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (typeTable[x][y] === QRPointType.POS_OTHER) {
|
else if (typeTable[x][y] === QRPointType.POS_OTHER) {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {getExactValue, getIdNum} from "../../utils/util";
|
||||||
|
|
||||||
function listPoints({ qrcode, params, icon }) {
|
function listPoints({ qrcode, params, icon }) {
|
||||||
if (!qrcode) return []
|
if (!qrcode) return []
|
||||||
console.log(icon)
|
|
||||||
const nCount = qrcode.getModuleCount();
|
const nCount = qrcode.getModuleCount();
|
||||||
const typeTable = getTypeTable(qrcode);
|
const typeTable = getTypeTable(qrcode);
|
||||||
const pointList = new Array(nCount);
|
const pointList = new Array(nCount);
|
||||||
|
@ -175,11 +174,13 @@ let defaultDrawIcon = function ({ qrcode, params, title, icon }) {
|
||||||
if (icon && iconEnabled) {
|
if (icon && iconEnabled) {
|
||||||
const randomIdDefs = getIdNum();
|
const randomIdDefs = getIdNum();
|
||||||
const randomIdClips = getIdNum();
|
const randomIdClips = getIdNum();
|
||||||
pointList.push(<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 3} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} />);
|
|
||||||
|
pointList.push(<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 3} fill="#FFF" transform={`translate(${iconXY},${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />);
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g key={id++}>
|
<g key={id++}>
|
||||||
<defs>
|
<defs>
|
||||||
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} /> </defs>
|
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={`translate(${iconXY},${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />
|
||||||
|
</defs>
|
||||||
<clipPath id={"clip-path" + randomIdClips}>
|
<clipPath id={"clip-path" + randomIdClips}>
|
||||||
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
|
@ -255,16 +256,16 @@ let builtinDrawIcon = function ({ qrcode, params, title, icon }) {
|
||||||
if (icon && iconMode) {
|
if (icon && iconMode) {
|
||||||
const randomIdDefs = getIdNum();
|
const randomIdDefs = getIdNum();
|
||||||
const randomIdClips = getIdNum();
|
const randomIdClips = getIdNum();
|
||||||
pointList.push(<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 3} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} />);
|
pointList.push(<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 3} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />);
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g key={id++}>
|
<g key={id++}>
|
||||||
<defs>
|
<defs>
|
||||||
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} /> </defs>
|
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={`translate(${iconXY},${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} /></defs>
|
||||||
<clipPath id={"clip-path" + randomIdClips}>
|
<clipPath id={"clip-path" + randomIdClips}>
|
||||||
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
<g clipPath={"url(#clip-path" + randomIdClips + ")"}>
|
<g clipPath={"url(#clip-path" + randomIdClips + ")"}>
|
||||||
<g transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} >
|
<g transform={`translate(${iconXY},${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} >
|
||||||
{builtinIcon()}
|
{builtinIcon()}
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|
|
@ -35,11 +35,13 @@ let defaultDrawIcon = function ({ qrcode, params, title, icon }) {
|
||||||
if (icon && iconEnabled) {
|
if (icon && iconEnabled) {
|
||||||
const randomIdDefs = getIdNum();
|
const randomIdDefs = getIdNum();
|
||||||
const randomIdClips = getIdNum();
|
const randomIdClips = getIdNum();
|
||||||
pointList.push(<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} />);
|
|
||||||
|
pointList.push(<path key={id++} d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />);
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g key={id++}>
|
<g key={id++}>
|
||||||
<defs>
|
<defs>
|
||||||
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} /> </defs>
|
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />
|
||||||
|
</defs>
|
||||||
<clipPath id={"clip-path" + randomIdClips}>
|
<clipPath id={"clip-path" + randomIdClips}>
|
||||||
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
|
@ -115,16 +117,17 @@ let builtinDrawIcon = function ({ qrcode, params, title, icon }) {
|
||||||
if (icon && iconMode) {
|
if (icon && iconMode) {
|
||||||
const randomIdDefs = getIdNum();
|
const randomIdDefs = getIdNum();
|
||||||
const randomIdClips = getIdNum();
|
const randomIdClips = getIdNum();
|
||||||
pointList.push(<path d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} />);
|
pointList.push(<path key={id++} d={sq25} stroke="#FFF" strokeWidth={100/iconSize * 1} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />);
|
||||||
pointList.push(
|
pointList.push(
|
||||||
<g key={id++}>
|
<g key={id++}>
|
||||||
<defs>
|
<defs>
|
||||||
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} /> </defs>
|
<path id={"defs-path" + randomIdDefs} d={sq25} fill="#FFF" transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} />
|
||||||
|
</defs>
|
||||||
<clipPath id={"clip-path" + randomIdClips}>
|
<clipPath id={"clip-path" + randomIdClips}>
|
||||||
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
<use xlinkHref={"#defs-path" + randomIdDefs} overflow="visible"/>
|
||||||
</clipPath>
|
</clipPath>
|
||||||
<g clipPath={"url(#clip-path" + randomIdClips + ")"}>
|
<g clipPath={"url(#clip-path" + randomIdClips + ")"}>
|
||||||
<g transform={'translate('+String(iconXY)+','+String(iconXY)+') ' + 'scale(' + String(iconSize/100) + ',' + String(iconSize/100) + ')'} >
|
<g transform={`translate(${iconXY}, ${iconXY}) scale(${iconSize / 100}, ${iconSize / 100})`} >
|
||||||
{builtinIcon()}
|
{builtinIcon()}
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
function FileImport(props) {
|
||||||
|
return (
|
||||||
|
<svg width={30} d="1633445633242" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<style type="text/css"/>
|
||||||
|
</defs>
|
||||||
|
<path
|
||||||
|
d="M182 841h-46C61.442 841 1 780.558 1 706V136C1 61.442 61.442 1 136 1h570c74.558 0 135 60.442 135 135v48h46c74.558 0 135 60.442 135 135v570c0 74.558-60.442 135-135 135H317c-74.558 0-135-60.442-135-135v-48z m569-657v-48c0-24.853-20.147-45-45-45H136c-24.853 0-45 20.147-45 45v570c0 24.853 20.147 45 45 45h46V319c0-74.558 60.442-135 135-135h434z m-434 90c-24.853 0-45 20.147-45 45v570c0 24.853 20.147 45 45 45h570c24.853 0 45-20.147 45-45V319c0-24.853-20.147-45-45-45H317z m239.71 278.5V402.79c0-24.854 20.148-45 45-45 24.854 0 45 20.146 45 45V552.5h149.712c24.852 0 45 20.147 45 45s-20.148 45-45 45H646.71v149.71c0 24.854-20.147 45-45 45s-45-20.146-45-45V642.5H407c-24.853 0-45-20.147-45-45s20.147-45 45-45h149.71z"/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FileImport;
|
|
@ -4,6 +4,7 @@ import React, {useRef} from "react";
|
||||||
import {isPicture} from "../../utils/imageUtils";
|
import {isPicture} from "../../utils/imageUtils";
|
||||||
import {decodeData} from "../../utils/qrcodeHandler";
|
import {decodeData} from "../../utils/qrcodeHandler";
|
||||||
import { handleUpload, handleInputUrl } from "../../utils/gaHelper";
|
import { handleUpload, handleInputUrl } from "../../utils/gaHelper";
|
||||||
|
import FileImport from "../../components/svg/FileImport";
|
||||||
|
|
||||||
const InputText = ({dispatch}) => {
|
const InputText = ({dispatch}) => {
|
||||||
const textRef = useRef();
|
const textRef = useRef();
|
||||||
|
@ -41,7 +42,6 @@ const InputText = ({dispatch}) => {
|
||||||
decodeData(file).then((res) => {
|
decodeData(file).then((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
textRef.current.value = res.data;
|
textRef.current.value = res.data;
|
||||||
console.log(res.data)
|
|
||||||
dispatch(genQRInfo(res.data))
|
dispatch(genQRInfo(res.data))
|
||||||
}
|
}
|
||||||
}).catch(console.err);
|
}).catch(console.err);
|
||||||
|
@ -65,9 +65,39 @@ const InputText = ({dispatch}) => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<label htmlFor="text_import" className="Qr-upload">
|
||||||
|
<FileImport />
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id="text_import"
|
||||||
|
hidden={true}
|
||||||
|
accept={".txt"}
|
||||||
|
onClick={(e) => e.target.value = null}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (e.target.files.length > 0) {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
if (file.type === "text/plain") {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
fileReader.onload = function(event) {
|
||||||
|
const lines = event.target.result
|
||||||
|
.split(/[\r\n]+/g)
|
||||||
|
.map(line => line.trim())
|
||||||
|
.filter(line => line.length > 0);
|
||||||
|
console.log(lines)
|
||||||
|
if (lines.length > 0) {
|
||||||
|
textRef.current.value = lines[0];
|
||||||
|
dispatch(genQRInfo(lines))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileReader.readAsText(file, "UTF-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="Qr-input-hint">
|
<div className="Qr-input-hint">
|
||||||
上传普通二维码或输入网址
|
上传普通二维码、输入网址或上传 txt 文本批量生成
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>);
|
</React.Fragment>);
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PartDownload from "../../components/app/PartDownload";
|
import PartDownload from "../../components/app/PartDownload";
|
||||||
import {saveImg, saveSvg} from "../../utils/downloader";
|
import {saveImg, saveSvg, startTask} from "../../utils/downloader";
|
||||||
import {getDownloadCount, increaseDownloadData, recordDownloadDetail} from "../../api/TcbHandler";
|
import {getDownloadCount, increaseDownloadData, recordDownloadDetail} from "../../api/TcbHandler";
|
||||||
import {getParamDetailedValue, outerHtml} from "../../utils/util";
|
import {fillEmptyWith, getParamDetailedValue, outerHtml} from "../../utils/util";
|
||||||
import {handleDownloadImg, handleDownloadSvg} from "../../utils/gaHelper";
|
import {handleDownloadImg, handleDownloadSvg} from "../../utils/gaHelper";
|
||||||
|
import {appendPreset} from "../../utils/storageUtils";
|
||||||
|
import {svgToBase64} from "../../utils/imageUtils";
|
||||||
|
import React from "react";
|
||||||
|
import ReactDOMServer from "react-dom/server";
|
||||||
|
import JSZip from "jszip";
|
||||||
|
import {encodeData} from "../../utils/qrcodeHandler";
|
||||||
|
|
||||||
function saveDB(state, type, updateDownloadData) {
|
function saveDB(state, type, updateDownloadData) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
@ -40,20 +46,86 @@ function saveDB(state, type, updateDownloadData) {
|
||||||
const mapStateToProps = (state, ownProps) => ({
|
const mapStateToProps = (state, ownProps) => ({
|
||||||
value: state.value,
|
value: state.value,
|
||||||
downloadCount: state.downloadData[state.value],
|
downloadCount: state.downloadData[state.value],
|
||||||
onSvgDownload: () => {
|
batchMode: state.textUrlArray.length > 0,
|
||||||
saveSvg(state.value, outerHtml(state.selectedIndex));
|
onSvgDownload: async () => {
|
||||||
saveDB(state, 'svg', ownProps.updateDownloadData);
|
let data;
|
||||||
|
if (state.textUrlArray.length === 0) {
|
||||||
|
data = saveSvg(state.value, outerHtml(state.selectedIndex));
|
||||||
|
const filename = "QRcode_" + state.value + ".svg";
|
||||||
|
startTask(URL.createObjectURL(data), filename);
|
||||||
|
} else {
|
||||||
|
const zip = new JSZip();
|
||||||
|
for (let i = 0; i < state.textUrlArray.length; i++) {
|
||||||
|
const qrcode = encodeData({ text: state.textUrlArray[i], correctLevel: state.correctLevel });
|
||||||
|
const el = React.createElement(state.rendererType, {
|
||||||
|
qrcode: qrcode,
|
||||||
|
params: fillEmptyWith(state.paramValue[state.selectedIndex].slice(), 0),
|
||||||
|
title: state.title,
|
||||||
|
icon: state.icon,
|
||||||
|
setParamInfo: () => {}
|
||||||
|
});
|
||||||
|
data = saveSvg(state.value, ReactDOMServer.renderToString(el));
|
||||||
|
console.log(data)
|
||||||
|
const filename = "QRcode_" + state.value + "_" + i + ".svg";
|
||||||
|
zip.file(filename, data);
|
||||||
|
}
|
||||||
|
const href = URL.createObjectURL(await zip.generateAsync({ type: "blob" }));
|
||||||
|
startTask(href, "QRcode_" + state.value + ".zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
await saveDB(state, 'svg', ownProps.updateDownloadData);
|
||||||
handleDownloadSvg(state.value);
|
handleDownloadSvg(state.value);
|
||||||
|
return data;
|
||||||
},
|
},
|
||||||
onImgDownload: (type) => {
|
onImgDownload: async (type) => {
|
||||||
return new Promise(resolve => {
|
let data;
|
||||||
saveImg(state.value, outerHtml(state.selectedIndex), 1500, 1500, type).then((res) => {
|
if (state.textUrlArray.length === 0) {
|
||||||
saveDB(state, type, ownProps.updateDownloadData).then(() => {
|
data = await saveImg(state.value, outerHtml(state.selectedIndex), 1500, 1500, type);
|
||||||
|
const filename = "QRcode_" + state.value + "." + type;
|
||||||
|
startTask(data, filename);
|
||||||
|
} else {
|
||||||
|
const zip = new JSZip();
|
||||||
|
for (let i = 0; i < state.textUrlArray.length; i++) {
|
||||||
|
const qrcode = encodeData({ text: state.textUrlArray[i], correctLevel: state.correctLevel });
|
||||||
|
const el = React.createElement(state.rendererType, {
|
||||||
|
qrcode: qrcode,
|
||||||
|
params: fillEmptyWith(state.paramValue[state.selectedIndex].slice(), 0),
|
||||||
|
title: state.title,
|
||||||
|
icon: state.icon,
|
||||||
|
setParamInfo: () => {}
|
||||||
|
});
|
||||||
|
data = await saveImg(state.value, ReactDOMServer.renderToString(el), 1500, 1500, type);
|
||||||
|
const startIdx = data.indexOf("base64,") + "base64,".length;
|
||||||
|
const filename = "QRcode_" + state.value + "_" + i + "." + type;
|
||||||
|
zip.file(filename, data.substring(startIdx), {base64: true});
|
||||||
|
}
|
||||||
|
const href = URL.createObjectURL(await zip.generateAsync({ type: "blob" }));
|
||||||
|
startTask(href, "QRcode_" + state.value + ".zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
await saveDB(state, type, ownProps.updateDownloadData)
|
||||||
handleDownloadImg(state.value, type);
|
handleDownloadImg(state.value, type);
|
||||||
resolve(res)
|
return data;
|
||||||
});
|
},
|
||||||
});
|
savePreset: () => {
|
||||||
});
|
let preset = {
|
||||||
|
name: '测试预设',
|
||||||
|
selectedIndex: state.selectedIndex,
|
||||||
|
preview: svgToBase64(outerHtml(state.selectedIndex), 1500, 1500),
|
||||||
|
styleName: state.value,
|
||||||
|
params: state.paramInfo[state.selectedIndex].map((paramInfo, index) => {
|
||||||
|
return {
|
||||||
|
name: paramInfo.key,
|
||||||
|
value: state.paramValue[state.selectedIndex][index],
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
globalParams: new Array(3),
|
||||||
|
};
|
||||||
|
preset.globalParams[0] = {name: '容错率', value: state.correctLevel};
|
||||||
|
preset.globalParams[1] = {name: '图标', value: state.icon};
|
||||||
|
preset.globalParams[2] = {name: '文字', value: state.title};
|
||||||
|
appendPreset(preset);
|
||||||
|
alert('saved');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import PresetModal from "../../components/preset/PresetModal";
|
||||||
|
import {getPresets} from "../../utils/storageUtils";
|
||||||
|
import {changeCorrectLevel, changeIcon, changeParam, changeStyle, changeTitle} from "../../actions";
|
||||||
|
|
||||||
|
const mapStateToProps = (state, ownProps) => ({
|
||||||
|
visible: ownProps.visible,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||||
|
onClose: ownProps.onClose,
|
||||||
|
loadPreset: (preset) => {
|
||||||
|
dispatch(changeStyle(preset.selectedIndex, preset.styleName));
|
||||||
|
dispatch(changeCorrectLevel(preset.globalParams[0].value));
|
||||||
|
dispatch(changeIcon(preset.globalParams[1].value));
|
||||||
|
dispatch(changeTitle(preset.globalParams[2].value));
|
||||||
|
preset.params.forEach((param, index) => dispatch(changeParam(preset.selectedIndex, index, param.value)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(PresetModal);
|
|
@ -52,7 +52,7 @@ const mapStateToProps = state => ({
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
onSelected: rendererIndex => {
|
onSelected: rendererIndex => {
|
||||||
dispatch(changeStyle(rendererIndex, styles[rendererIndex].renderer, styles[rendererIndex].value))
|
dispatch(changeStyle(rendererIndex, styles[rendererIndex].value))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ const initialState = {
|
||||||
rendererType: RendererRect,
|
rendererType: RendererRect,
|
||||||
correctLevel: 0,
|
correctLevel: 0,
|
||||||
textUrl: QRBTF_URL,
|
textUrl: QRBTF_URL,
|
||||||
|
textUrlArray: [],
|
||||||
history: [],
|
history: [],
|
||||||
downloadData: [],
|
downloadData: [],
|
||||||
qrcode: encodeData({text: QRBTF_URL, correctLevel: 0}),
|
qrcode: encodeData({text: QRBTF_URL, correctLevel: 0}),
|
||||||
|
@ -26,7 +27,8 @@ export default function appReducer(state = initialState, action) {
|
||||||
if (!text || text.length === 0) text = QRBTF_URL;
|
if (!text || text.length === 0) text = QRBTF_URL;
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
textUrl: text,
|
textUrl: text,
|
||||||
qrcode: encodeData({text: text, correctLevel: state.correctLevel})
|
qrcode: encodeData({text: text, correctLevel: state.correctLevel}),
|
||||||
|
textUrlArray: action.textArray || []
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
case actionTypes.CHANGE_STYLE: {
|
case actionTypes.CHANGE_STYLE: {
|
||||||
|
|
|
@ -3,23 +3,25 @@ const svgHead = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n " +
|
||||||
|
|
||||||
const MIME = { "jpg": "image/jpeg", "png": "image/png" };
|
const MIME = { "jpg": "image/jpeg", "png": "image/png" };
|
||||||
|
|
||||||
|
export function startTask(data, filename) {
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.setAttribute('href', data)
|
||||||
|
a.setAttribute('target', 'download')
|
||||||
|
a.setAttribute('download', filename);
|
||||||
|
a.setAttribute('hidden', true);
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
|
||||||
export function saveSvg(value, content) {
|
export function saveSvg(value, content) {
|
||||||
let htmlContent = [svgHead + content]
|
let htmlContent = [svgHead + content]
|
||||||
let bl = new Blob(htmlContent, {type: "image/svg+xml"})
|
let bl = new Blob(htmlContent, {type: "image/svg+xml"})
|
||||||
let a = document.createElement("a")
|
return bl;
|
||||||
let filename = "QRcode_" + value + ".svg"
|
|
||||||
|
|
||||||
a.href = URL.createObjectURL(bl)
|
|
||||||
a.download = filename
|
|
||||||
a.hidden = true
|
|
||||||
a.click()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveImg(value, content, width, height, type) {
|
export function saveImg(value, content, width, height, type) {
|
||||||
if (!MIME[type]) throw "Error image type";
|
if (!MIME[type]) throw "Error image type";
|
||||||
|
|
||||||
// Finish creating downloadable data
|
// Finish creating downloadable data
|
||||||
let filename = "QRcode_" + value + "." + type;
|
|
||||||
const wrap = document.createElement('div');
|
const wrap = document.createElement('div');
|
||||||
wrap.innerHTML = content;
|
wrap.innerHTML = content;
|
||||||
|
|
||||||
|
@ -51,12 +53,8 @@ export function saveImg(value, content, width, height, type) {
|
||||||
// Will result in a download popup for chrome and the
|
// Will result in a download popup for chrome and the
|
||||||
// image opening in a new tab for others.
|
// image opening in a new tab for others.
|
||||||
|
|
||||||
let a = document.createElement('a');
|
|
||||||
let data = canvas.toDataURL(MIME[type], 0.8);
|
let data = canvas.toDataURL(MIME[type], 0.8);
|
||||||
a.setAttribute('href', data)
|
// startTask(data, filename);
|
||||||
a.setAttribute('target', 'download')
|
|
||||||
a.setAttribute('download', filename);
|
|
||||||
a.click();
|
|
||||||
|
|
||||||
resolve(data)
|
resolve(data)
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,20 @@ export function isPicture(file) {
|
||||||
return fileTypes.includes(file.type);
|
return fileTypes.includes(file.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function svgToBase64(content, width, height) {
|
||||||
|
const wrap = document.createElement('div');
|
||||||
|
wrap.innerHTML = content;
|
||||||
|
|
||||||
|
const $svg = wrap.firstChild
|
||||||
|
const $clone = $svg.cloneNode(true);
|
||||||
|
|
||||||
|
$clone.setAttribute('width', width);
|
||||||
|
$clone.setAttribute('height', height);
|
||||||
|
|
||||||
|
const svgData = new XMLSerializer().serializeToString($clone);
|
||||||
|
return 'data:image/svg+xml;base64,' + btoa(svgData);
|
||||||
|
}
|
||||||
|
|
||||||
export function toBase64(file, aspectRatio) {
|
export function toBase64(file, aspectRatio) {
|
||||||
let canvas = document.createElement('canvas');
|
let canvas = document.createElement('canvas');
|
||||||
let ctx = canvas.getContext('2d');
|
let ctx = canvas.getContext('2d');
|
||||||
|
@ -25,7 +39,6 @@ export function toBase64(file, aspectRatio) {
|
||||||
height = img.height;
|
height = img.height;
|
||||||
width = height * aspectRatio;
|
width = height * aspectRatio;
|
||||||
}
|
}
|
||||||
console.log(width + ' ' + height)
|
|
||||||
canvas.setAttribute('width', width);
|
canvas.setAttribute('width', width);
|
||||||
canvas.setAttribute('height', height);
|
canvas.setAttribute('height', height);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
const STORAGE_KEYS = {
|
||||||
|
PRESETS: 'presets'
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getPresets() {
|
||||||
|
let presetArray = [];
|
||||||
|
const presetsValue = localStorage.getItem(STORAGE_KEYS.PRESETS);
|
||||||
|
if (presetsValue) {
|
||||||
|
presetArray = JSON.parse(presetsValue);
|
||||||
|
}
|
||||||
|
return presetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function appendPreset(preset) {
|
||||||
|
const presets = getPresets();
|
||||||
|
presets.push(preset);
|
||||||
|
localStorage.setItem(STORAGE_KEYS.PRESETS, JSON.stringify(presets));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removePreset(index) {
|
||||||
|
const presets = getPresets();
|
||||||
|
presets.splice(index, 1);
|
||||||
|
localStorage.setItem(STORAGE_KEYS.PRESETS, JSON.stringify(presets));
|
||||||
|
}
|
56
yarn.lock
56
yarn.lock
|
@ -4311,6 +4311,11 @@ execa@^1.0.0:
|
||||||
signal-exit "^3.0.0"
|
signal-exit "^3.0.0"
|
||||||
strip-eof "^1.0.0"
|
strip-eof "^1.0.0"
|
||||||
|
|
||||||
|
exenv@^1.2.0:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.npm.taobao.org/exenv/download/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||||
|
integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=
|
||||||
|
|
||||||
exit@^0.1.2:
|
exit@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.npm.taobao.org/exit/download/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
resolved "https://registry.npm.taobao.org/exit/download/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
|
||||||
|
@ -5274,6 +5279,11 @@ ignore@^4.0.6:
|
||||||
resolved "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz?cache=0&sync_timestamp=1565775199290&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fignore%2Fdownload%2Fignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
resolved "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz?cache=0&sync_timestamp=1565775199290&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fignore%2Fdownload%2Fignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||||
integrity sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=
|
integrity sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=
|
||||||
|
|
||||||
|
immediate@~3.0.5:
|
||||||
|
version "3.0.6"
|
||||||
|
resolved "https://registry.nlark.com/immediate/download/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
|
||||||
|
integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
|
||||||
|
|
||||||
immer@1.10.0:
|
immer@1.10.0:
|
||||||
version "1.10.0"
|
version "1.10.0"
|
||||||
resolved "https://registry.npm.taobao.org/immer/download/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d"
|
resolved "https://registry.npm.taobao.org/immer/download/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d"
|
||||||
|
@ -6392,6 +6402,16 @@ jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3:
|
||||||
array-includes "^3.0.3"
|
array-includes "^3.0.3"
|
||||||
object.assign "^4.1.0"
|
object.assign "^4.1.0"
|
||||||
|
|
||||||
|
jszip@^3.7.1:
|
||||||
|
version "3.7.1"
|
||||||
|
resolved "https://registry.nlark.com/jszip/download/jszip-3.7.1.tgz#bd63401221c15625a1228c556ca8a68da6fda3d9"
|
||||||
|
integrity sha1-vWNAEiHBViWhIoxVbKimjab9o9k=
|
||||||
|
dependencies:
|
||||||
|
lie "~3.3.0"
|
||||||
|
pako "~1.0.2"
|
||||||
|
readable-stream "~2.3.6"
|
||||||
|
set-immediate-shim "~1.0.1"
|
||||||
|
|
||||||
killable@^1.0.1:
|
killable@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.npm.taobao.org/killable/download/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
resolved "https://registry.npm.taobao.org/killable/download/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
||||||
|
@ -6483,6 +6503,13 @@ levn@^0.3.0, levn@~0.3.0:
|
||||||
prelude-ls "~1.1.2"
|
prelude-ls "~1.1.2"
|
||||||
type-check "~0.3.2"
|
type-check "~0.3.2"
|
||||||
|
|
||||||
|
lie@~3.3.0:
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.nlark.com/lie/download/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
|
||||||
|
integrity sha1-3Pgt7lRfRgdNryAMfBxaCOD0D2o=
|
||||||
|
dependencies:
|
||||||
|
immediate "~3.0.5"
|
||||||
|
|
||||||
lines-and-columns@^1.1.6:
|
lines-and-columns@^1.1.6:
|
||||||
version "1.1.6"
|
version "1.1.6"
|
||||||
resolved "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
resolved "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||||
|
@ -7478,7 +7505,7 @@ p-try@^2.0.0:
|
||||||
resolved "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
resolved "https://registry.npm.taobao.org/p-try/download/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||||
integrity sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=
|
integrity sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=
|
||||||
|
|
||||||
pako@~1.0.5:
|
pako@~1.0.2, pako@~1.0.5:
|
||||||
version "1.0.11"
|
version "1.0.11"
|
||||||
resolved "https://registry.npm.taobao.org/pako/download/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
|
resolved "https://registry.npm.taobao.org/pako/download/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
|
||||||
integrity sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=
|
integrity sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=
|
||||||
|
@ -8774,6 +8801,21 @@ react-lazy-load@^3.0.13:
|
||||||
lodash.throttle "^4.0.0"
|
lodash.throttle "^4.0.0"
|
||||||
prop-types "^15.5.8"
|
prop-types "^15.5.8"
|
||||||
|
|
||||||
|
react-lifecycles-compat@^3.0.0:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.npm.taobao.org/react-lifecycles-compat/download/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||||
|
integrity sha1-TxonOv38jzSIqMUWv9p4+HI1I2I=
|
||||||
|
|
||||||
|
react-modal@^3.12.1:
|
||||||
|
version "3.12.1"
|
||||||
|
resolved "https://registry.npm.taobao.org/react-modal/download/react-modal-3.12.1.tgz?cache=0&sync_timestamp=1606096428365&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-modal%2Fdownload%2Freact-modal-3.12.1.tgz#38c33f70d81c33d02ff1ed115530443a3dc2afd3"
|
||||||
|
integrity sha1-OMM/cNgcM9Av8e0RVTBEOj3Cr9M=
|
||||||
|
dependencies:
|
||||||
|
exenv "^1.2.0"
|
||||||
|
prop-types "^15.5.10"
|
||||||
|
react-lifecycles-compat "^3.0.0"
|
||||||
|
warning "^4.0.3"
|
||||||
|
|
||||||
react-redux@^7.2.0:
|
react-redux@^7.2.0:
|
||||||
version "7.2.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.npm.taobao.org/react-redux/download/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d"
|
resolved "https://registry.npm.taobao.org/react-redux/download/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d"
|
||||||
|
@ -9483,6 +9525,11 @@ set-blocking@^2.0.0:
|
||||||
resolved "https://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
resolved "https://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||||
|
|
||||||
|
set-immediate-shim@~1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.nlark.com/set-immediate-shim/download/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
|
||||||
|
integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=
|
||||||
|
|
||||||
set-value@^2.0.0, set-value@^2.0.1:
|
set-value@^2.0.0, set-value@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.npm.taobao.org/set-value/download/set-value-2.0.1.tgz?cache=0&sync_timestamp=1585775409029&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fset-value%2Fdownload%2Fset-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
|
resolved "https://registry.npm.taobao.org/set-value/download/set-value-2.0.1.tgz?cache=0&sync_timestamp=1585775409029&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fset-value%2Fdownload%2Fset-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
|
||||||
|
@ -10642,6 +10689,13 @@ walker@^1.0.7, walker@~1.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
makeerror "1.0.x"
|
makeerror "1.0.x"
|
||||||
|
|
||||||
|
warning@^4.0.3:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
|
||||||
|
integrity sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.0.0"
|
||||||
|
|
||||||
watchpack-chokidar2@^2.0.0:
|
watchpack-chokidar2@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npm.taobao.org/watchpack-chokidar2/download/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
|
resolved "https://registry.npm.taobao.org/watchpack-chokidar2/download/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
|
||||||
|
|
Loading…
Reference in New Issue