First commit
|
@ -0,0 +1,2 @@
|
|||
> 1%
|
||||
last 2 versions
|
|
@ -0,0 +1,6 @@
|
|||
# just a flag
|
||||
ENV = 'development'
|
||||
|
||||
# base api
|
||||
VUE_APP_BASE_API = '/dev-api'
|
||||
VUE_APP_BASE_PORT = 1024
|
|
@ -0,0 +1,6 @@
|
|||
# just a flag
|
||||
ENV = 'production'
|
||||
|
||||
# base api
|
||||
VUE_APP_BASE_API = '/'
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
|
@ -0,0 +1,29 @@
|
|||
# vue-general
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Run your tests
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
|
@ -0,0 +1,12 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
],
|
||||
plugins: [
|
||||
['import', {
|
||||
libraryName: 'vant',
|
||||
libraryDirectory: 'es',
|
||||
style: true
|
||||
}, 'vant']
|
||||
]
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "vue-general",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nutui/nutui": "^3.1.20",
|
||||
"axios": "0.19.0",
|
||||
"core-js": "^2.6.5",
|
||||
"exif-js": "^2.3.0",
|
||||
"image-conversion": "^1.1.9",
|
||||
"mockjs": "^1.1.0",
|
||||
"normalize.css": "7.0.0",
|
||||
"qrcodejs2": "^0.0.2",
|
||||
"vant": "^2.1.1",
|
||||
"vue": "^2.6.10",
|
||||
"vue-router": "^3.0.3",
|
||||
"weixin-js-sdk": "^1.4.0-test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^3.11.0",
|
||||
"@vue/cli-service": "^3.11.0",
|
||||
"babel-plugin-import": "^1.11.0",
|
||||
"stylus": "^0.54.5",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= webpackConfig.name %></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<keep-alive>
|
||||
<router-view/>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="stylus">
|
||||
#app
|
||||
font-family 'Avenir', Helvetica, Arial, sans-serif
|
||||
-webkit-font-smoothing antialiased
|
||||
-moz-osx-font-smoothing grayscale
|
||||
color #2c3e50
|
||||
min-height 100vh
|
||||
position relative
|
||||
padding 0
|
||||
margin 0
|
||||
a
|
||||
font-weight bold
|
||||
color #2c3e50
|
||||
&.router-link-exact-active
|
||||
color #42b983
|
||||
</style>
|
|
@ -0,0 +1,16 @@
|
|||
import request from 'utils/request'
|
||||
|
||||
|
||||
/**
|
||||
* 通过人脸认证返回的code获取个人二维码字符串
|
||||
* @param {string} code
|
||||
*/
|
||||
export function GetQRCode(code){
|
||||
return request({
|
||||
url:'/api/v1/personverify/qrcode',
|
||||
method:'get',
|
||||
params:{
|
||||
code
|
||||
}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
import request from 'utils/request'
|
||||
|
||||
/**
|
||||
* 传入页面url,获取微信扫一扫调用签名
|
||||
* @param {string} url
|
||||
*/
|
||||
export function GetScanParams(url){
|
||||
return request({
|
||||
url:'/app/v1/wechat/getjsparam',
|
||||
method:'get',
|
||||
params:{
|
||||
url
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过二维码字符串获取运动员个人信息
|
||||
* @param {string} code
|
||||
*/
|
||||
export function GetPeopleData(code){
|
||||
return request({
|
||||
url:'/api/v1/checking/get',
|
||||
method:'get',
|
||||
params:{
|
||||
code
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 传入用户个人codemd5和编号进行绑定
|
||||
* @param {string} CodeMd5
|
||||
* @param {number} No
|
||||
*/
|
||||
export function AddNo(CodeMd5,No){
|
||||
return request({
|
||||
url:'/api/v1/checking/addno',
|
||||
method:'post',
|
||||
data:{
|
||||
CodeMd5,
|
||||
No
|
||||
}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import request from 'utils/request'
|
||||
|
||||
/**
|
||||
* 提交人脸及姓名、身份证号码,进行身份认证
|
||||
* @param {object} data
|
||||
*/
|
||||
export function Login(data){
|
||||
return request({
|
||||
url:'/api/v1/wechat/runnerlogin',
|
||||
method:'post',
|
||||
data:{
|
||||
Name: data.Name,
|
||||
Phone:data.Phone
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function Runnerverify(data){
|
||||
return request({
|
||||
url:'/api/v1/wechat/runnerverify',
|
||||
method:'post',
|
||||
data
|
||||
})
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import request from 'utils/request'
|
||||
|
||||
|
||||
/**
|
||||
* 管理员登陆接口
|
||||
* @param {number} Name
|
||||
* @param {numebr} Password
|
||||
*/
|
||||
export function Login(loginForm){
|
||||
return request({
|
||||
url:'/api/v1/Users/login',
|
||||
method:'post',
|
||||
data:{
|
||||
username:loginForm.username,
|
||||
password:loginForm.password
|
||||
}
|
||||
})
|
||||
|
||||
}
|
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 140 KiB |
After Width: | Height: | Size: 364 KiB |
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 426 KiB |
After Width: | Height: | Size: 442 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 5.6 KiB |
|
@ -0,0 +1,9 @@
|
|||
import busVue from 'vue'
|
||||
|
||||
/**
|
||||
* 在原型上挂载一个新的vue实例对象
|
||||
* 用于储存公共值的同时,借用vue的$emit/$on/$off实现数据监听
|
||||
*/
|
||||
export default function (vue){
|
||||
vue.prototype.$bus = new busVue()
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import LoadingComponent from './loading.vue'
|
||||
const Loading = {};
|
||||
|
||||
// 注册Loading
|
||||
Loading.install = function (Vue) {
|
||||
// 生成一个Vue的子类
|
||||
// 同时这个子类也就是组件
|
||||
const LoadingConstructor = Vue.extend(LoadingComponent);
|
||||
// 生成一个该子类的实例
|
||||
const instance = new LoadingConstructor();
|
||||
// 将这个实例挂载在我创建的div上
|
||||
instance.$mount(document.createElement('div'));
|
||||
// 并将此div加入全局挂载点内部
|
||||
document.body.appendChild(instance.$el);
|
||||
// 通过Vue的原型注册一个方法
|
||||
// 让所有实例共享这个方法
|
||||
|
||||
function handlerloading(text = '', full) {
|
||||
instance.text = text; //文字是以最后一个show的展示
|
||||
instance.full = true; //控制填充满屏,但不开放使用;
|
||||
}
|
||||
const loading_main = {
|
||||
show(text = ''){
|
||||
instance.loadings.push('show') //执行一次添加一个
|
||||
handlerloading(text) //把text填充
|
||||
},
|
||||
hidden(){
|
||||
instance.loadings.pop() //执行一次减少一个,通过数组长度控制显示与否(考虑到同时打开多个loading情况)
|
||||
}
|
||||
}
|
||||
//将方法挂载全局
|
||||
Vue.prototype.$Loading = loading_main;
|
||||
}
|
||||
export default Loading
|
|
@ -0,0 +1,139 @@
|
|||
<template>
|
||||
<div id="vue-loading" v-show="loadings.length">
|
||||
<div class="filter" v-show="full"></div>
|
||||
<div class="loader-wrap">
|
||||
<!-- <div class="loader"></div> -->
|
||||
<div class="logo">
|
||||
<img src="@/assets/image/loding-logo.png" alt="">
|
||||
</div>
|
||||
<div class="hint">{{text}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'Loading',
|
||||
data(){
|
||||
return {
|
||||
loadings:[],
|
||||
text:'',
|
||||
full:false, //是否展示蒙层
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
#vue-loading
|
||||
width 100%
|
||||
height 100%
|
||||
position absolute
|
||||
left 0
|
||||
top 0
|
||||
z-index 999
|
||||
.filter
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(255,255,255,0.3);
|
||||
.loader-wrap
|
||||
position absolute
|
||||
left 50%
|
||||
top 50%
|
||||
transform translate(-50%,-50%)
|
||||
display flex
|
||||
flex-direction column
|
||||
justify-content center
|
||||
.logo
|
||||
// width 100%
|
||||
text-align center
|
||||
img
|
||||
animation scal 0.8s infinite
|
||||
opacity 0.8
|
||||
width 16vw
|
||||
.hint
|
||||
margin-top 10px
|
||||
font-size 14px
|
||||
color #666
|
||||
text-shadow 1px 1px 3px white
|
||||
.loader
|
||||
width 2.5em
|
||||
height 2.5em
|
||||
transform rotate(165deg)
|
||||
position relative
|
||||
&:before
|
||||
animation before 2s infinite
|
||||
&:after
|
||||
animation after 2s infinite
|
||||
&:before,
|
||||
&:after
|
||||
content ''
|
||||
position absolute
|
||||
top 50%
|
||||
left 50%
|
||||
display block
|
||||
width 0.5em
|
||||
height 0.5em
|
||||
border-radius 0.25em
|
||||
transform translate(-50%, -50%)
|
||||
</style>
|
||||
|
||||
<style>
|
||||
@keyframes scal {
|
||||
0%{
|
||||
transform:scale(0.8);
|
||||
}
|
||||
50%{
|
||||
transform:scale(1);
|
||||
}
|
||||
100%{
|
||||
transform:scale(0.8);
|
||||
}
|
||||
}
|
||||
@keyframes before {
|
||||
0% {
|
||||
width: 0.5em;
|
||||
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
|
||||
}
|
||||
35% {
|
||||
width: 2.5em;
|
||||
box-shadow: 0 -0.5em rgba(225, 20, 98, 0.75), 0 0.5em rgba(111, 202, 220, 0.75);
|
||||
}
|
||||
70% {
|
||||
width: 0.5em;
|
||||
box-shadow: -1em -0.5em rgba(225, 20, 98, 0.75), 1em 0.5em rgba(111, 202, 220, 0.75);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
|
||||
}
|
||||
}
|
||||
@keyframes after {
|
||||
0% {
|
||||
height: 0.5em;
|
||||
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
|
||||
}
|
||||
35% {
|
||||
height: 2.5em;
|
||||
box-shadow: 0.5em 0 rgba(61, 184, 143, 0.75), -0.5em 0 rgba(233, 169, 32, 0.75);
|
||||
}
|
||||
70% {
|
||||
height: 0.5em;
|
||||
box-shadow: 0.5em -1em rgba(61, 184, 143, 0.75), -0.5em 1em rgba(233, 169, 32, 0.75);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Attempt to center the whole thing!
|
||||
*/
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
.loader {
|
||||
position: absolute;
|
||||
top: calc(50% - 1.25em);
|
||||
left: calc(50% - 1.25em);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import ToastComponent from './toast.vue'
|
||||
const Toast = {};
|
||||
|
||||
// 注册Toast
|
||||
Toast.install = function (Vue) {
|
||||
// 生成一个Vue的子类
|
||||
// 同时这个子类也就是组件
|
||||
const ToastConstructor = Vue.extend(ToastComponent);
|
||||
// 生成一个该子类的实例
|
||||
const instance = new ToastConstructor();
|
||||
// 将这个实例挂载在我创建的div上
|
||||
instance.$mount(document.createElement('div'));
|
||||
// 并将此div加入全局挂载点内部
|
||||
document.body.appendChild(instance.$el);
|
||||
//定义一个外部的变量,用于控制调用多次提示组件时,清除延时器
|
||||
let timer;
|
||||
// 通过Vue的原型注册一个方法
|
||||
// 让所有实例共享这个方法
|
||||
class message_main {
|
||||
constructor(){}
|
||||
static all_message(msg, type, duration) {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
instance.successMessage = []
|
||||
instance.errorMessage = [];
|
||||
}, duration);
|
||||
if(type == 'success'){
|
||||
instance.successMessage = [msg];
|
||||
instance.errorMessage = [];
|
||||
}else if (type == 'error'){
|
||||
instance.successMessage = [];
|
||||
instance.errorMessage = [msg];
|
||||
}
|
||||
instance.type = type;
|
||||
}
|
||||
success(msg, duration = 2000) { //默认两秒停留时长
|
||||
message_main.all_message({txt:msg,key:new Date().getTime()}, 'success', duration);
|
||||
}
|
||||
error(msg, duration = 2000) {
|
||||
message_main.all_message({txt:msg,key:new Date().getTime()}, 'error', duration);
|
||||
}
|
||||
}
|
||||
//将方法挂载全局
|
||||
Vue.prototype.$Toast = new message_main();
|
||||
}
|
||||
export default Toast
|
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- 全局提示框 -->
|
||||
<transition-group name="fade">
|
||||
<div name='fade' v-for="item in successMessage" :key='item.key' class="dialog-tips">
|
||||
<span>{{item.txt}}</span>
|
||||
</div>
|
||||
</transition-group>
|
||||
|
||||
<transition-group name="fade">
|
||||
<div v-for="item in errorMessage" :key='item.key' class="dialog-tips error">
|
||||
<span>{{item.txt}}</span>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
successMessage: [],
|
||||
errorMessage:[],
|
||||
type:'success',
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
$Height = 35px
|
||||
|
||||
.dialog-tips
|
||||
position absolute
|
||||
z-index 999
|
||||
width 100vw
|
||||
height $Height
|
||||
background-color rgba(123,210,57,0.85)
|
||||
color white
|
||||
border-radius 0 0 3px 3px
|
||||
left 50%
|
||||
top 0
|
||||
transform translate(-50%,0)
|
||||
display flex
|
||||
justify-content center
|
||||
transition all 0.2s
|
||||
align-items center
|
||||
&.error
|
||||
background-color rgba(255,70,0,0.85)
|
||||
span
|
||||
font-size 14px
|
||||
line-height $Height
|
||||
color red
|
||||
// 通知动画
|
||||
.fade-enter-active, .fade-leave-active
|
||||
transform translate(-50%,0%)
|
||||
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */
|
||||
transform translate(-50%,-100%)
|
||||
</style>
|
|
@ -0,0 +1,37 @@
|
|||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import 'normalize.css/normalize.css' // 重置、初始化css样式的库
|
||||
import '@/permission' // 挂载路由后添加路由拦截器(守卫 )
|
||||
|
||||
// import NutUI from "@nutui/nutui";
|
||||
// import "@nutui/nutui/dist/style.css";
|
||||
// Vue.use(NutUI)
|
||||
|
||||
import Loading from 'globalComponents/Loading'
|
||||
import Toast from 'globalComponents/Toast'
|
||||
Vue.use(Toast) //启用全局提示组件
|
||||
Vue.use(Loading) //使用全局loading组件
|
||||
|
||||
/**
|
||||
* 如果需要bus总线模式
|
||||
* this.$bus.$data.xxx = xxx
|
||||
* this.$bus.emit('change',data)
|
||||
* this.$bus.$on('change',data => console.log(data))
|
||||
* this.$bus.$off('change')
|
||||
*/
|
||||
// import bus from './bus'
|
||||
// Vue.use(bus) //使用BUS总线模式,实现组件间任意传值
|
||||
|
||||
Vue.config.productionTip = false //生产模式下关闭vue在控制台的提示
|
||||
|
||||
if (process.env.NODE_ENV == 'development'){
|
||||
require('./mock/index.js');
|
||||
}
|
||||
|
||||
const vm = new Vue({
|
||||
router,
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
|
||||
export default vm
|
|
@ -0,0 +1,11 @@
|
|||
let runnerlogin = {
|
||||
code: 0,
|
||||
data: ['https://blog.skywt.cn/usr/themes/Daydream/assets/img/avatar.png'],
|
||||
msg: '成功'
|
||||
}
|
||||
|
||||
let home = {
|
||||
runnerlogin
|
||||
}
|
||||
|
||||
export default home
|
|
@ -0,0 +1,16 @@
|
|||
import Mock from 'mockjs'
|
||||
|
||||
import login from './login'
|
||||
import home from './home'
|
||||
|
||||
Mock.mock('/api/v1/Users/login', 'post', () => {
|
||||
return login.login_request
|
||||
})
|
||||
|
||||
Mock.mock('/api/v1/wechat/runnerlogin', 'post', () => {
|
||||
return home.runnerlogin
|
||||
})
|
||||
|
||||
Mock.mock('/dev-api/api/v1/wechat/runnerlogin', 'post', () => {
|
||||
return home.runnerlogin
|
||||
})
|
|
@ -0,0 +1,9 @@
|
|||
let login_request = {
|
||||
code: 200
|
||||
}
|
||||
|
||||
let login = {
|
||||
login_request
|
||||
}
|
||||
|
||||
export default login
|
|
@ -0,0 +1,47 @@
|
|||
import router from './router'
|
||||
import getPageTitle from 'utils/getPageTitle'
|
||||
import { Checkrunner } from 'api/home'
|
||||
|
||||
|
||||
import Vue from 'vue';
|
||||
import { Toast } from 'vant';
|
||||
Vue.use(Toast);
|
||||
|
||||
|
||||
|
||||
// 路由拦截
|
||||
// router.beforeEach(async(to, from, next) => {
|
||||
// document.title = getPageTitle(to.meta.title) // set page title
|
||||
// if(to.name ==='Admin'){
|
||||
// if(sessionStorage.loginStatus){
|
||||
// next()
|
||||
// }else{
|
||||
// next('/login')
|
||||
// Toast('请登录!')
|
||||
// }
|
||||
// }else if(to.name === 'Home'){
|
||||
// let skipUrl = 'http://5gmalasong.hnabc.cn/app'
|
||||
// let wechatUrl = 'http://5gmalasong.hnabc.cn'
|
||||
// let routerUrl = escape('/#/home')
|
||||
// Checkrunner().then(res =>{
|
||||
// if(res.code === 0){
|
||||
// sessionStorage.Code = res.data.Code
|
||||
// next('/QRCode')
|
||||
// }else if(res.code === 3009){
|
||||
// location.href = wechatUrl + '/wechat/login/runner?returnurl=' + skipUrl + routerUrl
|
||||
// // alert(baseUrl + 'wechat/login/runner?returnurl=' + baseUrl + '#/home')
|
||||
// }else{
|
||||
// next()
|
||||
// }
|
||||
// })
|
||||
// }else{
|
||||
// next()
|
||||
// }
|
||||
// })
|
||||
|
||||
|
||||
|
||||
//跳转完成后
|
||||
router.afterEach(() => {
|
||||
//to do something
|
||||
})
|
|
@ -0,0 +1,45 @@
|
|||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import Home from './views/home'
|
||||
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect:'/login'
|
||||
},
|
||||
{
|
||||
path:'/login',
|
||||
name:'Login',
|
||||
component:() => import('./views/login'),
|
||||
meta:{ title:'登陆' }
|
||||
},
|
||||
{
|
||||
path:'/home',
|
||||
name:'Home',
|
||||
component:() => import('./views/home'),
|
||||
meta:{ title:'人脸注册' }
|
||||
},
|
||||
{
|
||||
path:'/photos',
|
||||
name:'Photos',
|
||||
component:() => import('./views/photos'),
|
||||
meta:{ title:'' }
|
||||
},
|
||||
// {
|
||||
// path:'/QRCode',
|
||||
// name:'QRCode',
|
||||
// component:() => import('./views/QRCode'),
|
||||
// meta:{ title:'身份二维码' }
|
||||
// },
|
||||
// {
|
||||
// path:'/admin',
|
||||
// name:'Admin',
|
||||
// component:() => import('./views/admin'),
|
||||
// meta:{ title:'物资发放' }
|
||||
// },
|
||||
]
|
||||
})
|
|
@ -0,0 +1,2 @@
|
|||
export const title = '2019长沙国际马拉松纪念照' //标签页title
|
||||
export const globalSuccessToast = true //是否在request中开启全局请求成功的成功提示(基于全局Toast)
|
|
@ -0,0 +1,132 @@
|
|||
$themeColor = rgb(128,51,134);
|
||||
$fontColor = rgb(77,9,86)
|
||||
|
||||
Button()
|
||||
background linear-gradient(135deg,#fa2c19 0%,#fa6419 100%)
|
||||
color white
|
||||
padding 10px
|
||||
width 85%
|
||||
text-align center
|
||||
border-radius 25px
|
||||
border: 1px solid transparent
|
||||
|
||||
hint()
|
||||
width 100%
|
||||
box-sizing border-box
|
||||
position absolute
|
||||
text-indent 2em
|
||||
z-index 9999
|
||||
padding 10px
|
||||
background rgba(255,255,255,0.8)
|
||||
color rgb(0,133,208)
|
||||
font-size 12px
|
||||
line-height 1.4em
|
||||
|
||||
.home-wrap
|
||||
overflow hidden
|
||||
height: 100vh
|
||||
width: 100%
|
||||
.bottom-img
|
||||
position absolute
|
||||
bottom 0px
|
||||
width 100%
|
||||
left 0
|
||||
.hint
|
||||
width 100%
|
||||
box-sizing border-box
|
||||
position absolute
|
||||
text-indent 2em
|
||||
z-index 9999
|
||||
padding 10px
|
||||
background rgba(255,255,255,0.3)
|
||||
backdrop-filter: blur(30)
|
||||
color white
|
||||
font-size 12px
|
||||
line-height 1.4em
|
||||
bottom 0
|
||||
.background-wrap
|
||||
position: fixed
|
||||
z-index: -1
|
||||
// .background-image
|
||||
.top-brand-wrap
|
||||
color: white
|
||||
text-align: center
|
||||
margin-top: 15vh
|
||||
.info-card
|
||||
position relative
|
||||
// z-index 999
|
||||
width 90%
|
||||
box-shadow: 0 4px 10px #00000012
|
||||
-webkit-box-shadow: 0px 4px 10px 0px rgba(0,0,0,.07)
|
||||
background rgba(255, 255, 255, 0.7)
|
||||
backdrop-filter: blur(20px)
|
||||
-webkit-backdrop-filter: blur(20px)
|
||||
margin 0 auto
|
||||
margin-top 10vh
|
||||
z-index 500
|
||||
padding-bottom 30px
|
||||
padding-top 30px
|
||||
.form
|
||||
width 100%
|
||||
padding 30px
|
||||
box-sizing border-box
|
||||
position relative
|
||||
// z-index 999
|
||||
.van-cell
|
||||
height: 48px
|
||||
background: transparent
|
||||
&::after
|
||||
// border-bottom: 2px solid #f5f6f7
|
||||
border-bottom: 2px solid #323233
|
||||
>>>input
|
||||
height 48px
|
||||
// >>>field__body
|
||||
.button
|
||||
background linear-gradient(135deg,#fa2c19 0%,#fa6419 100%)
|
||||
color white
|
||||
padding 10px
|
||||
width 85%
|
||||
text-align center
|
||||
border-radius 25px
|
||||
border: 1px solid transparent
|
||||
margin-bottom: 20px
|
||||
.register
|
||||
background linear-gradient(135deg,rgb(255,158,13) 0%,rgb(255,167,13) 45%,rgb(255,182,13) 83%,rgb(255,190,13) 100%)
|
||||
.flex-container
|
||||
display flex
|
||||
flex-direction column
|
||||
justify-content center
|
||||
align-items center
|
||||
.main
|
||||
width 100vw
|
||||
position relative
|
||||
z-index 800
|
||||
.hint
|
||||
width 70%
|
||||
border-radius 10px
|
||||
height 100px
|
||||
background rgba(255,255,255,0.9)
|
||||
position absolute
|
||||
left 50%
|
||||
top 50%
|
||||
transform translate(-50%,-50%)
|
||||
display flex
|
||||
justify-content center
|
||||
align-items center
|
||||
color rgba(0,133,208,1)
|
||||
.imgs-wrap
|
||||
overflow hidden
|
||||
width 100%
|
||||
padding 8px
|
||||
padding-top 40px
|
||||
padding-bottom 50px
|
||||
box-sizing border-box
|
||||
.imgs-item
|
||||
font-size 0
|
||||
border 1px solid white
|
||||
width 100%
|
||||
margin-bottom 10px
|
||||
border-radius 10px
|
||||
overflow hidden
|
||||
img
|
||||
width 100%
|
|
@ -0,0 +1,55 @@
|
|||
// 微信扫一扫封装,传入callback在扫码执行并接收一个code参数,修改api即可;
|
||||
|
||||
import wx from 'weixin-js-sdk'
|
||||
import { GetScanParams } from 'api/admin'
|
||||
import vm from '@/main.js'
|
||||
|
||||
export default function WeChatScan(callback){
|
||||
GetScanParams(window.location.href.split('#')[0]).then(res => {
|
||||
if(res.code === 0){
|
||||
openScan(res.data,callback)
|
||||
}else{
|
||||
vm.$Toast.error('签名信息获取失败!')
|
||||
}
|
||||
}).catch(err => vm.$Toast.error('签名信息获取失败,请重试!'))
|
||||
}
|
||||
|
||||
function openScan(data,callback){
|
||||
wx.config({
|
||||
debug: false, // 开启调试模式
|
||||
appId: data.appid, // 公众号的唯一标识
|
||||
timestamp: data.Timestamp, // 生成签名的时间戳
|
||||
nonceStr: data.NonceStr, // 生成签名的随机串
|
||||
signature: data.Signature, // 签名
|
||||
jsApiList: [ 'scanQRCode' ] // 需要使用的JS接口列表
|
||||
});
|
||||
|
||||
wx.ready(function () {
|
||||
var isBack = callback
|
||||
wx.checkJsApi({ // 判断当前客户端版本是否支持指定JS接口
|
||||
jsApiList: [ 'scanQRCode' ],
|
||||
success: function (res) { // 以键值对的形式返回,可用true,不可用false。如:{"checkResult":{"scanQRCode":true},"errMsg":"checkJsApi:ok"}
|
||||
if (res.checkResult.scanQRCode === true) {
|
||||
wx.scanQRCode({ // 微信扫一扫接口
|
||||
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
|
||||
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
|
||||
success: function (res) {
|
||||
const getCode = res.resultStr // 当needResult 为 1 时,扫码返回的结果
|
||||
isBack(getCode)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
vm.$Toast.error('抱歉,当前客户端版本不支持扫一扫!')
|
||||
}
|
||||
},
|
||||
fail: function (res) { // 检测getNetworkType该功能失败时处理
|
||||
vm.$Toast.error('失败' + res)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/* 处理失败验证 */
|
||||
wx.error(function (res) {
|
||||
vm.$Toast.error('签名信息错误: ' + res.errMsg)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { title } from '@/settings'
|
||||
|
||||
export default function getPageTitle(pageTitle) {
|
||||
if (pageTitle) {
|
||||
return `${pageTitle} - ${title}`
|
||||
}
|
||||
return `${title}`
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
import EXIF from 'exif-js' //获取拍照时的信息的库(角度),用于调正图片展示角度
|
||||
import imageConversion from 'image-conversion' //图片压缩、转换处理库
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 压缩文件函数
|
||||
* 传入图片-压缩后的尺寸(kb)-压缩率
|
||||
* 返回压缩后的文件
|
||||
* @param {file} imageFile
|
||||
* @param {number} compressSize
|
||||
* @param {number} quality
|
||||
*/
|
||||
export function JudgeCompress(imageFile, compressSize, quality = 0.99) { //传入图片文件-规定压缩后的尺寸(kb)-压缩率
|
||||
return new Promise(function (resolve,reject) {
|
||||
if(imageFile.size < 100 * 1024) { //如果图片小于规定尺寸,则直接返回
|
||||
resolve(imageFile)
|
||||
return
|
||||
}
|
||||
imageConversion.compressAccurately(imageFile,{size:compressSize,accuracy:quality,scale:0.5}).then(res =>{ //压缩函数
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 图片文件转base64 DataUrl
|
||||
* @param {file} file
|
||||
*/
|
||||
export function FiletoDataURL(file){
|
||||
return new Promise((resolve,reject) => {
|
||||
imageConversion.filetoDataURL(file).then(res => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 判断文件类型是否为image
|
||||
* @param {file} file
|
||||
*/
|
||||
export function CheckFile(file) {
|
||||
if (!/image\/\w+/.test(file.type)) {
|
||||
return false;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 旋转图片总体函数
|
||||
* 传入文件,返回旋转后的文件
|
||||
* @param {file} imageFile
|
||||
*/
|
||||
export function RotateImage(imageFile) {
|
||||
return new Promise((resolve,reject)=>{
|
||||
imageConversion.filetoDataURL(imageFile).then(res =>{ //把文件转成图片格式用于旋转
|
||||
var image = new window.Image();
|
||||
image.src = res
|
||||
image.onload = function () {
|
||||
// 旋转图片
|
||||
let newImage = handleRotate(image)
|
||||
imageConversion.dataURLtoFile(newImage.src).then(res => {
|
||||
resolve(res) //返回的是file(文件)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
// 使用如上filetoDataURL插件方法实现文件转url 而 替代本手写方法 by:luqiang 20191012
|
||||
// var reader = new FileReader();
|
||||
// reader.onload = function(e){
|
||||
// }
|
||||
// reader.readAsDataURL(imageFile); //先挂载onload方法再绑定read事件
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理旋转函数,传入图片,返回旋转正确的图片
|
||||
* @param {img} image
|
||||
*/
|
||||
function handleRotate(image){ //处理旋转的函数
|
||||
var width = image.width;
|
||||
var height = image.height;
|
||||
var canvas = document.createElement("canvas")
|
||||
var ctx = canvas.getContext('2d');
|
||||
var newImage = new Image();
|
||||
//旋转图片操作
|
||||
EXIF.getData(image, function () {
|
||||
var orientation = EXIF.getTag(this, 'Orientation');
|
||||
let imageDate = null
|
||||
switch (orientation) {
|
||||
//正常状态
|
||||
case 1:
|
||||
// alert('旋转0°');
|
||||
newImage.src = image.src;
|
||||
break;
|
||||
//旋转90度
|
||||
case 6:
|
||||
// alert('旋转90°');
|
||||
canvas.height = width;
|
||||
canvas.width = height;
|
||||
ctx.rotate(Math.PI / 2);
|
||||
ctx.translate(0, -height);
|
||||
ctx.drawImage(image,0,0)
|
||||
imageDate = canvas.toDataURL('image/jpeg', 1)
|
||||
newImage.src = imageDate;
|
||||
break;
|
||||
//旋转180°
|
||||
case 3:
|
||||
// alert('旋转180°');
|
||||
canvas.height = height;
|
||||
canvas.width = width;
|
||||
ctx.rotate(Math.PI);
|
||||
ctx.translate(-width, -height);
|
||||
ctx.drawImage(image,0,0)
|
||||
imageDate = canvas.toDataURL('image/jpeg', 1)
|
||||
newImage.src = imageDate;
|
||||
break;
|
||||
//旋转270°
|
||||
case 8:
|
||||
// alert('旋转270°');
|
||||
canvas.height = width;
|
||||
canvas.width = height;
|
||||
ctx.rotate(-Math.PI / 2);
|
||||
ctx.translate(-height, 0);
|
||||
ctx.drawImage(image, -810,0) //????安卓要-810????
|
||||
// ctx.drawImage(image)
|
||||
imageDate = canvas.toDataURL('image/jpeg', 1)
|
||||
newImage.src = imageDate;
|
||||
break;
|
||||
//undefined时不旋转
|
||||
case undefined:
|
||||
// alert('旋转0°');
|
||||
newImage.src = image.src;
|
||||
break;
|
||||
default:
|
||||
newImage.src = image.src;
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
return newImage;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 压缩图片函数 --> by:luqiang 20191012 使用imageConversion库代替手写操作以精准控制压缩后的文件尺寸
|
||||
// function Compress(image, quality) {
|
||||
// var canvas = document.createElement('canvas')
|
||||
// var ctx = canvas.getContext('2d');
|
||||
// var width = image.width;
|
||||
// var height = image.height;
|
||||
// canvas.width = width;
|
||||
// canvas.height = height;
|
||||
// ctx.drawImage(image, 0, 0, width, height);
|
||||
// //压缩操作
|
||||
// var imageData = canvas.toDataURL("image/jpeg", quality);
|
||||
// var imageLength = image.src.length;
|
||||
// console.log("压缩前:" + imageLength);
|
||||
// console.log("压缩后:" + imageData.length,imageData);
|
||||
// console.log("压缩率:" + ~~(100 * (imageLength - imageData.length) / imageLength) + "%");
|
||||
// return imageData;
|
||||
// }
|
|
@ -0,0 +1,52 @@
|
|||
import axios from 'axios'
|
||||
import router from '@/router'
|
||||
import vm from '@/main.js'
|
||||
import { globalSuccessToast } from '@/settings'
|
||||
|
||||
const service = axios.create({
|
||||
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
|
||||
withCredentials: true, // 设置是否在请求中携带cookie
|
||||
timeout: 30000 // 请求超时时间
|
||||
})
|
||||
|
||||
// request interceptor(请求拦截器)
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
vm.$Loading.show()
|
||||
// 给config统一配置属性
|
||||
return config
|
||||
},
|
||||
error => {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
//response (响应拦截器)
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
vm.$Loading.hidden()
|
||||
const res = response.data
|
||||
const code = response.status
|
||||
if (code !== 200) {
|
||||
vm.$Toast.error(res.msg)
|
||||
return Promise.reject(new Error(res.msg || 'Error'))
|
||||
} else {
|
||||
if (globalSuccessToast && res.code == 0) { //全局成功提示
|
||||
// vm.$Toast.success('查询成功!') //暂时不要
|
||||
}
|
||||
return res
|
||||
}
|
||||
},
|
||||
error => {
|
||||
vm.$Loading.hidden()
|
||||
if (error.response.status && error.response.status == 401) { //拦截401,代表登陆失效,触发页面刷新后再触发路由拦截,拦截到重新登录
|
||||
// 401一般是权限问题或者登录失效
|
||||
// router.push('/login') //如果项目存在登录验证,应该在这里返回登录页面重新登录;
|
||||
console.log('response status is 401')
|
||||
}
|
||||
vm.$Toast.error(error)
|
||||
return Promise.reject(error) //请求错误不return出去,直接在这里处理toast
|
||||
}
|
||||
)
|
||||
|
||||
export default service
|
|
@ -0,0 +1,33 @@
|
|||
import waterMark from '@/assets/image/waterMark.png'
|
||||
function drawAndShareImage(imgUrl){
|
||||
return new Promise((resolve,reject) => {
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = 1280;
|
||||
canvas.height = 720;
|
||||
var context = canvas.getContext("2d");
|
||||
|
||||
// context.rect(0 , 0 , canvas.width , canvas.height);
|
||||
// context.fillStyle = "#fff";
|
||||
// context.fill();
|
||||
|
||||
var myImage = new Image();
|
||||
myImage.crossOrigin = 'Anonymous'; //允许跨域
|
||||
myImage.src = imgUrl; //背景图片
|
||||
myImage.onload = function(){
|
||||
context.drawImage(myImage , 0 , 0 , 1280 , 720);
|
||||
// context.font = "60px Courier New";
|
||||
// context.fillText("我是文字",350,450);
|
||||
var waterMarkImg = new Image();
|
||||
waterMarkImg.crossOrigin = 'Anonymous';
|
||||
waterMarkImg.src = waterMark; //水印图
|
||||
|
||||
waterMarkImg.onload = function(){ //第二次绘制,绘制logo即可
|
||||
context.drawImage(waterMarkImg , 0 , 0 , 499 , 210);
|
||||
var base64 = canvas.toDataURL("image/jpg"); //"image/png" 这里注意一下
|
||||
resolve(base64)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default drawAndShareImage
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div class='QR-code-wrap'>
|
||||
<div class="info-card">
|
||||
<div class="title">身份二维码</div>
|
||||
<div class="QR-wrap">
|
||||
<div class="temp">
|
||||
<div class="QRImg" ref="qrCodeUrl"></div>
|
||||
</div>
|
||||
<div class="hint">
|
||||
<div>本码用于领取物资!请妥善保管二维码!</div>
|
||||
<div>(刷新倒计时:<span style="color:red">{{times}}s</span>)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="button" @click="Update">刷新</div>
|
||||
</div>
|
||||
<img class="bottom-img" src="@/assets/image/logo.png" alt="">
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import QRCode from 'qrcodejs2'
|
||||
import { GetQRCode } from 'api/QRCode'
|
||||
|
||||
export default {
|
||||
name:'QRCode',
|
||||
data(){
|
||||
return {
|
||||
times: 0,
|
||||
Code: null,
|
||||
timer: null,
|
||||
upDateTime:30
|
||||
}
|
||||
},
|
||||
activated(){
|
||||
this.Code = sessionStorage.Code
|
||||
if(this.Code){
|
||||
this.getQRCode(this.Code)
|
||||
}else{
|
||||
this.$Toast.error('未认证人脸信息!即将返回!')
|
||||
setTimeout(() => {
|
||||
this.$router.push('/home')
|
||||
},800)
|
||||
}
|
||||
},
|
||||
deactivated(){
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods:{
|
||||
getQRCode(code,flag){
|
||||
GetQRCode(code).then(res =>{
|
||||
if(res.code === 0){
|
||||
this.QRCode = res.data.Code
|
||||
this.creatQrCode(this.QRCode)
|
||||
if(flag){ //如果是刷新操作则提示一下
|
||||
this.$Toast.success('二维码刷新成功')
|
||||
}
|
||||
}else{
|
||||
this.$Toast.error('查询二维码失败!即将返回!')
|
||||
setTimeout(() => {
|
||||
this.$router.push('/home')
|
||||
},800)
|
||||
}
|
||||
})
|
||||
},
|
||||
Update(){ //刷新二维码
|
||||
this.getQRCode(this.Code,true)
|
||||
},
|
||||
creatQrCode(text) { //创建二维码
|
||||
clearInterval(this.timer)
|
||||
this.times = this.upDateTime
|
||||
this.$refs.qrCodeUrl.innerHTML = '' //每次创建二维码先清空之前的二维码图片
|
||||
var qrcode = new QRCode(this.$refs.qrCodeUrl, {
|
||||
text:text,
|
||||
width:200,
|
||||
height:200,
|
||||
colorDark: '#000000',
|
||||
colorLight: '#ffffff',
|
||||
correctLevel: QRCode.CorrectLevel.H
|
||||
})
|
||||
// 每三十秒刷新一次二维码
|
||||
this.timer = setInterval(() => {
|
||||
if(this.times == 0){
|
||||
this.getQRCode(this.Code,true)
|
||||
}else{
|
||||
this.times --
|
||||
}
|
||||
},1000)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.QR-code-wrap
|
||||
box-sizing border-box
|
||||
width 100%
|
||||
overflow hidden
|
||||
height 100vh
|
||||
position relative
|
||||
.bottom-img
|
||||
position absolute
|
||||
bottom 0px
|
||||
width 100%
|
||||
left 0
|
||||
.info-card
|
||||
position relative
|
||||
z-index 999
|
||||
width 90%
|
||||
border-radius 15px
|
||||
background white
|
||||
margin 0 auto
|
||||
display flex
|
||||
flex-direction column
|
||||
justify-content center
|
||||
align-items center
|
||||
padding-bottom 30px
|
||||
overflow hidden
|
||||
margin-top 70px
|
||||
.title
|
||||
Title()
|
||||
.button
|
||||
Button()
|
||||
.QR-wrap
|
||||
width 100%
|
||||
display flex
|
||||
justify-content center
|
||||
flex-direction column
|
||||
align-items center
|
||||
padding 20px
|
||||
box-sizing border-box
|
||||
.temp
|
||||
width 224px
|
||||
height 224px
|
||||
box-sizing border-box
|
||||
padding 10px
|
||||
border 2px dotted #eee
|
||||
border-radius 5px
|
||||
.QRImg
|
||||
display flex
|
||||
justify-content center
|
||||
font-size 0
|
||||
.hint
|
||||
font-size 12px
|
||||
color #666
|
||||
margin-top 10px
|
||||
text-align center
|
||||
div
|
||||
margin-top 15px
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
|
@ -0,0 +1,296 @@
|
|||
<template>
|
||||
<div class="admin-wrap">
|
||||
<!-- <div class="title">操作中心</div> -->
|
||||
<div class="scan-wrap">
|
||||
<div class="main" @click="onScan">
|
||||
<img src="@/assets/image/scan1.png" alt="" class="outside">
|
||||
<img src="@/assets/image/scan2.png" alt="" class="interior">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info">
|
||||
<div class="main">
|
||||
<div class="detail">
|
||||
<div class="main">
|
||||
<div class="temp">
|
||||
<div class="userInfo">
|
||||
<span>姓名:</span>
|
||||
<span class="value">{{userData.Name}}</span>
|
||||
</div>
|
||||
<div class="userInfo">
|
||||
<span class='type'>身份证号:</span>
|
||||
<span class="value">{{idCard}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="img-wrap">
|
||||
<!-- <div class="imgs" :style="{backgroundImage:`url(${userData.imgUrl})`}" @click="showPreview = true"></div> -->
|
||||
<van-image
|
||||
class="imgs"
|
||||
fit="contain"
|
||||
:src="userData.FaceImgUrl"
|
||||
@click="showPreview = true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-wrap">
|
||||
<input v-model="code" type="text" placeholder='请输入编号'>
|
||||
<div class="button" @click="onSubmit">确认发放</div>
|
||||
</div>
|
||||
<van-image-preview
|
||||
v-model="showPreview"
|
||||
:images="images"
|
||||
>
|
||||
</van-image-preview>
|
||||
<img class="bottom-img" src="@/assets/image/logo.png" alt="">
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import {Icon, ImagePreview, Image,Dialog } from 'vant'
|
||||
import WeChatScan from 'utils/WeChatScan.js'
|
||||
import Vue from 'vue';
|
||||
Vue.use(ImagePreview);
|
||||
import { GetPeopleData, AddNo } from 'api/admin'
|
||||
|
||||
|
||||
export default {
|
||||
name:"Admin",
|
||||
data(){
|
||||
return {
|
||||
userData:{IdCard:'',Name:''},
|
||||
showPreview:false,
|
||||
code:'',
|
||||
}
|
||||
},
|
||||
components:{
|
||||
[Icon.name] :Icon,
|
||||
[Image.name]:Image,
|
||||
[Dialog.name]:Dialog,
|
||||
},
|
||||
computed:{
|
||||
images(){
|
||||
return [this.userData.FaceImgUrl]
|
||||
},
|
||||
idCard(){
|
||||
if(this.userData.IdCard){
|
||||
let str = this.userData.IdCard
|
||||
let difference = str.length - 5 - 3;
|
||||
return str.slice(0, 5) + '*'.repeat(difference) + str.slice(-3)
|
||||
}else{
|
||||
return ''
|
||||
}
|
||||
|
||||
// let replaceStr = new Array(difference + 1).join('*')
|
||||
// return this.userData.IdCard.replace(/^(.{5})(?:\d+)(.{3})$/,'$1' + replaceStr + '$2');
|
||||
}
|
||||
},
|
||||
activated(){
|
||||
this.$Toast.success('欢迎您!管理员!')
|
||||
},
|
||||
methods:{
|
||||
onScan(){
|
||||
WeChatScan(this.handleScanCode) //调用微信扫一扫一系列流程,传入回调函数
|
||||
},
|
||||
handleScanCode(ScanCode){
|
||||
this.userData = {}
|
||||
GetPeopleData(ScanCode).then(res => {
|
||||
if(res.code === 0){
|
||||
this.$Toast.success('查询成功!')
|
||||
this.userData = res.data
|
||||
if(res.data.No){
|
||||
Dialog.alert({
|
||||
title: '改用户已经绑定,无需再次绑定',
|
||||
message: '绑定编号为:' + this.userData.No
|
||||
});
|
||||
}
|
||||
}else{
|
||||
this.$Toast.error(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit(){
|
||||
var reg = new RegExp('^[0-9]*$')
|
||||
if(this.code){
|
||||
if(!reg.test(this.code)){
|
||||
this.$Toast.error('请输入数字!')
|
||||
return
|
||||
}
|
||||
AddNo(this.userData.CodeMd5,this.code).then(res=> {
|
||||
if(res.code != 0 && res.code != 2018){
|
||||
this.$Toast.error('绑定失败:' + res.msg)
|
||||
}
|
||||
if(res.code === 0){
|
||||
this.$Toast.success('绑定成功!')
|
||||
}else if(res.code === 2018){
|
||||
Dialog.alert({
|
||||
title: '改用户已经绑定,请勿重复绑定',
|
||||
message: '绑定编号为:' + this.userData.No
|
||||
});
|
||||
}
|
||||
this.userData = {} //操作成功清空
|
||||
this.code = ''
|
||||
})
|
||||
}else{
|
||||
this.$Toast.error('请输入编号')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
@keyframes rotate{
|
||||
0%{
|
||||
transform: rotate(0deg) scale(1);
|
||||
}
|
||||
50%{
|
||||
transform:rotate(180deg) scale(1.2)
|
||||
}
|
||||
100%{
|
||||
transform: rotate(360deg) scale(1);
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.admin-wrap
|
||||
width 100%
|
||||
.bottom-img
|
||||
position absolute
|
||||
bottom 0px
|
||||
width 100%
|
||||
left 0
|
||||
.title
|
||||
padding 10px
|
||||
font-size 14px
|
||||
background rgb(64,158,255)
|
||||
text-align center
|
||||
color white
|
||||
.scan-wrap
|
||||
display flex
|
||||
justify-content center
|
||||
padding 30px 0
|
||||
.main
|
||||
width 25%
|
||||
position relative
|
||||
.outside
|
||||
width 100%
|
||||
animation rotate 5s linear 0s normal infinite
|
||||
.interior
|
||||
position absolute
|
||||
left 50%
|
||||
top 50%
|
||||
transform translate(-50%,-50%)
|
||||
width 50%
|
||||
.info
|
||||
width 90%
|
||||
border-radius 5px
|
||||
margin 0 auto
|
||||
min-height 100px
|
||||
background white
|
||||
overflow hidden
|
||||
.title
|
||||
background #eee
|
||||
color black
|
||||
.main
|
||||
width 100%
|
||||
padding 10px
|
||||
box-sizing border-box
|
||||
display flex
|
||||
justify-content space-between
|
||||
.img-wrap
|
||||
width 26%
|
||||
height 0
|
||||
background rgb(250,250,250)
|
||||
padding-bottom 30%
|
||||
box-sizing border-box
|
||||
position relative
|
||||
.imgs
|
||||
position absolute
|
||||
left 5px
|
||||
top 5px
|
||||
right 5px
|
||||
bottom 5px
|
||||
.detail
|
||||
width 72%
|
||||
box-sizing border-box
|
||||
vertical-align top
|
||||
height 0
|
||||
padding-bottom 30%
|
||||
background rgb(250,250,250)
|
||||
position relative
|
||||
font-size 16px
|
||||
.main
|
||||
position absolute
|
||||
left 0
|
||||
right 0
|
||||
top 0
|
||||
bottom 0
|
||||
display flex
|
||||
justify-content center
|
||||
align-items center
|
||||
.temp
|
||||
width 100%
|
||||
.userInfo
|
||||
color #666
|
||||
margin 10px 0
|
||||
word-wrap break-word
|
||||
white-space:normal
|
||||
font-size 14px
|
||||
.type
|
||||
width 5em
|
||||
display inline-block
|
||||
vertical-align top
|
||||
.value
|
||||
width calc(100% - 5em)
|
||||
display inline-block
|
||||
color #0086ff
|
||||
font-size 15px
|
||||
.input-wrap
|
||||
background white
|
||||
margin 0 auto
|
||||
width 90%
|
||||
border-radius 5px
|
||||
overflow hidden
|
||||
padding 20px 0
|
||||
display flex
|
||||
flex-direction column
|
||||
align-items center
|
||||
margin-top 5px
|
||||
box-sizing border-box
|
||||
position relative
|
||||
z-index 999
|
||||
input
|
||||
border none
|
||||
border-bottom 1px solid rgb(64,158,255)
|
||||
width 110px
|
||||
text-align center
|
||||
padding 10px
|
||||
border-radius 0
|
||||
font-size 25px
|
||||
color rgb(64,158,255)
|
||||
&::-webkit-input-placeholder
|
||||
text-align center
|
||||
font-size 16px
|
||||
color rgba(64,158,255,0.7)
|
||||
.button
|
||||
Button()
|
||||
margin-top 25px
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
<template>
|
||||
<div class="addPhoto-wrap">
|
||||
<div class="main-wrap">
|
||||
<!-- <div class="img-title">
|
||||
<span>请上传人脸照片</span>
|
||||
</div> -->
|
||||
<div class="main">
|
||||
<div class="img-item" >
|
||||
<div class="template-wrap">
|
||||
<!-- 使用背景图展示 -->
|
||||
<!-- <div class="imgs" :style="{backgroundImage:`url(${photo.url})`}"></div> -->
|
||||
<!-- 用image组件展示 -->
|
||||
<div class="img-wrap">
|
||||
<van-image
|
||||
v-show="photo"
|
||||
class="imgs"
|
||||
fit="contain"
|
||||
:src="photo"
|
||||
/>
|
||||
|
||||
<div class="temp" v-show="!photo" >
|
||||
<!-- <img class="cameraIcon" src="@/assets/image/camera-icon.png" alt=""> -->
|
||||
<svg class="cameraIcon" viewBox="0 0 24 24"><path fill="currentColor" d="M20,4H16.83L15,2H9L7.17,4H4A2,2 0 0,0 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6A2,2 0 0,0 20,4M20,18H4V6H8.05L9.88,4H14.12L15.95,6H20V18M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15Z" /></svg>
|
||||
<span>头像上传</span>
|
||||
</div>
|
||||
</div>
|
||||
<input :key="isKey" @change="onChange($event)" id="myInput" ref="myInput" type="file" accept="image/*">
|
||||
<!-- <input :key="isKey" @change="onChange($event)" id="myInput" ref="myInput" type="file" accept="image/*"> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 用来放添加按钮 -->
|
||||
<!-- <div class="img-item" v-show="!photo.url">
|
||||
<div class="template-wrap">
|
||||
<input :key="isKey" @change="onChange($event)" id="myInput" ref="myInput" type="file" accept="image/*" capture="camera">
|
||||
<div class="img-wrap">
|
||||
<div class="temp">
|
||||
<img class="cameraIcon" src="@/assets/image/camera-icon.png" alt="">
|
||||
<span>头像上传</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { JudgeCompress, RotateImage, CheckFile, FiletoDataURL } from '@/utils/handleImage'
|
||||
import { Image } from 'vant'
|
||||
|
||||
|
||||
export default {
|
||||
name:'AddPhoto',
|
||||
// props:{
|
||||
// photo:Object,
|
||||
// },
|
||||
components:{
|
||||
[Image.name]:Image,
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
isKey:0,
|
||||
compressSize:100,
|
||||
photo:'',
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onChange(e) {
|
||||
if(!e.target.files[0]){ //用户可能取消选择,此时啥都不用做
|
||||
return
|
||||
}
|
||||
this.$emit('readyHandle') //告诉父级已经开始处理.
|
||||
this.photo = ''
|
||||
let file = e.target.files[0];
|
||||
let _this = this
|
||||
if(file){
|
||||
var imageFile = CheckFile(file);
|
||||
if(!imageFile){
|
||||
this.$Toast.error('文件格式错误!')
|
||||
return
|
||||
}else{
|
||||
RotateImage(imageFile).then(res =>{ //传入文件,旋转后返回文件进行压缩
|
||||
JudgeCompress(res,this.compressSize,0.95).then(res => { //传入文件,压缩返回压缩后的文件
|
||||
FiletoDataURL(res).then(res => { //传入文件,返回base64 DataURL
|
||||
_this.photo = res
|
||||
_this.$emit('changePhoto', res)
|
||||
_this.isKey = (new Date()).getTime() //修改key以防止重新选择同一张图不触发change
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.addPhoto-wrap
|
||||
width 100%
|
||||
position relative
|
||||
z-index 999
|
||||
.main-wrap
|
||||
width 100%
|
||||
padding 0
|
||||
box-sizing border-box
|
||||
.img-title
|
||||
// background rgb(64,158,255)
|
||||
padding 10px
|
||||
text-align center
|
||||
font-size 14px
|
||||
align-items center
|
||||
color black
|
||||
padding-left 5px
|
||||
.main
|
||||
width 100%
|
||||
box-sizing border-box
|
||||
padding 40px 5px
|
||||
display flex
|
||||
justify-content center
|
||||
.img-item
|
||||
width 50%
|
||||
height 0
|
||||
padding-bottom 50%
|
||||
position relative
|
||||
overflow hidden
|
||||
box-sizing border-box
|
||||
display inline-block
|
||||
.template-wrap
|
||||
box-sizing border-box
|
||||
position absolute
|
||||
overflow hidden
|
||||
bottom 5px
|
||||
top 5px
|
||||
left 5px
|
||||
overflow hidden
|
||||
right 5px
|
||||
// background rgba(0,133,208,0.7)
|
||||
padding 5px
|
||||
.img-wrap
|
||||
box-sizing border-box
|
||||
width 100%
|
||||
height 100%
|
||||
border-radius 5px
|
||||
overflow hidden
|
||||
.imgs
|
||||
width 100%
|
||||
height 100%
|
||||
.temp
|
||||
position absolute
|
||||
top 5px
|
||||
bottom 5px
|
||||
left 5px
|
||||
right 5px
|
||||
border-radius 5px
|
||||
overflow hidden
|
||||
position absolute
|
||||
left 50%
|
||||
top 50%
|
||||
transform translate(-50%, -50%)
|
||||
display flex
|
||||
flex-direction column
|
||||
justify-content center
|
||||
align-items center
|
||||
span
|
||||
color black
|
||||
margin-top 10px
|
||||
font-size 14px
|
||||
.cameraIcon
|
||||
width 60px
|
||||
height 60px
|
||||
color black
|
||||
#myInput
|
||||
position absolute
|
||||
left 0
|
||||
top 0
|
||||
z-index 500
|
||||
display inline-block
|
||||
opacity 0
|
||||
width 100%
|
||||
height 100%
|
||||
|
||||
</style>
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<div class='home-wrap'>
|
||||
<div class="background-wrap">
|
||||
<img class="background-image" src="@/assets/image/track.jpg" />
|
||||
</div>
|
||||
<!-- <div class="top-bgimg-wrap">
|
||||
<img class="top-img" src="@/assets/image/bgimg-top.png"/>
|
||||
<div class="logo-wrap">
|
||||
<img class="yidong-img" src="@/assets/image/yidong.png"/>
|
||||
<img class="fiveG-img" src="@/assets/image/5g.png"/>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="info-card flex-container">
|
||||
<add-photo @changePhoto="changePhoto" @readyHandle='readyHandle'></add-photo>
|
||||
<div class="form">
|
||||
<van-field required v-model="formData.Name" clearable placeholder="请输入姓名" />
|
||||
<van-field required type='number' v-model="formData.Phone" clearable placeholder="请输入手机号" />
|
||||
<!-- <van-field required type='text' v-model="formData.Code" clearable placeholder="请输入参赛编号" /> -->
|
||||
</div>
|
||||
<div class="button" @click="onSubmit">提交</div>
|
||||
</div>
|
||||
<!-- <div class="hint">
|
||||
温馨提示:请使用只包含本人正面头像的清晰照片进行注册
|
||||
</div> -->
|
||||
<!-- <img class="bottom-img" src="@/assets/image/bgimg-bottom.png" alt=""> -->
|
||||
<!-- <van-image-preview v-model="showPreview" :images="images"> </van-image-preview> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addPhoto from "./components/addPhoto"
|
||||
import { Field, Dialog } from 'vant';
|
||||
import { Runnerverify} from 'api/home'
|
||||
|
||||
export default {
|
||||
name:'Home',
|
||||
components:{
|
||||
addPhoto,
|
||||
[Field.name]:Field,
|
||||
[Dialog.name]:Dialog
|
||||
},
|
||||
activated(){
|
||||
|
||||
},
|
||||
watch:{
|
||||
Code(val){
|
||||
sessionStorage.Code = val
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
photo:'',
|
||||
formData:{
|
||||
Name:'',
|
||||
Phone:'',
|
||||
Code:''
|
||||
},
|
||||
Code:null, //存入本地的code
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
changePhoto(imgBase64){
|
||||
this.photo = imgBase64
|
||||
this.$Loading.hidden()
|
||||
},
|
||||
readyHandle(){
|
||||
this.$Loading.show('正在处理图片...')
|
||||
},
|
||||
onSubmit(){
|
||||
if(this.verifyForm()){
|
||||
let data = {
|
||||
Name: this.formData.Name,
|
||||
facePic: this.photo,
|
||||
Phone:this.formData.Phone
|
||||
}
|
||||
this.$Loading.show('正在注册...')
|
||||
Runnerverify(data).then(res => {
|
||||
if(res.code === 0){
|
||||
this.$Toast.success('注册成功!')
|
||||
this.$router.push('/photos')
|
||||
localStorage.images = JSON.stringify(res.data)
|
||||
}else if(res.code === 2004){ //号码已被使用
|
||||
Dialog.alert({
|
||||
title: '温馨提示',
|
||||
message: '号码已被占用,请使用新的手机号码进行注册!'
|
||||
});
|
||||
}else if(res.code == 2021){ //如果返回没有照片则提示用户
|
||||
localStorage.images = []
|
||||
this.$router.push({
|
||||
path:'/photos',
|
||||
query:{
|
||||
type:'hintPage'
|
||||
}
|
||||
})
|
||||
}else{
|
||||
this.$Toast.error('注册失败:' + res.msg)
|
||||
}
|
||||
this.$Loading.hidden()
|
||||
}).catch(err => {
|
||||
this.$Loading.hidden()
|
||||
})
|
||||
}
|
||||
},
|
||||
verifyForm(){ //表单校验
|
||||
// let idcardReg = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X|x)$/;
|
||||
// let IDcardFlag = idcardReg.test(this.formData.IDcard) ? true : false;
|
||||
let NameFlag = this.formData.Name.length && this.formData.Name.length > 0 ? true : false
|
||||
if(!this.photo){
|
||||
this.$Toast.error('请上传人脸照片!')
|
||||
return
|
||||
}else if(!NameFlag){
|
||||
this.$Toast.error('请填写姓名!')
|
||||
return
|
||||
}else if(this.formData.Phone.length !== 11){
|
||||
this.$Toast.error('请填写正确的手机号码!')
|
||||
return
|
||||
}else{
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,93 @@
|
|||
<template>
|
||||
<div class='home-wrap'>
|
||||
<div class="background-wrap">
|
||||
<img class="background-image" src="@/assets/image/track.jpg" />
|
||||
</div>
|
||||
<!-- <div class="top-bgimg-wrap">
|
||||
<img class="top-img" src="@/assets/image/bgimg-top.png"/>
|
||||
<div class="logo-wrap">
|
||||
<img class="yidong-img" src="@/assets/image/yidong.png"/>
|
||||
<img class="fiveG-img" src="@/assets/image/5g.png"/>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="top-brand-wrap">
|
||||
<h1 class="title">5G 赛道</h1>
|
||||
</div>
|
||||
<div class="info-card flex-container">
|
||||
<div class="form">
|
||||
<van-field required v-model="formData.Name" clearable placeholder="请输入姓名" />
|
||||
<van-field required type='number' v-model="formData.Phone" clearable placeholder="请输入手机号" />
|
||||
</div>
|
||||
<div class="button register" @click="onRegister">注册</div>
|
||||
<div class="button" @click="onLogin">登陆</div>
|
||||
</div>
|
||||
<!-- <div class="hint">
|
||||
已使用“5G赛道”小程序完成人脸注册的用户,请直接输入注册时的姓名和手机号码,登陆并领取照片。
|
||||
</div> -->
|
||||
<!-- <img class="bottom-img" src="@/assets/image/bgimg-bottom.png" alt=""> -->
|
||||
<!-- <van-image-preview v-model="showPreview" :images="images"> </van-image-preview> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Field, Toast, CellGroup, Dialog } from 'vant';
|
||||
import { Login } from 'api/home'
|
||||
|
||||
import imgs1 from '@/assets/image/imgs-01.jpg'
|
||||
import imgs2 from '@/assets/image/imgs-02.jpg'
|
||||
|
||||
export default {
|
||||
name:'Home',
|
||||
components:{
|
||||
[Field.name]:Field,
|
||||
[CellGroup.name]:CellGroup,
|
||||
},
|
||||
activated(){
|
||||
|
||||
},
|
||||
watch:{
|
||||
Code(val){
|
||||
sessionStorage.Code = val
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
photo:'',
|
||||
formData:{
|
||||
Name:'',
|
||||
Phone:'',
|
||||
},
|
||||
Code:null, //存入本地的code
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onLogin(){
|
||||
if(!this.formData.Name){
|
||||
this.$Toast.error('请填写姓名!')
|
||||
return
|
||||
}else if(!this.formData.Phone || this.formData.Phone.length != 11){
|
||||
this.$Toast.error('请填写正确的手机号!')
|
||||
return
|
||||
}else{
|
||||
this.$Loading.show('正在登陆...')
|
||||
Login(this.formData).then(res => {
|
||||
if(res.code === 0){
|
||||
this.$Toast.success('登陆成功!')
|
||||
this.$router.push('/photos')
|
||||
localStorage.images = JSON.stringify(res.data)
|
||||
// localStorage.images = JSON.stringify([imgs1,imgs2,imgs1,imgs2])
|
||||
}else{
|
||||
this.$Toast.error('登陆失败:' + res.msg)
|
||||
}
|
||||
this.$Loading.hidden()
|
||||
}).catch(err => {
|
||||
this.$Loading.hidden()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRegister(){
|
||||
this.$router.push('/home')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,104 @@
|
|||
<template>
|
||||
<div class='home-wrap'>
|
||||
<div class="background-wrap">
|
||||
<img class="background-image" src="@/assets/image/track.jpg" />
|
||||
</div>
|
||||
<!-- <div class="top-bgimg-wrap">
|
||||
<img class="top-img" src="@/assets/image/bgimg-top.png"/>
|
||||
<div class="logo-wrap">
|
||||
<img class="yidong-img" src="@/assets/image/yidong.png"/>
|
||||
<img class="fiveG-img" src="@/assets/image/5g.png"/>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="flex-container">
|
||||
<template v-if="!hintFlag">
|
||||
<div class="top-brand-wrap">
|
||||
<h1 class="title">您的 5G 纪念册</h1>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="imgs-wrap">
|
||||
<div class="imgs-item" v-for="(item,index) in imgs" :key="index">
|
||||
<img :src="item" alt="" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint" v-show='showHint'>
|
||||
<span>您没有任何纪念照哦!</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="button" @click="onRegister">重新注册</div>
|
||||
<template v-if="hintFlag">
|
||||
<div class="title">您的5G纪念册为空</div>
|
||||
<div class="hint-wrap">
|
||||
<div class="main">
|
||||
<div class="info-title">温馨提示</div>
|
||||
<div class="info">
|
||||
<p>1、为保证识别效果,请使用只有自己正面头像的清晰照片注册;</p>
|
||||
<p>2、若之前上传的照片效果不佳,没有匹配到照片,可以使用新的手机号码和头像照片,重新注册。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<!-- <img class="bottom-img" src="@/assets/image/bgimg-bottom.png" alt=""> -->
|
||||
<!-- <van-image-preview v-model="showPreview" :images="imgs"> </van-image-preview> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Field, CellGroup, Dialog } from 'vant';
|
||||
// import { ImagePreview} from 'vant'
|
||||
// import Vue from 'vue';
|
||||
// Vue.use(ImagePreview);
|
||||
import { GetUserAttestation } from 'api/home'
|
||||
import drawAndShareImage from '@/utils/waterMark'
|
||||
|
||||
export default {
|
||||
name:'Home',
|
||||
components:{
|
||||
[Field.name]:Field,
|
||||
[CellGroup.name]:CellGroup,
|
||||
[Dialog.name]:Dialog,
|
||||
},
|
||||
activated(){
|
||||
this.hintFlag = this.$route.query.type
|
||||
if(this.hintFlag) return
|
||||
let imgs = JSON.parse(localStorage.images)
|
||||
if(imgs){
|
||||
console.log(imgs,47)
|
||||
if(imgs.length === 0){
|
||||
this.showHint = true
|
||||
}
|
||||
this.handlerMark(imgs)
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
imgs:[],
|
||||
hintFlag:false, //空白页提示flag
|
||||
// showPreview:false,
|
||||
showHint:false
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onRegister(){
|
||||
Dialog.alert({
|
||||
title: '温馨提示',
|
||||
message: '请务必使用新的手机号码重新注册!'
|
||||
}).then(() => {
|
||||
this.$router.replace('/home')
|
||||
});
|
||||
},
|
||||
handlerMark(arr){
|
||||
this.imgs = []
|
||||
arr.forEach(ele => {
|
||||
this.$Loading.show('正在处理图片...')
|
||||
drawAndShareImage(ele).then(res =>{
|
||||
this.imgs.push(res)
|
||||
this.$Loading.hidden()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,49 @@
|
|||
'use strict'
|
||||
const path = require('path')
|
||||
|
||||
const resolve = dir => path.join(__dirname, dir)
|
||||
|
||||
const titleName = '5G 赛道' // 页面默认title,在路由中被覆盖(刚进入页面路由之前会展示这一段,之后会被路由中的逻辑覆盖)
|
||||
const port = process.env.VUE_APP_BASE_PORT || process.env.npm_config_port || 8088 // dev port 端口号
|
||||
|
||||
module.exports = {
|
||||
publicPath: process.env.NODE_ENV === "production" ? "./" : "/", //生产环境改成相对路径
|
||||
outputDir: 'dist',
|
||||
assetsDir: 'static', //打包后其他静态资源所在文件夹
|
||||
productionSourceMap: false, //设置成false加快打包速度,同时放弃生产环境的镜像map,也就是不能准确定位报错行数;
|
||||
devServer: {
|
||||
port: port,
|
||||
open: true,
|
||||
proxy: {
|
||||
[process.env.VUE_APP_BASE_API]: {
|
||||
target: `http://5gmalasong.hnabc.cn`,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
configureWebpack: {
|
||||
name: titleName, //在index.html中可通过webpackConfig.name使用
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve('src'),
|
||||
'components': resolve('src/components'),
|
||||
'globalComponents':resolve('src/globalComponents'),
|
||||
'utils':resolve('src/utils'),
|
||||
'assets':resolve('src/assets'),
|
||||
'api':resolve('src/api'),
|
||||
'styles':resolve('src/styles'),
|
||||
}
|
||||
}
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
// 给 stylus-loader 传递选项,使得指定stylus公共变量可以全局使用
|
||||
stylus: {
|
||||
import: ['~@/styles/variables.styl']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|