add qrcode

master
Aaron Yu 2021-12-25 01:17:45 +08:00
parent ae94e98ecf
commit f8ddb87499
7 changed files with 237 additions and 34 deletions

159
package-lock.json generated
View File

@ -4386,6 +4386,11 @@
"ms": "2.1.2" "ms": "2.1.2"
} }
}, },
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"decimal.js": { "decimal.js": {
"version": "10.3.1", "version": "10.3.1",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
@ -4534,6 +4539,11 @@
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz",
"integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==" "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww=="
}, },
"dijkstrajs": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.2.tgz",
"integrity": "sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg=="
},
"dir-glob": { "dir-glob": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@ -4723,6 +4733,11 @@
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
}, },
"encode-utf8": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
},
"encodeurl": { "encodeurl": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -8733,6 +8748,11 @@
} }
} }
}, },
"pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="
},
"portfinder": { "portfinder": {
"version": "1.0.28", "version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
@ -9506,6 +9526,130 @@
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
}, },
"qrcode": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.0.tgz",
"integrity": "sha512-9MgRpgVc+/+47dFvQeD6U2s0Z92EsKzcHogtum4QB+UNd025WOJSHvn/hjk9xmzj7Stj95CyUAs31mrjxliEsQ==",
"requires": {
"dijkstrajs": "^1.0.1",
"encode-utf8": "^1.0.3",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"requires": {
"p-locate": "^4.1.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"requires": {
"p-limit": "^2.2.0"
}
},
"wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"requires": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
"qs": { "qs": {
"version": "6.9.6", "version": "6.9.6",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
@ -9956,6 +10100,11 @@
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
}, },
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"requires-port": { "requires-port": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@ -10294,6 +10443,11 @@
"send": "0.17.2" "send": "0.17.2"
} }
}, },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"setprototypeof": { "setprototypeof": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@ -11474,6 +11628,11 @@
"is-symbol": "^1.0.3" "is-symbol": "^1.0.3"
} }
}, },
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"word-wrap": { "word-wrap": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",

View File

@ -11,6 +11,7 @@
"@testing-library/react": "^12.1.2", "@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"axios": "^0.24.0", "axios": "^0.24.0",
"qrcode": "^1.5.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-scripts": "5.0.0", "react-scripts": "5.0.0",

View File

@ -4,7 +4,10 @@ import DeviceFrame from './Components/deviceFrame';
import waterMarkPng from './images/water-mark.png' import waterMarkPng from './images/water-mark.png'
import React from 'react'; import React from 'react';
import SettingFrame from './Components/settingsFrame'; import SettingFrame from './Components/settingsFrame';
import QrCode from 'qrcode'
import toSJIS from 'qrcode/helper/to-sjis'
var baseUrl = "http://123.56.161.61:1157/"
class App extends React.Component { class App extends React.Component {
constructor() { constructor() {
super(); super();
@ -13,11 +16,25 @@ class App extends React.Component {
projects: [], projects: [],
selectedProject: {}, selectedProject: {},
device: 'android-h', device: 'android-h',
htmlUrl: '' htmlUrl: '',
dataUrl: '',
loading: false
} }
} }
componentDidMount() { componentDidMount() {
this.fetchData(); this.fetchData();
this.refreshQrCode()
}
refreshQrCode() {
var {selectedProject} = this.state;
var rawUrl = encodeURI(baseUrl + selectedProject.HtmlUrl)
selectedProject.HtmlUrl && QrCode.toDataURL([{ data: rawUrl, mode: 'byte'}], { width: 120 })
.then((dataUrl) => {
this.setState({
dataUrl: dataUrl
})
})
} }
setSelectedProject(selected) { setSelectedProject(selected) {
@ -39,6 +56,9 @@ class App extends React.Component {
} }
async fetchData() { async fetchData() {
this.setState({
loading: true
})
var response = await fetch('http://123.56.161.61:1157/home/GetServerJsonData', { var response = await fetch('http://123.56.161.61:1157/home/GetServerJsonData', {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@ -47,8 +67,10 @@ class App extends React.Component {
var projects = await response.json(); var projects = await response.json();
this.setState({ this.setState({
projects, projects,
selectedProject: projects[0] selectedProject: projects[0],
}) loading: false
});
this.refreshQrCode()
} }
UpdateSetting(obj) { UpdateSetting(obj) {
@ -65,7 +87,7 @@ class App extends React.Component {
} }
render() { render() {
var { mode, device, projects, selectedProject } = this.state; var { mode, device, projects, selectedProject, dataUrl, loading } = this.state;
return ( return (
<div className="App"> <div className="App">
@ -74,6 +96,7 @@ class App extends React.Component {
onModeChange={(_mode) => this.setMode(_mode) } onModeChange={(_mode) => this.setMode(_mode) }
projects={projects} projects={projects}
device={device} device={device}
loading={loading}
onProjectSelect={(project) => { onProjectSelect={(project) => {
this.setSelectedProject(project) this.setSelectedProject(project)
}} }}
@ -91,7 +114,8 @@ class App extends React.Component {
mode === "normal" mode === "normal"
? <DeviceFrame ? <DeviceFrame
htmlUrl={selectedProject.HtmlUrl} htmlUrl={selectedProject.HtmlUrl}
device={device}/> device={device}
qrDataUrl={dataUrl}/>
: <SettingFrame : <SettingFrame
setting={selectedProject.TextObjStr} setting={selectedProject.TextObjStr}
settingValue={selectedProject.OldSlectType ? selectedProject.OldSlectType.split('|').map(v => +v) : [1, 1, 1]} settingValue={selectedProject.OldSlectType ? selectedProject.OldSlectType.split('|').map(v => +v) : [1, 1, 1]}

View File

@ -7,4 +7,17 @@
height: 100vh; height: 100vh;
justify-content: center; justify-content: center;
overflow: hidden; overflow: hidden;
}
.refreshButton {
position: absolute;
left: 30px;
bottom: 30px;
cursor: pointer;
}
.qrCode {
position: absolute;
right: 30px;
top: 30px;
} }

View File

@ -60,31 +60,32 @@ function DeviceFrame(props) {
return ( return (
<div className='deviceFrameContainer'> <div className='deviceFrameContainer'>
<img src={refreshButtonPng} alt='refresh' onClick={() => refresh()} style={{ <img src={refreshButtonPng} alt='refresh' onClick={() => refresh()} className='refreshButton'/>
position: 'absolute', { props.qrDataUrl &&
left: '30px', <div className='qrCode'>
bottom: '30px', <p style={{ margin: '0' }}>扫一扫,手机预览</p>
cursor: 'pointer' <img src={props.qrDataUrl} alt='qr code'/>
}}/> </div>
}
<div> <div>
<img src={config.bkg} alt='background'/> <img src={config.bkg} alt='background'/>
{ {
props.htmlUrl props.htmlUrl
&& <iframe && <iframe
key={iframeKey} key={iframeKey}
id='deviceFrame' id='deviceFrame'
style={{ style={{
position: 'absolute', position: 'absolute',
top: '50%', top: '50%',
left: '50%', left: '50%',
transform: 'translate(-50%, -50%)' transform: 'translate(-50%, -50%)'
}} }}
title='preview' title='preview'
src={baseUrl + props.htmlUrl} src={baseUrl + props.htmlUrl}
width={config.width} width={config.width}
height={config.height} height={config.height}
frameBorder={'0'}/> frameBorder={'0'}/>
} }
</div> </div>
</div> </div>
) )

View File

@ -1,5 +1,5 @@
.Pane { .Pane {
width: 30vw; width: 350px;
background-color: rgb(52, 90, 176); background-color: rgb(52, 90, 176);
min-height: 100vh; min-height: 100vh;
} }

View File

@ -2,7 +2,7 @@ import './index.css';
import Select from '@mui/material/Select'; import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem' import MenuItem from '@mui/material/MenuItem'
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Chip, List, ListItem } from '@mui/material'; import { Chip, CircularProgress, List, ListItem } from '@mui/material';
import ipadPng from '../../images/ipad.png' import ipadPng from '../../images/ipad.png'
import iphonePng from '../../images/iphone.png' import iphonePng from '../../images/iphone.png'
import androidPng from '../../images/android.png' import androidPng from '../../images/android.png'
@ -102,17 +102,22 @@ function Pane(props) {
</ListItem>) </ListItem>)
} }
</List> </List>
<div> <div style={{
marginTop: '50px',
color: 'white'
}}>
{ {
project && props.loading
<Select ?
<CircularProgress color='inherit'/>
:
project && <Select
id="project-select" id="project-select"
value={project} value={project}
onChange={(e) => projectSelect(e)} onChange={(e) => projectSelect(e)}
placeholder='选择项目' placeholder='选择项目'
sx={{ sx={{
background: 'rgb(115, 158, 211)', background: 'rgb(115, 158, 211)',
marginTop: '50px',
width: '80%', width: '80%',
color: 'white' color: 'white'
}} }}