metaMask login
This commit is contained in:
parent
5fce327ce6
commit
a32a4e4e39
229
package.json
229
package.json
@ -1,114 +1,115 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-element-admin",
|
"name": "vue-element-admin",
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
||||||
"author": "Pan <panfree23@gmail.com>",
|
"author": "Pan <panfree23@gmail.com>",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vue-cli-service serve",
|
"dev": "vue-cli-service serve",
|
||||||
"lint": "eslint --ext .js,.vue src",
|
"lint": "eslint --ext .js,.vue src",
|
||||||
"build:prod": "vue-cli-service build",
|
"build:prod": "vue-cli-service build",
|
||||||
"build:stage": "vue-cli-service build --mode staging",
|
"build:stage": "vue-cli-service build --mode staging",
|
||||||
"preview": "node build/index.js --preview",
|
"preview": "node build/index.js --preview",
|
||||||
"new": "plop",
|
"new": "plop",
|
||||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
|
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
|
||||||
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
||||||
"test:ci": "npm run lint && npm run test:unit"
|
"test:ci": "npm run lint && npm run test:unit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "0.18.1",
|
"axios": "0.18.1",
|
||||||
"clipboard": "2.0.4",
|
"clipboard": "2.0.4",
|
||||||
"codemirror": "5.45.0",
|
"codemirror": "5.45.0",
|
||||||
"core-js": "3.6.5",
|
"core-js": "3.6.5",
|
||||||
"driver.js": "0.9.5",
|
"driver.js": "0.9.5",
|
||||||
"dropzone": "5.5.1",
|
"dropzone": "5.5.1",
|
||||||
"echarts": "4.2.1",
|
"echarts": "4.2.1",
|
||||||
"element-ui": "2.13.2",
|
"element-ui": "2.13.2",
|
||||||
"file-saver": "2.0.1",
|
"file-saver": "2.0.1",
|
||||||
"fuse.js": "3.4.4",
|
"fuse.js": "3.4.4",
|
||||||
"js-cookie": "2.2.0",
|
"js-cookie": "2.2.0",
|
||||||
"jsonlint": "1.6.3",
|
"jsonlint": "1.6.3",
|
||||||
"jszip": "3.2.1",
|
"jszip": "3.2.1",
|
||||||
"normalize.css": "7.0.0",
|
"normalize.css": "7.0.0",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"path-to-regexp": "2.4.0",
|
"path-to-regexp": "2.4.0",
|
||||||
"pinyin": "2.9.0",
|
"pinyin": "2.9.0",
|
||||||
"screenfull": "4.2.0",
|
"screenfull": "4.2.0",
|
||||||
"script-loader": "0.7.2",
|
"script-loader": "0.7.2",
|
||||||
"sortablejs": "1.8.4",
|
"sortablejs": "1.8.4",
|
||||||
"tui-editor": "1.3.3",
|
"tui-editor": "1.3.3",
|
||||||
"vue": "2.6.10",
|
"vue": "2.6.10",
|
||||||
"vue-count-to": "1.0.13",
|
"vue-count-to": "1.0.13",
|
||||||
"vue-i18n": "7.3.2",
|
"vue-i18n": "7.3.2",
|
||||||
"vue-router": "3.0.2",
|
"vue-router": "3.0.2",
|
||||||
"vue-splitpane": "1.0.4",
|
"vue-splitpane": "1.0.4",
|
||||||
"vuedraggable": "2.20.0",
|
"vuedraggable": "2.20.0",
|
||||||
"vuex": "3.1.0",
|
"vuex": "3.1.0",
|
||||||
"xlsx": "0.14.1"
|
"web3": "^1.7.4",
|
||||||
},
|
"xlsx": "0.14.1"
|
||||||
"devDependencies": {
|
},
|
||||||
"@vue/cli-plugin-babel": "4.4.4",
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-eslint": "4.4.4",
|
"@vue/cli-plugin-babel": "4.4.4",
|
||||||
"@vue/cli-plugin-unit-jest": "4.4.4",
|
"@vue/cli-plugin-eslint": "4.4.4",
|
||||||
"@vue/cli-service": "4.4.4",
|
"@vue/cli-plugin-unit-jest": "4.4.4",
|
||||||
"@vue/test-utils": "1.0.0-beta.29",
|
"@vue/cli-service": "4.4.4",
|
||||||
"autoprefixer": "9.5.1",
|
"@vue/test-utils": "1.0.0-beta.29",
|
||||||
"babel-eslint": "10.1.0",
|
"autoprefixer": "9.5.1",
|
||||||
"babel-jest": "23.6.0",
|
"babel-eslint": "10.1.0",
|
||||||
"babel-plugin-dynamic-import-node": "2.3.3",
|
"babel-jest": "23.6.0",
|
||||||
"chalk": "2.4.2",
|
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||||
"chokidar": "2.1.5",
|
"chalk": "2.4.2",
|
||||||
"connect": "3.6.6",
|
"chokidar": "2.1.5",
|
||||||
"eslint": "6.7.2",
|
"connect": "3.6.6",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint": "6.7.2",
|
||||||
"eslint-plugin-vue": "6.2.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
"html-webpack-plugin": "3.2.0",
|
"eslint-plugin-vue": "6.2.2",
|
||||||
"husky": "1.3.1",
|
"html-webpack-plugin": "3.2.0",
|
||||||
"lint-staged": "8.1.5",
|
"husky": "1.3.1",
|
||||||
"mockjs": "1.0.1-beta3",
|
"lint-staged": "8.1.5",
|
||||||
"plop": "2.3.0",
|
"mockjs": "1.0.1-beta3",
|
||||||
"runjs": "4.3.2",
|
"plop": "2.3.0",
|
||||||
"sass": "1.26.2",
|
"runjs": "4.3.2",
|
||||||
"sass-loader": "8.0.2",
|
"sass": "1.26.2",
|
||||||
"script-ext-html-webpack-plugin": "2.1.3",
|
"sass-loader": "8.0.2",
|
||||||
"serve-static": "1.13.2",
|
"script-ext-html-webpack-plugin": "2.1.3",
|
||||||
"svg-sprite-loader": "4.1.3",
|
"serve-static": "1.13.2",
|
||||||
"svgo": "1.2.0",
|
"svg-sprite-loader": "4.1.3",
|
||||||
"vue-template-compiler": "2.6.10"
|
"svgo": "1.2.0",
|
||||||
},
|
"vue-template-compiler": "2.6.10"
|
||||||
"browserslist": [
|
},
|
||||||
"> 1%",
|
"browserslist": [
|
||||||
"last 2 versions"
|
"> 1%",
|
||||||
],
|
"last 2 versions"
|
||||||
"bugs": {
|
],
|
||||||
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
|
"bugs": {
|
||||||
},
|
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
|
||||||
"engines": {
|
},
|
||||||
"node": ">=8.9",
|
"engines": {
|
||||||
"npm": ">= 3.0.0"
|
"node": ">=8.9",
|
||||||
},
|
"npm": ">= 3.0.0"
|
||||||
"keywords": [
|
},
|
||||||
"vue",
|
"keywords": [
|
||||||
"admin",
|
"vue",
|
||||||
"dashboard",
|
"admin",
|
||||||
"element-ui",
|
"dashboard",
|
||||||
"boilerplate",
|
"element-ui",
|
||||||
"admin-template",
|
"boilerplate",
|
||||||
"management-system"
|
"admin-template",
|
||||||
],
|
"management-system"
|
||||||
"license": "MIT",
|
],
|
||||||
"lint-staged": {
|
"license": "MIT",
|
||||||
"src/**/*.{js,vue}": [
|
"lint-staged": {
|
||||||
"eslint --fix",
|
"src/**/*.{js,vue}": [
|
||||||
"git add"
|
"eslint --fix",
|
||||||
]
|
"git add"
|
||||||
},
|
]
|
||||||
"husky": {
|
},
|
||||||
"hooks": {
|
"husky": {
|
||||||
"pre-commit": "lint-staged"
|
"hooks": {
|
||||||
}
|
"pre-commit": "lint-staged"
|
||||||
},
|
}
|
||||||
"repository": {
|
},
|
||||||
"type": "git",
|
"repository": {
|
||||||
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
|
"type": "git",
|
||||||
}
|
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,23 +1,38 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
export function login(data) {
|
export function login(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/user/login',
|
url: '/user/login',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function metamaskLogin(data) {
|
||||||
export function getInfo(token) {
|
return request({
|
||||||
return request({
|
url: '/user/metamask-login',
|
||||||
url: '/user/info',
|
method: 'post',
|
||||||
method: 'get'
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logout() {
|
export function getInfo(token) {
|
||||||
return request({
|
return request({
|
||||||
url: '/user/logout',
|
url: '/user/info',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function logout() {
|
||||||
|
return request({
|
||||||
|
url: '/user/logout',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNonce(account) {
|
||||||
|
return request({
|
||||||
|
url: '/user/getNonce?account=' + account,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
1
src/icons/svg/MetaMask.svg
Normal file
1
src/icons/svg/MetaMask.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1718869327969" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5949" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M517.77536 972.8c133.98016-30.19776 211.70176-70.42048 301.2608-156.3136 29.32736-28.11904 174.04928-63.68256 190.4128-100.83328 23.72608-53.8624-58.2144-115.72224-58.2144-178.40128 0-240.54784-194.06848-435.5584-433.4592-435.5584-239.38048 0-433.44896 195.01056-433.44896 435.5584 0 68.21888-86.13888 124.14976-58.3168 181.62688 15.28832 31.56992 164.1472 73.216 189.51168 97.60768C305.08032 902.68672 383.55968 942.60224 517.77536 972.8z" fill="#FFD797" p-id="5950"></path><path d="M908.77952 65.5872c-0.88064 1.40288 79.0528 276.7872 32.68608 379.32032a439.0912 439.0912 0 0 1 9.76896 92.34432c0 62.6688 81.94048 124.54912 58.2144 178.40128-1.71008 3.8912-4.88448 7.74144-9.216 11.55072-146.59584-39.44448-297.6768-4.31104-453.25312 105.41056l-5.64224 4.00384H494.592C336.24064 723.2 182.55872 686.92992 33.536 727.78752c-3.54304-3.0208-6.11328-5.9904-7.5264-8.9088-27.82208-57.47712 58.3168-113.408 58.3168-181.62688 0-27.4944 2.53952-54.39488 7.38304-80.47616-59.62752-90.97216 27.136-389.7344 26.22464-391.18848 81.39776-14.41792 159.06816 8.76544 233.03168 69.5296a430.40768 430.40768 0 0 1 166.8096-33.42336 430.44864 430.44864 0 0 1 160.94208 31.01696C751.77984 73.728 828.4672 51.36384 908.77952 65.5872z" fill="#FF6F24" p-id="5951"></path><path d="M283.1872 315.51488c31.10912-104.9088-23.97184-186.24512-165.25312-244.0192 1.024 1.65888-77.7216 340.93056 28.89728 383.11936-3.51232 2.92864 41.94304-43.42784 136.35584-139.10016z m461.48608 0c-31.10912-104.9088 23.97184-186.24512 165.24288-244.0192-1.024 1.65888 77.7216 340.93056-28.89728 383.11936 3.52256 2.92864-41.9328-43.42784-136.3456-139.10016z" fill="#922101" opacity=".574" p-id="5952"></path><path d="M647.69024 629.00224c-0.21504-60.29312 44.56448-83.94752 134.3488-70.95296-2.78528 3.072 6.78912 44.93312-40.51968 69.15072-11.264 5.76512-42.53696 6.36928-93.82912 1.80224z m-251.46368 0c0.22528-60.29312-44.55424-83.94752-134.33856-70.95296 2.78528 3.072-6.79936 44.93312 40.50944 69.15072 11.264 5.76512 42.53696 6.36928 93.82912 1.80224z" fill="#350000" p-id="5953"></path><path d="M743.10656 565.72928l0.04096 0.1536c0.78848 3.42016 1.20832 6.99392 1.20832 10.6496 0 23.4496-17.14176 42.82368-39.424 46.00832-3.42016 0.1536-7.2192 0.21504-11.39712 0.18432a45.93664 45.93664 0 0 1-36.7104-26.61376c10.25024-24.832 39.0144-34.95936 86.28224-30.38208z m-459.84768 0l-0.04096 0.1536a47.13472 47.13472 0 0 0-1.20832 10.6496c0 23.4496 17.14176 42.82368 39.424 46.00832 3.40992 0.1536 7.2192 0.21504 11.39712 0.18432a45.93664 45.93664 0 0 0 36.7104-26.61376c-10.26048-24.832-39.0144-34.95936-86.28224-30.38208z" fill="#923320" p-id="5954"></path><path d="M328.6528 574.72c-4.12672 10.24-6.25664 17.43872-6.38976 21.58592-0.23552 6.89152 1.8944 12.5952 6.38976 17.1008 0.768 0.54272 6.44096-5.30432 6.144-17.87904-0.1024-3.72736-2.1504-10.6496-6.144-20.80768z m372.72576 0c-4.12672 10.24-6.2464 17.43872-6.38976 21.58592-0.22528 6.89152 1.90464 12.5952 6.38976 17.1008 0.77824 0.54272 6.44096-5.30432 6.144-17.87904-0.09216-3.72736-2.14016-10.6496-6.144-20.80768z" fill="#FFFFFF" opacity=".632" p-id="5955"></path><path d="M520.42752 863.8464c37.24288 0 67.4304-27.81184 67.4304-62.1056 0-34.304-134.8608-34.304-134.8608 0s30.19776 62.1056 67.4304 62.1056z" fill="#040C12" p-id="5956"></path><path d="M520.15104 152.02304c8.86784 146.97472 40.57088 238.83776 95.10912 275.57888l2.19136 1.4336-0.24576 0.07168c-6.42048 2.53952-71.46496 73.5744-96.80896 138.2912-0.0512 0.08192-0.09216 0-0.12288-0.26624-0.04096 0.256-0.08192 0.34816-0.12288 0.26624-25.35424-64.7168-90.38848-135.75168-96.8192-138.2912l-0.24576-0.07168 2.2016-1.4336c53.71904-36.1984 85.1968-125.87008 94.45376-269.03552l0.4096-6.5536z" fill="#C74D22" p-id="5957"></path><path d="M735.15008 721.8688c49.55136 0 89.72288-17.17248 89.72288-38.3488s-40.17152-38.3488-89.72288-38.3488c-49.5616 0-89.72288 17.17248-89.72288 38.3488s40.17152 38.3488 89.72288 38.3488z m-443.89376 0c49.5616 0 89.72288-17.17248 89.72288-38.3488s-40.17152-38.3488-89.72288-38.3488-89.72288 17.17248-89.72288 38.3488 40.17152 38.3488 89.72288 38.3488z" fill="#C53028" fill-opacity=".3" p-id="5958"></path></svg>
|
After Width: | Height: | Size: 4.3 KiB |
@ -1,16 +1,17 @@
|
|||||||
const getters = {
|
const getters = {
|
||||||
sidebar: state => state.app.sidebar,
|
sidebar: state => state.app.sidebar,
|
||||||
language: state => state.app.language,
|
language: state => state.app.language,
|
||||||
size: state => state.app.size,
|
size: state => state.app.size,
|
||||||
device: state => state.app.device,
|
device: state => state.app.device,
|
||||||
visitedViews: state => state.tagsView.visitedViews,
|
visitedViews: state => state.tagsView.visitedViews,
|
||||||
cachedViews: state => state.tagsView.cachedViews,
|
cachedViews: state => state.tagsView.cachedViews,
|
||||||
token: state => state.user.token,
|
token: state => state.user.token,
|
||||||
name: state => state.user.name,
|
name: state => state.user.name,
|
||||||
introduction: state => state.user.introduction,
|
nonce: state => state.user.nonce,
|
||||||
roles: state => state.user.roles,
|
introduction: state => state.user.introduction,
|
||||||
permission_routes: state => state.permission.routes,
|
roles: state => state.user.roles,
|
||||||
errorLogs: state => state.errorLog.logs,
|
permission_routes: state => state.permission.routes,
|
||||||
email: state => state.emailView.email
|
errorLogs: state => state.errorLog.logs,
|
||||||
}
|
email: state => state.emailView.email
|
||||||
export default getters
|
}
|
||||||
|
export default getters
|
||||||
|
@ -1,127 +1,138 @@
|
|||||||
import { login, logout, getInfo } from '@/api/user'
|
import { login, logout, getInfo } from '@/api/user'
|
||||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||||
import router, { resetRouter } from '@/router'
|
import router, { resetRouter } from '@/router'
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
token: getToken(),
|
token: getToken(),
|
||||||
name: '',
|
name: '',
|
||||||
introduction: '',
|
introduction: '',
|
||||||
roles: []
|
roles: [],
|
||||||
}
|
nonce: ''
|
||||||
|
}
|
||||||
const mutations = {
|
|
||||||
SET_TOKEN: (state, token) => {
|
const mutations = {
|
||||||
state.token = token
|
SET_TOKEN: (state, token) => {
|
||||||
},
|
state.token = token
|
||||||
SET_INTRODUCTION: (state, introduction) => {
|
},
|
||||||
state.introduction = introduction
|
SET_INTRODUCTION: (state, introduction) => {
|
||||||
},
|
state.introduction = introduction
|
||||||
SET_NAME: (state, name) => {
|
},
|
||||||
state.name = name
|
SET_NAME: (state, name) => {
|
||||||
},
|
state.name = name
|
||||||
SET_ROLES: (state, roles) => {
|
},
|
||||||
state.roles = roles
|
SET_ROLES: (state, roles) => {
|
||||||
}
|
state.roles = roles
|
||||||
}
|
},
|
||||||
|
SET_NONCE: (state, nonce) => {
|
||||||
const actions = {
|
state.nonce = nonce
|
||||||
// user login
|
}
|
||||||
login({ commit }, userInfo) {
|
}
|
||||||
const { username, password } = userInfo
|
|
||||||
return new Promise((resolve, reject) => {
|
const actions = {
|
||||||
login({ username: username.trim(), password: password }).then(response => {
|
// user login
|
||||||
const { token } = response
|
login({ commit }, userInfo) {
|
||||||
commit('SET_TOKEN', token)
|
const { username, password } = userInfo
|
||||||
setToken(token)
|
return new Promise((resolve, reject) => {
|
||||||
resolve()
|
login({ username: username.trim(), password: password }).then(response => {
|
||||||
}).catch(error => {
|
const { token } = response
|
||||||
reject(error)
|
commit('SET_TOKEN', token)
|
||||||
})
|
setToken(token)
|
||||||
})
|
resolve()
|
||||||
},
|
}).catch(error => {
|
||||||
|
reject(error)
|
||||||
// get user info
|
})
|
||||||
getInfo({ commit, state }) {
|
})
|
||||||
return new Promise((resolve, reject) => {
|
},
|
||||||
getInfo().then(response => {
|
|
||||||
const { data } = response
|
// get user info
|
||||||
|
getInfo({ commit, state }) {
|
||||||
if (!data) {
|
return new Promise((resolve, reject) => {
|
||||||
reject('Verification failed, please Login again.')
|
getInfo().then(response => {
|
||||||
}
|
const { data } = response
|
||||||
|
|
||||||
const { roles } = data
|
if (!data) {
|
||||||
|
reject('Verification failed, please Login again.')
|
||||||
// roles must be a non-empty array
|
}
|
||||||
if (!roles || roles.length <= 0) {
|
|
||||||
reject('getInfo: roles must be a non-null array!')
|
const { roles } = data
|
||||||
}
|
|
||||||
|
// roles must be a non-empty array
|
||||||
commit('SET_ROLES', roles)
|
if (!roles || roles.length <= 0) {
|
||||||
// commit('SET_NAME', name)
|
reject('getInfo: roles must be a non-null array!')
|
||||||
//
|
}
|
||||||
// commit('SET_INTRODUCTION', introduction)
|
|
||||||
resolve(data)
|
commit('SET_ROLES', roles)
|
||||||
}).catch(error => {
|
// commit('SET_NAME', name)
|
||||||
reject(error)
|
//
|
||||||
})
|
// commit('SET_INTRODUCTION', introduction)
|
||||||
})
|
resolve(data)
|
||||||
},
|
}).catch(error => {
|
||||||
|
reject(error)
|
||||||
// user logout
|
})
|
||||||
logout({ commit, state, dispatch }) {
|
})
|
||||||
return new Promise((resolve, reject) => {
|
},
|
||||||
logout(state.token).then(() => {
|
|
||||||
commit('SET_TOKEN', '')
|
// user logout
|
||||||
commit('SET_ROLES', [])
|
logout({ commit, state, dispatch }) {
|
||||||
removeToken()
|
return new Promise((resolve, reject) => {
|
||||||
resetRouter()
|
logout(state.token).then(() => {
|
||||||
|
commit('SET_TOKEN', '')
|
||||||
// reset visited views and cached views
|
commit('SET_ROLES', [])
|
||||||
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
|
removeToken()
|
||||||
dispatch('tagsView/delAllViews', null, { root: true })
|
resetRouter()
|
||||||
|
|
||||||
resolve()
|
// reset visited views and cached views
|
||||||
}).catch(error => {
|
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
|
||||||
reject(error)
|
dispatch('tagsView/delAllViews', null, { root: true })
|
||||||
})
|
|
||||||
})
|
resolve()
|
||||||
},
|
}).catch(error => {
|
||||||
|
reject(error)
|
||||||
// remove token
|
})
|
||||||
resetToken({ commit }) {
|
})
|
||||||
return new Promise(resolve => {
|
},
|
||||||
commit('SET_TOKEN', '')
|
|
||||||
commit('SET_ROLES', [])
|
// remove token
|
||||||
removeToken()
|
resetToken({ commit }) {
|
||||||
resolve()
|
return new Promise(resolve => {
|
||||||
})
|
commit('SET_TOKEN', '')
|
||||||
},
|
commit('SET_ROLES', [])
|
||||||
|
removeToken()
|
||||||
// dynamically modify permissions
|
resolve()
|
||||||
async changeRoles({ commit, dispatch }, role) {
|
})
|
||||||
const token = role + '-token'
|
},
|
||||||
|
// get nonce
|
||||||
commit('SET_TOKEN', token)
|
getNonce({ commit }, nonce) {
|
||||||
setToken(token)
|
return new Promise(resolve => {
|
||||||
|
commit('SET_NONCE', nonce)
|
||||||
const { roles } = await dispatch('getInfo')
|
resolve()
|
||||||
|
})
|
||||||
resetRouter()
|
},
|
||||||
|
|
||||||
// generate accessible routes map based on roles
|
// dynamically modify permissions
|
||||||
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
|
async changeRoles({ commit, dispatch }, role) {
|
||||||
// dynamically add accessible routes
|
const token = role + '-token'
|
||||||
router.addRoutes(accessRoutes)
|
|
||||||
|
commit('SET_TOKEN', token)
|
||||||
// reset visited views and cached views
|
setToken(token)
|
||||||
dispatch('tagsView/delAllViews', null, { root: true })
|
|
||||||
}
|
const { roles } = await dispatch('getInfo')
|
||||||
}
|
|
||||||
|
resetRouter()
|
||||||
export default {
|
|
||||||
namespaced: true,
|
// generate accessible routes map based on roles
|
||||||
state,
|
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
|
||||||
mutations,
|
// dynamically add accessible routes
|
||||||
actions
|
router.addRoutes(accessRoutes)
|
||||||
}
|
|
||||||
|
// reset visited views and cached views
|
||||||
|
dispatch('tagsView/delAllViews', null, { root: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
@ -1,22 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="social-signup-container">
|
<div class="social-signup-container">
|
||||||
<div class="sign-btn" @click="wechatHandleClick('wechat')">
|
<!-- <div class="sign-btn" @click="wechatHandleClick('wechat')">-->
|
||||||
<span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon" /></span>
|
<!-- <span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon" /></span>-->
|
||||||
WeChat
|
<!-- WeChat-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="sign-btn" @click="tencentHandleClick('tencent')">
|
<!-- <div class="sign-btn" @click="tencentHandleClick('tencent')">-->
|
||||||
<span class="qq-svg-container"><svg-icon icon-class="qq" class="icon" /></span>
|
<!-- <span class="qq-svg-container"><svg-icon icon-class="qq" class="icon" /></span>-->
|
||||||
QQ
|
<!-- QQ-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<div class="sign-btn" @click="marketHandleClick('MetaMask')">
|
||||||
|
<span class="qq-svg-container"><svg-icon icon-class="MetaMask" class="icon" /></span>
|
||||||
|
Market
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import openWindow from '@/utils/open-window'
|
// import openWindow from '@/utils/open-window'
|
||||||
|
import Web3 from 'web3'
|
||||||
|
import { getNonce, metamaskLogin } from '@/api/user'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SocialSignin',
|
name: 'SocialSignin',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
provider: '',
|
||||||
|
web3: '',
|
||||||
|
chainId: '',
|
||||||
|
account: '',
|
||||||
|
redirect: undefined,
|
||||||
|
otherQuery: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route: {
|
||||||
|
handler: function(route) {
|
||||||
|
const query = route.query
|
||||||
|
if (query) {
|
||||||
|
this.redirect = query.redirect
|
||||||
|
this.otherQuery = this.getOtherQuery(query)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getOtherQuery(query) {
|
||||||
|
return Object.keys(query).reduce((acc, cur) => {
|
||||||
|
if (cur !== 'redirect') {
|
||||||
|
acc[cur] = query[cur]
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
},
|
||||||
wechatHandleClick(thirdpart) {
|
wechatHandleClick(thirdpart) {
|
||||||
alert('ok')
|
alert('ok')
|
||||||
// this.$store.commit('SET_AUTH_TYPE', thirdpart)
|
// this.$store.commit('SET_AUTH_TYPE', thirdpart)
|
||||||
@ -32,6 +68,131 @@ export default {
|
|||||||
// const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect')
|
// const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect')
|
||||||
// const url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirect_uri
|
// const url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirect_uri
|
||||||
// openWindow(url, thirdpart, 540, 540)
|
// openWindow(url, thirdpart, 540, 540)
|
||||||
|
},
|
||||||
|
async marketHandleClick(thirdpart) {
|
||||||
|
if (!this.hasMetamask()) {
|
||||||
|
this.$message({
|
||||||
|
message: '请先安装MetaMask插件',
|
||||||
|
type: 'error',
|
||||||
|
duration: 1200
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.provider = await this.connectMetaMask()
|
||||||
|
if (!this.provider) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.web3 = new Web3(this.provider)
|
||||||
|
this.chainId = await this.web3.eth.getChainId()
|
||||||
|
const accounts = await this.web3.eth.getAccounts()
|
||||||
|
if (accounts && accounts.length > 0) {
|
||||||
|
this.account = accounts[0]
|
||||||
|
}
|
||||||
|
await getNonce(this.account).then(response => {
|
||||||
|
if (response.code === 0) {
|
||||||
|
this.$store.dispatch('user/getNonce', response.data)
|
||||||
|
} else {
|
||||||
|
this.$message({
|
||||||
|
message: response.message,
|
||||||
|
type: 'error',
|
||||||
|
duration: 1200
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('Api getNonce Error:' + err)
|
||||||
|
})
|
||||||
|
await this.metaMaskLogin()
|
||||||
|
},
|
||||||
|
hasMetamask() {
|
||||||
|
if (typeof window.ethereum !== 'undefined') {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
connectMetaMask() {
|
||||||
|
var provider = window.ethereum
|
||||||
|
try {
|
||||||
|
provider.request({ method: 'eth_requestAccounts' })
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code === -32002) {
|
||||||
|
throw new Error('MeatMask not login, Open MeatMask and login first')
|
||||||
|
} else {
|
||||||
|
throw new Error('User Rejected')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return provider
|
||||||
|
},
|
||||||
|
async metaMaskLogin() {
|
||||||
|
const account = this.account
|
||||||
|
const net_id = this.chainId
|
||||||
|
const nonce = this.$store.getters.nonce
|
||||||
|
const tips = 'This signature is only used for verify your account'
|
||||||
|
const signMsg = {
|
||||||
|
tips,
|
||||||
|
nonce
|
||||||
|
}
|
||||||
|
const EIP721_DOMAIN_DATA = [
|
||||||
|
{ name: 'name', type: 'string' },
|
||||||
|
{ name: 'version', type: 'string' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const signObj = {
|
||||||
|
types: {
|
||||||
|
EIP712Domain: EIP721_DOMAIN_DATA,
|
||||||
|
set: [
|
||||||
|
{ name: 'tips', type: 'string' },
|
||||||
|
{ name: 'nonce', type: 'string' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
primaryType: 'set',
|
||||||
|
domain: {
|
||||||
|
name: 'Auth',
|
||||||
|
version: '1'
|
||||||
|
},
|
||||||
|
message: signMsg
|
||||||
|
}
|
||||||
|
const signature = await this.signData(signObj, account)
|
||||||
|
const authData = {
|
||||||
|
account,
|
||||||
|
nonce,
|
||||||
|
signature,
|
||||||
|
tips,
|
||||||
|
net_id
|
||||||
|
}
|
||||||
|
metamaskLogin(authData).then(response => {
|
||||||
|
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
|
||||||
|
console.log(response)
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('Api getNonce Error:' + err)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async signData(signObj, signer) {
|
||||||
|
const msgParams = JSON.stringify(signObj)
|
||||||
|
const from = signer
|
||||||
|
const params = [from, msgParams]
|
||||||
|
const result = await this.sendCmd(
|
||||||
|
'eth_signTypedData_v4',
|
||||||
|
params,
|
||||||
|
from
|
||||||
|
)
|
||||||
|
return result.result
|
||||||
|
},
|
||||||
|
async sendCmd(method, params, from) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.web3.currentProvider.sendAsync({
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
from
|
||||||
|
}, async function(err, result) {
|
||||||
|
if (err) {
|
||||||
|
reject && reject(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resolve && resolve(result)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,281 +1,290 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
||||||
|
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<h3 class="title">Login Form</h3>
|
<h3 class="title">Login Form</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<span class="svg-container">
|
<span class="svg-container">
|
||||||
<svg-icon icon-class="user" />
|
<svg-icon icon-class="user" />
|
||||||
</span>
|
</span>
|
||||||
<el-input
|
<el-input
|
||||||
ref="username"
|
ref="username"
|
||||||
v-model="loginForm.username"
|
v-model="loginForm.username"
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
name="username"
|
name="username"
|
||||||
type="text"
|
type="text"
|
||||||
tabindex="1"
|
tabindex="1"
|
||||||
autocomplete="on"
|
autocomplete="on"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
|
<el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password">
|
||||||
<span class="svg-container">
|
<span class="svg-container">
|
||||||
<svg-icon icon-class="password" />
|
<svg-icon icon-class="password" />
|
||||||
</span>
|
</span>
|
||||||
<el-input
|
<el-input
|
||||||
:key="passwordType"
|
:key="passwordType"
|
||||||
ref="password"
|
ref="password"
|
||||||
v-model="loginForm.password"
|
v-model="loginForm.password"
|
||||||
:type="passwordType"
|
:type="passwordType"
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
name="password"
|
name="password"
|
||||||
tabindex="2"
|
tabindex="2"
|
||||||
autocomplete="on"
|
autocomplete="on"
|
||||||
@keyup.native="checkCapslock"
|
@keyup.native="checkCapslock"
|
||||||
@blur="capsTooltip = false"
|
@blur="capsTooltip = false"
|
||||||
@keyup.enter.native="handleLogin"
|
@keyup.enter.native="handleLogin"
|
||||||
/>
|
/>
|
||||||
<span class="show-pwd" @click="showPwd">
|
<span class="show-pwd" @click="showPwd">
|
||||||
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
|
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
|
||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
|
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
|
||||||
</el-form>
|
<div style="position:relative;margin-top: 30px">
|
||||||
|
<el-button class="thirdparty-button" type="primary" @click="showDialog=true">
|
||||||
</div>
|
Or connect with
|
||||||
</template>
|
</el-button>
|
||||||
|
</div>
|
||||||
<script>
|
</el-form>
|
||||||
import { validUsername } from '@/utils/validate'
|
<el-dialog title="Or connect with" :visible.sync="showDialog">
|
||||||
export default {
|
<social-sign />
|
||||||
name: 'Login',
|
</el-dialog>
|
||||||
components: {},
|
</div>
|
||||||
data() {
|
</template>
|
||||||
const validateUsername = (rule, value, callback) => {
|
|
||||||
if (!validUsername(value)) {
|
<script>
|
||||||
callback(new Error('Please enter the correct user name'))
|
import { validUsername } from '@/utils/validate'
|
||||||
} else {
|
import SocialSign from './components/SocialSignin'
|
||||||
callback()
|
|
||||||
}
|
export default {
|
||||||
}
|
name: 'Login',
|
||||||
const validatePassword = (rule, value, callback) => {
|
components: { SocialSign },
|
||||||
if (value.length < 5) {
|
data() {
|
||||||
callback(new Error('The password can not be less than 6 digits'))
|
const validateUsername = (rule, value, callback) => {
|
||||||
} else {
|
if (!validUsername(value)) {
|
||||||
callback()
|
callback(new Error('Please enter the correct user name'))
|
||||||
}
|
} else {
|
||||||
}
|
callback()
|
||||||
return {
|
}
|
||||||
loginForm: {
|
}
|
||||||
username: 'admin',
|
const validatePassword = (rule, value, callback) => {
|
||||||
password: 'admin'
|
if (value.length < 5) {
|
||||||
},
|
callback(new Error('The password can not be less than 6 digits'))
|
||||||
loginRules: {
|
} else {
|
||||||
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
|
callback()
|
||||||
password: [{ required: true, trigger: 'blur', validator: validatePassword }]
|
}
|
||||||
},
|
}
|
||||||
passwordType: 'password',
|
return {
|
||||||
capsTooltip: false,
|
loginForm: {
|
||||||
loading: false,
|
username: 'admin',
|
||||||
showDialog: false,
|
password: 'admin'
|
||||||
redirect: undefined,
|
},
|
||||||
otherQuery: {}
|
loginRules: {
|
||||||
}
|
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
|
||||||
},
|
password: [{ required: true, trigger: 'blur', validator: validatePassword }]
|
||||||
watch: {
|
},
|
||||||
$route: {
|
passwordType: 'password',
|
||||||
handler: function(route) {
|
capsTooltip: false,
|
||||||
const query = route.query
|
loading: false,
|
||||||
if (query) {
|
showDialog: false,
|
||||||
this.redirect = query.redirect
|
redirect: undefined,
|
||||||
this.otherQuery = this.getOtherQuery(query)
|
otherQuery: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
immediate: true
|
watch: {
|
||||||
}
|
$route: {
|
||||||
},
|
handler: function(route) {
|
||||||
created() {
|
const query = route.query
|
||||||
|
if (query) {
|
||||||
},
|
this.redirect = query.redirect
|
||||||
mounted() {
|
this.otherQuery = this.getOtherQuery(query)
|
||||||
if (this.loginForm.username === '') {
|
}
|
||||||
this.$refs.username.focus()
|
},
|
||||||
} else if (this.loginForm.password === '') {
|
immediate: true
|
||||||
this.$refs.password.focus()
|
}
|
||||||
}
|
},
|
||||||
},
|
created() {
|
||||||
destroyed() {
|
|
||||||
|
},
|
||||||
},
|
mounted() {
|
||||||
methods: {
|
if (this.loginForm.username === '') {
|
||||||
checkCapslock(e) {
|
this.$refs.username.focus()
|
||||||
const { key } = e
|
} else if (this.loginForm.password === '') {
|
||||||
this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
|
this.$refs.password.focus()
|
||||||
},
|
}
|
||||||
showPwd() {
|
},
|
||||||
if (this.passwordType === 'password') {
|
destroyed() {
|
||||||
this.passwordType = ''
|
|
||||||
} else {
|
},
|
||||||
this.passwordType = 'password'
|
methods: {
|
||||||
}
|
checkCapslock(e) {
|
||||||
this.$nextTick(() => {
|
const { key } = e
|
||||||
this.$refs.password.focus()
|
this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
|
||||||
})
|
},
|
||||||
},
|
showPwd() {
|
||||||
handleLogin() {
|
if (this.passwordType === 'password') {
|
||||||
this.$refs.loginForm.validate(valid => {
|
this.passwordType = ''
|
||||||
if (valid) {
|
} else {
|
||||||
this.loading = true
|
this.passwordType = 'password'
|
||||||
this.$store.dispatch('user/login', this.loginForm)
|
}
|
||||||
.then(() => {
|
this.$nextTick(() => {
|
||||||
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
|
this.$refs.password.focus()
|
||||||
this.loading = false
|
})
|
||||||
})
|
},
|
||||||
.catch(() => {
|
handleLogin() {
|
||||||
this.loading = false
|
this.$refs.loginForm.validate(valid => {
|
||||||
})
|
if (valid) {
|
||||||
} else {
|
this.loading = true
|
||||||
console.log('error submit!!')
|
this.$store.dispatch('user/login', this.loginForm)
|
||||||
return false
|
.then(() => {
|
||||||
}
|
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
|
||||||
})
|
this.loading = false
|
||||||
},
|
})
|
||||||
getOtherQuery(query) {
|
.catch(() => {
|
||||||
return Object.keys(query).reduce((acc, cur) => {
|
this.loading = false
|
||||||
if (cur !== 'redirect') {
|
})
|
||||||
acc[cur] = query[cur]
|
} else {
|
||||||
}
|
console.log('error submit!!')
|
||||||
return acc
|
return false
|
||||||
}, {})
|
}
|
||||||
}
|
})
|
||||||
}
|
},
|
||||||
}
|
getOtherQuery(query) {
|
||||||
</script>
|
return Object.keys(query).reduce((acc, cur) => {
|
||||||
|
if (cur !== 'redirect') {
|
||||||
<style lang="scss">
|
acc[cur] = query[cur]
|
||||||
/* 修复input 背景不协调 和光标变色 */
|
}
|
||||||
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
return acc
|
||||||
|
}, {})
|
||||||
$bg:#283443;
|
}
|
||||||
$light_gray:#fff;
|
}
|
||||||
$cursor: #fff;
|
}
|
||||||
|
</script>
|
||||||
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
|
||||||
.login-container .el-input input {
|
<style lang="scss">
|
||||||
color: $cursor;
|
/* 修复input 背景不协调 和光标变色 */
|
||||||
}
|
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
|
||||||
}
|
|
||||||
|
$bg:#283443;
|
||||||
/* reset element-ui css */
|
$light_gray:#fff;
|
||||||
.login-container {
|
$cursor: #fff;
|
||||||
.el-input {
|
|
||||||
display: inline-block;
|
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
||||||
height: 47px;
|
.login-container .el-input input {
|
||||||
width: 85%;
|
color: $cursor;
|
||||||
|
}
|
||||||
input {
|
}
|
||||||
background: transparent;
|
|
||||||
border: 0px;
|
/* reset element-ui css */
|
||||||
-webkit-appearance: none;
|
.login-container {
|
||||||
border-radius: 0px;
|
.el-input {
|
||||||
padding: 12px 5px 12px 15px;
|
display: inline-block;
|
||||||
color: $light_gray;
|
height: 47px;
|
||||||
height: 47px;
|
width: 85%;
|
||||||
caret-color: $cursor;
|
|
||||||
|
input {
|
||||||
&:-webkit-autofill {
|
background: transparent;
|
||||||
box-shadow: 0 0 0px 1000px $bg inset !important;
|
border: 0px;
|
||||||
-webkit-text-fill-color: $cursor !important;
|
-webkit-appearance: none;
|
||||||
}
|
border-radius: 0px;
|
||||||
}
|
padding: 12px 5px 12px 15px;
|
||||||
}
|
color: $light_gray;
|
||||||
|
height: 47px;
|
||||||
.el-form-item {
|
caret-color: $cursor;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
background: rgba(0, 0, 0, 0.1);
|
&:-webkit-autofill {
|
||||||
border-radius: 5px;
|
box-shadow: 0 0 0px 1000px $bg inset !important;
|
||||||
color: #454545;
|
-webkit-text-fill-color: $cursor !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
}
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
.el-form-item {
|
||||||
$bg:#2d3a4b;
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
$dark_gray:#889aa4;
|
background: rgba(0, 0, 0, 0.1);
|
||||||
$light_gray:#eee;
|
border-radius: 5px;
|
||||||
|
color: #454545;
|
||||||
.login-container {
|
}
|
||||||
min-height: 100%;
|
}
|
||||||
width: 100%;
|
</style>
|
||||||
background-color: $bg;
|
|
||||||
overflow: hidden;
|
<style lang="scss" scoped>
|
||||||
|
$bg:#2d3a4b;
|
||||||
.login-form {
|
$dark_gray:#889aa4;
|
||||||
position: relative;
|
$light_gray:#eee;
|
||||||
width: 520px;
|
|
||||||
max-width: 100%;
|
.login-container {
|
||||||
padding: 160px 35px 0;
|
min-height: 100%;
|
||||||
margin: 0 auto;
|
width: 100%;
|
||||||
overflow: hidden;
|
background-color: $bg;
|
||||||
}
|
overflow: hidden;
|
||||||
|
|
||||||
.tips {
|
.login-form {
|
||||||
font-size: 14px;
|
position: relative;
|
||||||
color: #fff;
|
width: 520px;
|
||||||
margin-bottom: 10px;
|
max-width: 100%;
|
||||||
|
padding: 160px 35px 0;
|
||||||
span {
|
margin: 0 auto;
|
||||||
&:first-of-type {
|
overflow: hidden;
|
||||||
margin-right: 16px;
|
}
|
||||||
}
|
|
||||||
}
|
.tips {
|
||||||
}
|
font-size: 14px;
|
||||||
|
color: #fff;
|
||||||
.svg-container {
|
margin-bottom: 10px;
|
||||||
padding: 6px 5px 6px 15px;
|
|
||||||
color: $dark_gray;
|
span {
|
||||||
vertical-align: middle;
|
&:first-of-type {
|
||||||
width: 30px;
|
margin-right: 16px;
|
||||||
display: inline-block;
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.title-container {
|
|
||||||
position: relative;
|
.svg-container {
|
||||||
|
padding: 6px 5px 6px 15px;
|
||||||
.title {
|
color: $dark_gray;
|
||||||
font-size: 26px;
|
vertical-align: middle;
|
||||||
color: $light_gray;
|
width: 30px;
|
||||||
margin: 0px auto 40px auto;
|
display: inline-block;
|
||||||
text-align: center;
|
}
|
||||||
font-weight: bold;
|
|
||||||
}
|
.title-container {
|
||||||
}
|
position: relative;
|
||||||
|
|
||||||
.show-pwd {
|
.title {
|
||||||
position: absolute;
|
font-size: 26px;
|
||||||
right: 10px;
|
color: $light_gray;
|
||||||
top: 7px;
|
margin: 0px auto 40px auto;
|
||||||
font-size: 16px;
|
text-align: center;
|
||||||
color: $dark_gray;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
}
|
||||||
user-select: none;
|
}
|
||||||
}
|
|
||||||
|
.show-pwd {
|
||||||
.thirdparty-button {
|
position: absolute;
|
||||||
position: absolute;
|
right: 10px;
|
||||||
right: 0;
|
top: 7px;
|
||||||
bottom: 6px;
|
font-size: 16px;
|
||||||
}
|
color: $dark_gray;
|
||||||
|
cursor: pointer;
|
||||||
@media only screen and (max-width: 470px) {
|
user-select: none;
|
||||||
.thirdparty-button {
|
}
|
||||||
display: none;
|
|
||||||
}
|
.thirdparty-button {
|
||||||
}
|
position: absolute;
|
||||||
}
|
right: 0;
|
||||||
</style>
|
bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 470px) {
|
||||||
|
.thirdparty-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user