9 files modified
5 files added
| New file |
| | |
| | | import request from '@/router/axios'; |
| | | import website from "@/config/website"; |
| | | |
| | | export const loginByUsername = (tenantId, username, password, type, key, code) => request({ |
| | | url: '/api/blade-auth/oauth/token', |
| | | method: 'post', |
| | | headers: { |
| | | 'Tenant-Id': tenantId, |
| | | 'Captcha-Key': key, |
| | | 'Captcha-Code': code, |
| | | }, |
| | | params: { |
| | | tenantId, |
| | | username, |
| | | password, |
| | | grant_type: (website.captchaMode ? "captcha" : "password"), |
| | | scope: "all", |
| | | type |
| | | } |
| | | }); |
| | | |
| | | export const loginBySocial = (tenantId, source, code, state) => request({ |
| | | url: '/api/blade-auth/oauth/token', |
| | | method: 'post', |
| | | headers: { |
| | | 'Tenant-Id': tenantId |
| | | }, |
| | | params: { |
| | | tenantId, |
| | | source, |
| | | code, |
| | | state, |
| | | grant_type: "social", |
| | | scope: "all", |
| | | } |
| | | }) |
| | | |
| | | export const refreshToken = (refresh_token, tenantId) => request({ |
| | | url: '/api/blade-auth/oauth/token', |
| | | method: 'post', |
| | | headers: { |
| | | 'Tenant-Id': tenantId |
| | | }, |
| | | params: { |
| | | tenantId, |
| | | refresh_token, |
| | | grant_type: "refresh_token", |
| | | scope: "all", |
| | | } |
| | | }); |
| | | |
| | | export const getButtons = () => request({ |
| | | url: '/api/blade-system/menu/buttons', |
| | | method: 'get' |
| | | }); |
| | | |
| | | export const getCaptcha = () => request({ |
| | | url: '/api/blade-auth/oauth/captcha', |
| | | method: 'get' |
| | | }); |
| | | |
| | | export const logout = () => request({ |
| | | url: '/api/blade-auth/oauth/logout', |
| | | method: 'get' |
| | | }); |
| | | |
| | | export const getUserInfo = () => request({ |
| | | url: '/api/blade-auth/oauth/user-info', |
| | | method: 'get' |
| | | }); |
| | | |
| | | export const sendLogs = (list) => request({ |
| | | url: '/api/blade-auth/oauth/logout', |
| | | method: 'post', |
| | | data: list |
| | | }); |
| | | |
| | | export const clearCache = () => request({ |
| | | url: '/api/blade-auth/oauth/clear-cache', |
| | | method: 'get' |
| | | }); |
| New file |
| | |
| | | /** |
| | | * 全局配置文件 |
| | | */ |
| | | |
| | | var fistPage = { |
| | | label: "首页", |
| | | value: "/layout/home", |
| | | params: {}, |
| | | query: {}, |
| | | meta: { |
| | | i18n: 'dashboard' |
| | | }, |
| | | group: [], |
| | | close: false |
| | | } |
| | | |
| | | export default { |
| | | title: "保安员考试大屏", |
| | | logo: "S", |
| | | key: 'saber', |
| | | indexTitle: '保安员考试大屏', |
| | | clientId: 'saber', |
| | | clientSecret: 'saber_secret', |
| | | tenantMode: true, |
| | | tenantId: "000000", |
| | | captchaMode: false, |
| | | lockPage: '/lock', |
| | | tokenTime: 3000, |
| | | tokenHeader: 'Blade-Auth', |
| | | statusWhiteList: [], |
| | | isFirstPage: false, |
| | | fistPage: fistPage, |
| | | menu: { |
| | | iconDefault: 'iconfont icon-caidan', |
| | | props: { |
| | | label: 'name', |
| | | path: 'path', |
| | | icon: 'source', |
| | | children: 'children' |
| | | } |
| | | }, |
| | | authUrl: 'http://localhost/blade-auth/oauth/render', |
| | | } |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-08-18 16:16:10 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-05-04 11:09:35 |
| | | * @FilePath: \web\bigScreen\src\permission.js |
| | | * @Description: 路由守卫 |
| | | * |
| | | * Copyright (c) 2022 by shuishen 1109946754@qq.com, All Rights Reserved. |
| | | */ |
| | | import router from "@/router/page/index"; |
| | | import store from './store' |
| | | import { getToken } from "./utils/auth"; |
| | | import NProgress from 'nprogress' |
| | | import 'nprogress/nprogress.css' |
| | | |
| | | NProgress.configure({showSpinner: false}); |
| | | |
| | | router.beforeEach((to, from, next) => { |
| | | // window._axiosPromiseArr && window._axiosPromiseArr.length && window._axiosPromiseArr.forEach((ele, index) => { |
| | | // ele.cancel() |
| | | // delete window._axiosPromiseArr[index] |
| | | // console.clear() |
| | | // }) |
| | | |
| | | const meta = to.meta || {}; |
| | | next(); |
| | | |
| | | // if (getToken()) { |
| | | // if (to.path === '/login') { // 如果登录成功访问登录页跳转到主页 |
| | | // next({ |
| | | // path: '/' |
| | | // }) |
| | | // } else { |
| | | // next() |
| | | // } |
| | | // } else { |
| | | // // 判断是否需要认证,没有登录访问去登录页 |
| | | // if (meta.isAuth === false) { |
| | | // next() |
| | | // } else { |
| | | // window.open('https://sk.hubeishuiyi.cn/business/', "_self") |
| | | // } |
| | | // } |
| | | if (getToken()) { |
| | | if (to.path === '/login') { |
| | | next({ path: '/layout/home' }) |
| | | } else { |
| | | if (store.getters.token.length === 0) { |
| | | store.dispatch('FedLogOut').then(() => { |
| | | next({ path: '/login' }) |
| | | }) |
| | | } else { |
| | | next() |
| | | } |
| | | } |
| | | } else { |
| | | if (meta.isAuth === false) { |
| | | next() |
| | | } else { |
| | | next('/login') |
| | | } |
| | | } |
| | | }); |
| | | |
| | | router.afterEach(() => { |
| | | NProgress.done(); |
| | | }); |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-07-29 15:19:13 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-04-21 10:16:58 |
| | | * @FilePath: \web\bigScreen\src\router\axios.js |
| | | * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE |
| | | */ |
| | | /** |
| | | * 全站http配置 |
| | | * |
| | | * axios参数说明 |
| | | * isSerialize是否开启form表单提交 |
| | | * isToken是否需要token |
| | | */ |
| | | import axios from "axios"; |
| | | import store from '@/store/'; |
| | | import router from '@/router/page'; |
| | | import { getToken } from '@/utils/auth'; |
| | | import { MessageBox } from 'element-ui'; |
| | | import website from '@/config/website'; |
| | | import { Base64 } from 'js-base64'; |
| | | import NProgress from 'nprogress'; |
| | | import 'nprogress/nprogress.css'; |
| | | |
| | | // 调用后台管理的 |
| | | const service = axios.create({ |
| | | timeout: 600000, // request timeout |
| | | timeout: 600000, |
| | | }); |
| | | |
| | | // 返回其他状态码 |
| | | service.defaults.validateStatus = function (status) { |
| | | return status >= 200 && status <= 500; |
| | | }; |
| | | |
| | | // 跨域请求,允许保存cookie |
| | | // service.defaults.withCredentials = true |
| | | service.defaults.withCredentials = true; |
| | | |
| | | // http request拦截 |
| | | NProgress.configure({ |
| | | showSpinner: false |
| | | }); |
| | | |
| | | service.interceptors.request.use( |
| | | (config) => { |
| | | if (config.apiKey) { |
| | | config.headers["apikey"] = |
| | | "F1DBECD719108635189480CF60E6553ADB3109616426BD537F25A430DFC613B491A025C4A51E77FD08C6E5B7CBE05917A461286E7B6D69F1AB1B14F946149D2065B0C675F8FEDF4B9B05C1496881BC5A"; |
| | | NProgress.start(); |
| | | const meta = (config.meta || {}); |
| | | const isToken = meta.isToken === false; |
| | | config.headers['Authorization'] = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`; |
| | | |
| | | if (getToken() && !isToken) { |
| | | config.headers[website.tokenHeader] = 'bearer ' + getToken() |
| | | } |
| | | |
| | | if (config.text === true) { |
| | | config.headers["Content-Type"] = "text/plain"; |
| | | } |
| | | |
| | | config.cancelToken = new axios.CancelToken((cancel) => { |
| | | window._axiosPromiseArr.push({ cancel }); |
| | | }); |
| | |
| | | } |
| | | ); |
| | | |
| | | // http response 拦截 |
| | | service.interceptors.response.use( |
| | | (res) => { |
| | | const code = res.data.code; |
| | | NProgress.done(); |
| | | const status = res.data.code || res.status; |
| | | const statusWhiteList = website.statusWhiteList || []; |
| | | const message = res.data.msg || res.data.error_description || '未知错误'; |
| | | |
| | | if (statusWhiteList.includes(status)) return Promise.reject(res); |
| | | |
| | | if (status === 401) { |
| | | store.dispatch('FedLogOut').then(() => { |
| | | router.push({ path: '/login' }); |
| | | }); |
| | | } |
| | | |
| | | if (status !== 200 && status !== 201) { |
| | | MessageBox.alert(message); |
| | | return Promise.reject(new Error(message)) |
| | | } |
| | | |
| | | if (res.data.resultList && res.data.resultList.length > 0) { |
| | | res.data.resultList = res.data.resultList.map((item) => { |
| | |
| | | return res; |
| | | }, |
| | | (error) => { |
| | | NProgress.done(); |
| | | return Promise.reject(new Error(error)); |
| | | } |
| | | ); |
| | | |
| | | export default service; |
| | | export default service; |
| | |
| | | /* |
| | | * @Author: Morpheus |
| | | * @Date: 2021-04-30 14:12:09 |
| | | * @Last Modified by: Morpheus |
| | | * @Last Modified time: 2022-07-29 09:15:23 |
| | | */ |
| | | |
| | | import Vue from 'vue' |
| | | import VueRouter from 'vue-router' |
| | | |
| | |
| | | const home = () => import('../../views/home/index.vue') |
| | | const home_02 = () => import('../../views/home/index_02.vue') |
| | | const home_03 = () => import('../../views/home/index_03.vue') |
| | | const login = () => import('../../views/login/index.vue') |
| | | |
| | | const routes = [ |
| | | { |
| | | path: '/', |
| | | redirect: '/layout' |
| | | redirect: '/login' |
| | | }, |
| | | { |
| | | path: '/login', |
| | | meta: { |
| | | title: '登录', |
| | | isAuth: false |
| | | }, |
| | | component: login, |
| | | }, |
| | | { |
| | | path: '/layout', |
| | |
| | | } |
| | | ] |
| | | }, |
| | | |
| | | { |
| | | path: '/ssjk', |
| | | meta: { |
| | |
| | | }, |
| | | component: () => import('../../views/ywsys/index.vue'), |
| | | }, |
| | | |
| | | { |
| | | path: '/csmodel', |
| | | meta: { |
| | |
| | | routes |
| | | }) |
| | | |
| | | export default router |
| | | export default router |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2023-03-02 16:36:47 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-04-04 10:54:12 |
| | | * @FilePath: \srs-police-affairs\src\store\getters.js |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | */ |
| | | const getters = { |
| | | examId: (state) => state.user.examId, |
| | | isShowVideoDialog: (state) => state.user.isShowVideoDialog, |
| | | token: (state) => state.user.token, |
| | | userInfo: (state) => state.user.userInfo, |
| | | tenantId: (state) => state.user.tenantId, |
| | | permission: (state) => state.user.permission, |
| | | roles: (state) => state.user.roles, |
| | | menu: (state) => state.user.menu, |
| | | menuAll: (state) => state.user.menuAll, |
| | | } |
| | | |
| | | export default getters |
| | | export default getters |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-12-27 09:33:01 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2023-04-02 12:18:26 |
| | | * @FilePath: \srs-police-affairs\src\store\modules\user.js |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. |
| | | */ |
| | | import { setToken, setRefreshToken, removeToken, removeRefreshToken } from '@/utils/auth' |
| | | import { Message } from 'element-ui' |
| | | import { setStore, getStore } from '@/utils/store' |
| | | import { isURL, validatenull } from '@/utils/validate' |
| | | import { deepClone } from '@/utils/tool' |
| | | import website from '@/config/website' |
| | | import { loginByUsername, loginBySocial, getUserInfo, logout, refreshToken, getButtons } from '@/api/user' |
| | | import md5 from 'js-md5' |
| | | |
| | | const user = { |
| | | state: { |
| | | examId: '', |
| | | isShowVideoDialog: '' |
| | | }, |
| | | actions: { |
| | | |
| | | }, |
| | | mutations: { |
| | | SET_EXAMID: (state, active) => { |
| | | state.examId = active |
| | | }, |
| | | |
| | | SET_ISSHOWVIDEODIALOG: (state, active) => { |
| | | state.isShowVideoDialog = active |
| | | }, |
| | | } |
| | | function addPath(ele, first) { |
| | | const menu = website.menu; |
| | | const propsConfig = menu.props; |
| | | const propsDefault = { |
| | | label: propsConfig.label || 'name', |
| | | path: propsConfig.path || 'path', |
| | | icon: propsConfig.icon || 'icon', |
| | | children: propsConfig.children || 'children' |
| | | } |
| | | const icon = ele[propsDefault.icon]; |
| | | ele[propsDefault.icon] = validatenull(icon) ? menu.iconDefault : icon; |
| | | const isChild = ele[propsDefault.children] && ele[propsDefault.children].length !== 0; |
| | | if (!isChild) ele[propsDefault.children] = []; |
| | | if (!isChild && first && !isURL(ele[propsDefault.path])) { |
| | | ele[propsDefault.path] = ele[propsDefault.path] + '/index' |
| | | } else { |
| | | ele[propsDefault.children].forEach(child => { |
| | | addPath(child); |
| | | }) |
| | | } |
| | | } |
| | | |
| | | export default user |
| | | const user = { |
| | | state: { |
| | | tenantId: getStore({ name: 'tenantId' }) || '', |
| | | userInfo: getStore({ name: 'userInfo' }) || [], |
| | | permission: getStore({ name: 'permission' }) || {}, |
| | | roles: [], |
| | | menuId: {}, |
| | | menu: getStore({ name: 'menu' }) || [], |
| | | menuAll: getStore({ name: 'menuAll' }) || [], |
| | | token: getStore({ name: 'token' }) || '', |
| | | refreshToken: getStore({ name: 'refreshToken' }) || '', |
| | | hideHome: false, |
| | | examId: '', |
| | | isShowVideoDialog: '' |
| | | }, |
| | | actions: { |
| | | LoginByUsername({ commit }, userInfo) { |
| | | return new Promise((resolve, reject) => { |
| | | loginByUsername(userInfo.tenantId, userInfo.username, md5(userInfo.password), userInfo.type, userInfo.key, userInfo.code).then(res => { |
| | | const data = res.data; |
| | | if (data.error_description) { |
| | | Message({ |
| | | message: data.error_description, |
| | | type: 'error' |
| | | }) |
| | | } else { |
| | | commit('SET_TOKEN', data.access_token); |
| | | commit('SET_REFRESH_TOKEN', data.refresh_token); |
| | | commit('SET_TENANT_ID', data.tenant_id); |
| | | commit('SET_USER_INFO', data); |
| | | commit('DEL_ALL_TAG'); |
| | | commit('CLEAR_LOCK'); |
| | | } |
| | | resolve(data); |
| | | }).catch(error => { |
| | | reject(error); |
| | | }) |
| | | }) |
| | | }, |
| | | LoginByPhone({ commit }, userInfo) { |
| | | return new Promise((resolve) => { |
| | | loginByUsername(userInfo.phone, userInfo.code).then(res => { |
| | | const data = res.data.data; |
| | | commit('SET_TOKEN', data); |
| | | commit('DEL_ALL_TAG'); |
| | | commit('CLEAR_LOCK'); |
| | | resolve(); |
| | | }) |
| | | }) |
| | | }, |
| | | LoginBySocial({ commit }, userInfo) { |
| | | return new Promise((resolve) => { |
| | | loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state).then(res => { |
| | | const data = res.data; |
| | | if (data.error_description) { |
| | | Message({ |
| | | message: data.error_description, |
| | | type: 'error' |
| | | }) |
| | | } else { |
| | | commit('SET_TOKEN', data.access_token); |
| | | commit('SET_REFRESH_TOKEN', data.refresh_token); |
| | | commit('SET_USER_INFO', data); |
| | | commit('DEL_ALL_TAG'); |
| | | commit('CLEAR_LOCK'); |
| | | } |
| | | resolve(); |
| | | }) |
| | | }) |
| | | }, |
| | | GetUserInfo({ commit }) { |
| | | return new Promise((resolve, reject) => { |
| | | getUserInfo().then((res) => { |
| | | const data = res.data.data; |
| | | commit('SET_ROLES', data.roles); |
| | | resolve(data); |
| | | }).catch(err => { |
| | | reject(err); |
| | | }) |
| | | }) |
| | | }, |
| | | refreshToken({ state, commit }) { |
| | | return new Promise((resolve, reject) => { |
| | | refreshToken(state.refreshToken, state.tenantId).then(res => { |
| | | const data = res.data; |
| | | commit('SET_TOKEN', data.access_token); |
| | | commit('SET_REFRESH_TOKEN', data.refresh_token); |
| | | resolve(); |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | }, |
| | | LogOut({ commit }) { |
| | | return new Promise((resolve, reject) => { |
| | | logout().then(() => { |
| | | commit('SET_TOKEN', ''); |
| | | commit('SET_MENU', []); |
| | | commit('SET_MENU_ALL_NULL', []); |
| | | commit('SET_ROLES', []); |
| | | commit('SET_TAG_LIST', []); |
| | | commit('DEL_ALL_TAG'); |
| | | commit('CLEAR_LOCK'); |
| | | removeToken(); |
| | | removeRefreshToken(); |
| | | resolve(); |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | }, |
| | | FedLogOut({ commit }) { |
| | | return new Promise(resolve => { |
| | | commit('SET_TOKEN', ''); |
| | | commit('SET_MENU_ALL_NULL', []); |
| | | commit('SET_MENU', []); |
| | | commit('SET_ROLES', []); |
| | | commit('SET_TAG_LIST', []); |
| | | commit('DEL_ALL_TAG'); |
| | | commit('CLEAR_LOCK'); |
| | | removeToken(); |
| | | removeRefreshToken(); |
| | | resolve(); |
| | | }) |
| | | }, |
| | | GetButtons({ commit }) { |
| | | return new Promise((resolve) => { |
| | | getButtons().then(res => { |
| | | const data = res.data.data; |
| | | commit('SET_PERMISSION', data); |
| | | resolve(); |
| | | }) |
| | | }) |
| | | }, |
| | | }, |
| | | mutations: { |
| | | set_hideHome: (state, val) => { |
| | | state.hideHome = val; |
| | | }, |
| | | SET_TOKEN: (state, token) => { |
| | | setToken(token); |
| | | state.token = token; |
| | | setStore({ name: 'token', content: state.token }) |
| | | }, |
| | | SET_MENU_ID(state, menuId) { |
| | | state.menuId = menuId; |
| | | }, |
| | | SET_MENU_ALL: (state, menuAll) => { |
| | | let menu = state.menuAll; |
| | | menuAll.forEach(ele => { |
| | | if (!menu.find(item => item.label === ele.label && item.path === ele.path)) { |
| | | menu.push(ele); |
| | | } |
| | | }) |
| | | state.menuAll = menu |
| | | setStore({ name: 'menuAll', content: state.menuAll }) |
| | | }, |
| | | SET_MENU_ALL_NULL: (state) => { |
| | | state.menuAll = [] |
| | | setStore({ name: 'menuAll', content: state.menuAll }) |
| | | }, |
| | | SET_MENU: (state, menu) => { |
| | | state.menu = menu |
| | | setStore({ name: 'menu', content: state.menu }) |
| | | }, |
| | | SET_REFRESH_TOKEN: (state, refreshToken) => { |
| | | setRefreshToken(refreshToken) |
| | | state.refreshToken = refreshToken; |
| | | setStore({ name: 'refreshToken', content: state.refreshToken }) |
| | | }, |
| | | SET_TENANT_ID: (state, tenantId) => { |
| | | state.tenantId = tenantId; |
| | | setStore({ name: 'tenantId', content: state.tenantId }) |
| | | }, |
| | | SET_USER_INFO: (state, userInfo) => { |
| | | if (validatenull(userInfo.avatar)) { |
| | | userInfo.avatar = "http://61.131.136.25:2081/zhba/upload/picture/mrtx.png"; |
| | | } |
| | | state.userInfo = userInfo; |
| | | setStore({ name: 'userInfo', content: state.userInfo }) |
| | | }, |
| | | SET_ROLES: (state, roles) => { |
| | | state.roles = roles; |
| | | }, |
| | | SET_PERMISSION: (state, permission) => { |
| | | let result = []; |
| | | |
| | | function getCode(list) { |
| | | list.forEach(ele => { |
| | | if (typeof (ele) === 'object') { |
| | | const chiildren = ele.children; |
| | | const code = ele.code; |
| | | if (chiildren) { |
| | | getCode(chiildren) |
| | | } else { |
| | | result.push(code); |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | getCode(permission); |
| | | state.permission = {}; |
| | | result.forEach(ele => { |
| | | state.permission[ele] = true; |
| | | }); |
| | | setStore({ name: 'permission', content: state.permission }) |
| | | }, |
| | | SET_EXAMID: (state, active) => { |
| | | state.examId = active |
| | | }, |
| | | SET_ISSHOWVIDEODIALOG: (state, active) => { |
| | | state.isShowVideoDialog = active |
| | | }, |
| | | } |
| | | } |
| | | |
| | | export default user |
| | |
| | | @import "./icon/index.scss"; |
| | | @import "./tool/index.scss"; |
| | | @import "./element-ui/element-ui.scss"; |
| | | @import "./login.scss"; |
| | | |
| | | @font-face { |
| | | font-family: Roboto-Bold; |
| New file |
| | |
| | | html, body, #app { |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | } |
| | | |
| | | .login-container { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-image: url("/images/pro-bg.png"); |
| | | background-size: cover; |
| | | background-position: center; |
| | | } |
| | | |
| | | .login-weaper { |
| | | display: flex; |
| | | width: 800px; |
| | | box-shadow: -4px 5px 20px rgba(0, 0, 0, 0.3); |
| | | border-radius: 8px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .login-left, |
| | | .login-border { |
| | | min-height: 450px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .login-left { |
| | | border-top-left-radius: 8px; |
| | | border-bottom-left-radius: 8px; |
| | | justify-content: center; |
| | | flex-direction: column; |
| | | background: linear-gradient(135deg, #409eff 0%, #67b8ff 100%); |
| | | color: #fff; |
| | | width: 45%; |
| | | padding: 30px; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .login-time { |
| | | position: absolute; |
| | | top: 30px; |
| | | left: 30px; |
| | | color: rgba(255, 255, 255, 0.9); |
| | | font-weight: 300; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .login-left .img { |
| | | width: 120px; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .login-left .title { |
| | | text-align: center; |
| | | color: #fff; |
| | | font-weight: 400; |
| | | letter-spacing: 3px; |
| | | font-size: 22px; |
| | | margin: 0; |
| | | } |
| | | |
| | | .login-border { |
| | | border-top-right-radius: 8px; |
| | | border-bottom-right-radius: 8px; |
| | | background-color: #fff; |
| | | width: 55%; |
| | | padding: 40px 30px; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .login-main { |
| | | width: 100%; |
| | | } |
| | | |
| | | .login-title { |
| | | color: #333; |
| | | margin-bottom: 8px; |
| | | font-weight: 500; |
| | | font-size: 20px; |
| | | text-align: center; |
| | | letter-spacing: 2px; |
| | | } |
| | | |
| | | .login-title-child { |
| | | color: #999; |
| | | margin-bottom: 30px; |
| | | font-weight: 300; |
| | | font-size: 12px; |
| | | text-align: center; |
| | | letter-spacing: 1px; |
| | | } |
| | | |
| | | .login-form { |
| | | margin: 0; |
| | | |
| | | .el-form-item { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .el-input { |
| | | input { |
| | | padding: 12px 15px; |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 6px; |
| | | font-size: 14px; |
| | | transition: border-color 0.3s; |
| | | |
| | | &:focus { |
| | | border-color: #409eff; |
| | | outline: none; |
| | | } |
| | | } |
| | | |
| | | .el-input__prefix { |
| | | i { |
| | | color: #909399; |
| | | font-size: 16px; |
| | | } |
| | | } |
| | | |
| | | .el-input__suffix { |
| | | i { |
| | | color: #909399; |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .login-submit { |
| | | width: 100%; |
| | | height: 42px; |
| | | background: linear-gradient(135deg, #409eff 0%, #67b8ff 100%); |
| | | border: none; |
| | | border-radius: 6px; |
| | | font-size: 16px; |
| | | letter-spacing: 2px; |
| | | color: #fff; |
| | | cursor: pointer; |
| | | margin-top: 10px; |
| | | transition: opacity 0.3s; |
| | | |
| | | &:hover { |
| | | opacity: 0.9; |
| | | } |
| | | |
| | | &:active { |
| | | opacity: 0.8; |
| | | } |
| | | } |
| | |
| | | /* |
| | | * @Author: shuishen 1109946754@qq.com |
| | | * @Date: 2022-10-17 09:34:19 |
| | | * @LastEditors: shuishen 1109946754@qq.com |
| | | * @LastEditTime: 2022-10-17 09:45:20 |
| | | * @FilePath: \srs-police-affairs\src\utils\tool.js |
| | | * @Description: |
| | | * |
| | | * Copyright (c) 2022 by shuishen 1109946754@qq.com, All Rights Reserved. |
| | | */ |
| | | function executeFunction (callbackArray, amount) { |
| | | return new Promise(function (resolve, reject) { |
| | | let index = 0 |
| | | |
| | | let currentIndex = 1 |
| | | |
| | | function execute () { |
| | | |
| | | try { |
| | | callbackArray[index]() |
| | | index++ |
| | | } catch (e) { |
| | | |
| | | return new Error(e) |
| | | |
| | | } finally { |
| | | |
| | | if (currentIndex == callbackArray.length) { |
| | | resolve |
| | | } |
| | | |
| | | execute() |
| | | currentIndex++ |
| | | } |
| | | |
| | | } |
| | | |
| | | execute() |
| | | }) |
| | | } |
| | | |
| | | export function deepClone(obj) { |
| | | if (obj === null || typeof obj !== 'object') { |
| | | return obj |
| | | } |
| | | if (obj instanceof Date) { |
| | | return new Date(obj.getTime()) |
| | | } |
| | | if (obj instanceof Array) { |
| | | return obj.map(item => deepClone(item)) |
| | | } |
| | | if (typeof obj === 'object') { |
| | | const clonedObj = {} |
| | | for (let key in obj) { |
| | | if (Object.prototype.hasOwnProperty.call(obj, key)) { |
| | | clonedObj[key] = deepClone(obj[key]) |
| | | } |
| | | } |
| | | return clonedObj |
| | | } |
| | | } |
| | | |
| | | export default executeFunction |
| | |
| | | |
| | | // 点击播放视频 |
| | | openVideoPlayer () { |
| | | this.$store.commit("SET_ISSHOWVIDEODIALOG", true) |
| | | // this.$store.commit("SET_ISSHOWVIDEODIALOG", true) |
| | | }, |
| | | }, |
| | | |
| New file |
| | |
| | | <template> |
| | | <div class="login-container" ref="login" @keyup.enter.native="handleLogin"> |
| | | <div class="login-weaper"> |
| | | <div class="login-left"> |
| | | <div class="login-time"> |
| | | {{ time }} |
| | | </div> |
| | | <img class="img" src="/images/logo.png" alt="" /> |
| | | <p class="title">保安员考试大屏</p> |
| | | </div> |
| | | <div class="login-border"> |
| | | <div class="login-main"> |
| | | <h4 class="login-title"> |
| | | 系统登录 |
| | | </h4> |
| | | <h4 class="login-title-child">Security Guard Exam System</h4> |
| | | <userLogin></userLogin> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | import userLogin from "./userlogin"; |
| | | import { dateFormat } from "@/utils/date"; |
| | | |
| | | export default { |
| | | name: "login", |
| | | components: { |
| | | userLogin, |
| | | }, |
| | | data() { |
| | | return { |
| | | time: "", |
| | | }; |
| | | }, |
| | | created() { |
| | | document.title = "保安员考试大屏" |
| | | this.$store.commit("SET_WEBTITLE", '保安员考试大屏') |
| | | this.getTime(); |
| | | }, |
| | | mounted() {}, |
| | | props: [], |
| | | methods: { |
| | | getTime() { |
| | | setInterval(() => { |
| | | this.time = dateFormat(new Date()); |
| | | }, 1000); |
| | | }, |
| | | handleLogin() { |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import "@/styles/login.scss"; |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <el-form class="login-form" status-icon :rules="loginRules" ref="loginForm" :model="loginForm" label-width="0"> |
| | | <el-form-item prop="username"> |
| | | <el-input size="small" @keyup.enter.native="handleLogin" v-model="loginForm.username" auto-complete="off" |
| | | placeholder="请输入用户名"> |
| | | <i slot="prefix" class="fa fa-user"/> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input size="small" @keyup.enter.native="handleLogin" :type="passwordType" v-model="loginForm.password" |
| | | auto-complete="off" placeholder="请输入密码"> |
| | | <i class="el-icon-view el-input__icon" slot="suffix" @click="showPassword"/> |
| | | <i slot="prefix" class="fa fa-lock"/> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" size="small" @click.native.prevent="handleLogin" class="login-submit">登录 |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script> |
| | | import {Message} from "element-ui"; |
| | | |
| | | export default { |
| | | name: "userlogin", |
| | | data() { |
| | | return { |
| | | loginForm: { |
| | | tenantId: "000000", |
| | | username: "", |
| | | password: "", |
| | | type: "account", |
| | | }, |
| | | loginRules: { |
| | | username: [ |
| | | {required: true, message: "请输入用户名", trigger: "blur"}, |
| | | ], |
| | | password: [ |
| | | {required: true, message: "请输入密码", trigger: "blur"}, |
| | | {min: 6, message: "密码长度最少为6位", trigger: "blur"}, |
| | | ], |
| | | }, |
| | | passwordType: "password", |
| | | } |
| | | }, |
| | | mounted() { |
| | | }, |
| | | methods: { |
| | | showPassword() { |
| | | this.passwordType = this.passwordType === "password" ? "" : "password" |
| | | }, |
| | | handleLogin() { |
| | | this.$refs.loginForm.validate((valid) => { |
| | | if (valid) { |
| | | const loading = this.$loading({ |
| | | lock: true, |
| | | text: "登录中,请稍后...", |
| | | spinner: "el-icon-loading", |
| | | }) |
| | | this.$store |
| | | .dispatch("LoginByUsername", this.loginForm) |
| | | .then((data) => { |
| | | if (data.error_description) { |
| | | loading.close() |
| | | }else{ |
| | | this.$router.push({path: '/layout/home'}) |
| | | loading.close() |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | loading.close() |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style></style> |
| | |
| | | scss: { |
| | | prependData: `@import "~@/styles/scssFile.scss";`, |
| | | }, |
| | | // postcss: { |
| | | // plugins: [ //配置px转rem进行适配 |
| | | // require('postcss-px2rem')({ |
| | | // // 根标签字号大小根据设计稿宽度/flexible.js里的份数得到,这里假定设计稿宽度为3840 3840/24 = 160px |
| | | // remUnit: 80 |
| | | // }), |
| | | // ] |
| | | // } |
| | | // postcss: { |
| | | // //给postcss-loader传递选项 |
| | | // plugins: [ |
| | | // new pxtovw({ |
| | | // unitToConvert: 'px', //需要转换的单位,默认为"px"; |
| | | // viewportWidth: 1920, //设计稿的视口宽度 |
| | | // viewportHeight: 1080, //设计稿的视口宽度 |
| | | // unitPrecision: 5, //单位转换后保留的小数位数 |
| | | // propList: ['*'], //要进行转换的属性列表,*表示匹配所有,!表示不转换 |
| | | // viewportUnit: 'vw', //转换后的视口单位 |
| | | // fontViewportUnit: 'vw', //转换后字体使用的视口单位 |
| | | // selectorBlackList: [], //不进行转换的css选择器,继续使用原有单位 |
| | | // minPixelValue: 1, //设置最小的转换数值 |
| | | // mediaQuery: false, //设置媒体查询里的单位是否需要转换单位 |
| | | // replace: true, //是否直接更换属性值,而不添加备用属性 |
| | | // exclude: [/node_modules/], //忽略某些文件夹下的文件 |
| | | // // landscape: true, |
| | | // // landscapeUnit: 'vw', |
| | | // // landscapeWidth: 1920 |
| | | // }) |
| | | // ] |
| | | // } |
| | | }, |
| | | }, |
| | | |
| | |
| | | } |
| | | ], |
| | | ]) |
| | | |
| | | // config.plugin("define").tap((args) => { |
| | | // args[0]["process"] = { ...args[0]["process.env"] } |
| | | // return args |
| | | // }) |
| | | }, |
| | | |
| | | configureWebpack: { |
| | |
| | | maxChunks: 5, |
| | | minChunkSize: 100, |
| | | }), |
| | | // 提供带 Content-Encoding 编码的压缩版的资源 |
| | | // new CompressionPlugin({ |
| | | // algorithm: 'gzip', |
| | | // test: /\.js$|\.html$|\.css/, // 匹配文件名 |
| | | // // test: /\.(js|css)$/, |
| | | // threshold: 10240, // 对超过10k的数据压缩 |
| | | // deleteOriginalAssets: false, // 不删除源文件 |
| | | // minRatio: 0.8 // 压缩比 |
| | | // }) |
| | | ], |
| | | }, |
| | | |
| | | devServer: { |
| | | // open: false, // 编译完成是否打开网页 |
| | | // host: "0.0.0.0", // 指定使用地址,默认localhost,0.0.0.0代表可以被外界访问 |
| | | // // port: 82, // 访问端口 |
| | | // https: false, // 编译失败时刷新页面 |
| | | // hot: true, // 开启热加载 |
| | | // hotOnly: false, |
| | | // proxy: { |
| | | // [process.env.VUE_APP_API]: {//拦截器(拦截链接中有/api) |
| | | // target: process.env.VUE_API_DEV_TARGET,//'http://192.168.1.114:3000', //process.env.VUE_API_DEV_TARGET, //API服务器的地址 |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // //'^/api': '/' |
| | | // [`^${process.env.VUE_APP_API}`]: '', |
| | | // //[`^${process.env.VUE_APP_API}`]: '/', //配置出来的接口没有 /api |
| | | // } |
| | | // } |
| | | // } |
| | | proxy: { |
| | | |
| | | // 中台接口 |
| | | "/services": { |
| | | target: "https://sk.hubeishuiyi.cn", |
| | | changeOrigin: true, //开启代理跨域 |
| | | // pathRewrite: { |
| | | // "^/services": "/", |
| | | // }, |
| | | }, |
| | | // 业务平台接口 |
| | | "/api": { |
| | | // target用于配置你允许访问数据的计算机名称,即是你的api接口的服务器地址 |
| | | target: "http://60.220.177.113:2081", |
| | | target: "http://124.164.10.118:2081", |
| | | // target: "http://192.168.0.102:81", |
| | | // ws: true, //启用webSocket6566 |
| | | changeOrigin: true, //开启代理跨域 |
| | | // pathRewrite: {//本地地址没有api需要去掉 |
| | | // '^/api': '/' |
| | | // } |
| | | pathRewrite: {}//后端接口包含/api前缀,不需要重写 |
| | | }, |
| | | }, |
| | | }, |