派生自 wuyushui/SewerAndRainNetwork

chenyibo
2021-03-30 cad0535f3fb14ff09db99ec43169da3aa33b83f2
1.新增登录界面
5个文件已添加
13个文件已修改
532 ■■■■■ 已修改文件
.env 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.production 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.test 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/host.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mapApi.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mapUrl.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/app.config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/login-page/page1.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/map.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/index.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.js 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/axios.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/navigation.js 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/tools.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Login.vue 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env
@@ -2,7 +2,7 @@
NODE_ENV=development
#vue项目 属性名必须以VUE_APP_开头,比如VUE_APP_XXX
VUE_APP_MOCK=true
VUE_APP_API_HOST=http://localhost:8080/
VUE_APP_API_HOST=http://xearth.cn:3000
VUE_APP_API_TOKEN_URL=https://auth.uat.siam.sinopec.com/
VUE_APP_API_BASE_URL=/api
VUE_APP_CLIENT_ID=no_apply
.env.production
@@ -1,7 +1,7 @@
# .env
NODE_ENV=production
VUE_APP_MOCK=false
VUE_APP_API_HOST=http://localhost:8080/
VUE_APP_API_HOST=http://localhost:3000/
VUE_APP_API_BASE_URL=/api
VUE_APP_API_TOKEN_URL=https://oauth.siam.sinopec.com/
VUE_APP_CLIENT_ID=no_apply
.env.test
@@ -1,7 +1,7 @@
# .env
NODE_ENV=test
VUE_APP_MOCK=false
VUE_APP_API_HOST=http://localhost:8080/
VUE_APP_API_HOST=http://localhost:3000/
VUE_APP_API_TOKEN_URL=https://auth.uat.siam.sinopec.com/
VUE_APP_API_BASE_URL=/api
VUE_APP_CLIENT_ID=no_apply
src/api/host.js
New file
@@ -0,0 +1,6 @@
/**
 * 服务HOST定义
 */
import { getSchemeHost } from '../utils/tools'
export const $HOST = getSchemeHost()
src/api/index.js
@@ -1,7 +1,4 @@
import * as mapApi from './mapApi'
import * as mapUrl from './mapUrl'
export default {
  mapApi,
  mapUrl
}
export default Object.assign({}, mapApi, mapUrl)
src/api/mapApi.js
@@ -3,13 +3,12 @@
// const $HOST = 'http://10.238.221.113'
// 测试环境IP:http://10.238.221.113
import axios from '@utils/axios'
import * as mapUrl from './mapUrl'
/**
 * 该方法配置
 */
class MapAPI {
  getToken (param) {
    axios.get(param.url, param.option)
export default {
  getUser (data) {
    return axios.get(mapUrl.GetUser, data)
  }
}
export default new MapAPI()
src/api/mapUrl.js
@@ -1,10 +1,6 @@
/**
 * 该文件配置接口的URL地址
 */
class ApiURLs {
  constructor () {
    this.APIURL_HELLOWORLD = 'http://www.baidu.com'
  }
}
import { $HOST } from './host'
export default new ApiURLs()
export const GetUser = $HOST + '/user/getUser'
src/app.config.js
@@ -11,7 +11,7 @@
      developmentOff: true // 设为true后在开发环境不会收集错误信息
    }
  },
  homeRouterName: 'Home',
  homeRouterName: 'mapTemplate',
  loginRouteName: 'Login',
  routeMode: 'history',
  tagNavCache: false,
src/assets/images/login-page/page1.jpg
src/main.js
@@ -15,12 +15,13 @@
import '@/utils/dialogDrag.js'
import '@components/plugin/leaflet-measure-path/leaflet-measure-path.css'
import '@components/plugin/leaflet-measure-path/leaflet-measure-path'
const appConfig = require('@/app.config')
Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.prototype.$cancels = []
Vue.prototype.L = L
Vue.prototype.$config = appConfig
// 注册指令7
// registerDirectives(Vue)
src/router/index.js
@@ -1,10 +1,11 @@
import Vue from 'vue'
import Router from 'vue-router'
import { routes } from './routes'
import { getToken } from '@/utils/navigation'
import 'nprogress/nprogress.css'
const appConfig = require('@/app.config')
const { routeMode } = appConfig
const { homeRouterName, loginRouteName, routeMode } = appConfig
const LOGIN_PAGE_ROUTE_NAME = loginRouteName
Vue.use(Router)
const baseName = process.env.NODE_ENV === 'production' ? `/${appConfig.projectName}/` : '/'
const router = new Router({
@@ -17,12 +18,32 @@
    cancel()
  })
  Vue.prototype.$cancels = []
  const token = getToken()
  if (!token && to.name !== LOGIN_PAGE_ROUTE_NAME) {
    // 未登录且要跳转的页面不是登录页
    next({
      name: LOGIN_PAGE_ROUTE_NAME // 跳转到登录页
    })
  } else if (!token && to.name === LOGIN_PAGE_ROUTE_NAME) {
    // 未登陆且要跳转的页面是登录页
    next() // 跳转
  } else if (token && to.name === LOGIN_PAGE_ROUTE_NAME) {
    // 已登录且要跳转的页面是登录页
    next({
      name: homeRouterName // 跳转到homeName页
    })
  } else if (!token) {
    next({
      name: LOGIN_PAGE_ROUTE_NAME // 跳转到登录页
    })
  } else {
    next()
  }
  // 不需要登录认证的路由
  if (Object.hasOwnProperty.call(to.meta, 'noLoginIdentify') && to.meta.noLoginIdentify) {
    next()
    return
  }
  next()
  // next()
})
router.beforeResolve((to, from, next) => {
  next()
src/router/map.js
@@ -9,8 +9,10 @@
 * }
 */
const MapTemplate = (r) => require.ensure([], () => r(require('../views/MapTemplate')), 'frame')
const Login = (r) => require.ensure([], () => r(require('../views/Login')), 'frame')
const routes = [
  { path: '/mapTemplate', name: 'MapTemplate', meta: { statusBgc: 0 }, component: MapTemplate }
  { path: '/mapTemplate', name: 'MapTemplate', meta: { statusBgc: 0 }, component: MapTemplate },
  { path: '/Login', name: 'Login', meta: { statusBgc: 0 }, component: Login }
]
// 所有上面定义的路由都要写在下面的routes里
src/store/index.js
@@ -1,6 +1,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
import map from './modules/map'
import user from './modules/user'
// import app from './modules/app'
Vue.use(Vuex)
@@ -13,6 +14,7 @@
  },
  modules: {
    // app,
    map
    map,
    user
  }
})
src/store/modules/user.js
New file
@@ -0,0 +1,149 @@
import $API from '../../api'
import $http from '@/utils/axios'
import { setToken, getToken, setAccount, getAccount } from '@/utils/navigation'
// import { replaceUrlParams } from '@/utils/tools'
const state = {
  account: '',
  userName: '',
  userId: '',
  avator: '',
  orgUnitName: '',
  orgUnitCode: '',
  orgUnitLevel: '',
  orgSectorName: '',
  orgSectorCode: '',
  isAdmin: null,
  token: getToken(),
  access: 0,
  hasGetInfo: false
}
const mutations = {
  setAvator (state, avator) {
    state.avator = avator
  },
  setUserId (state, id) {
    state.userId = id
  },
  setAccount (state, account) {
    state.account = account
    setAccount(account)
  },
  setUserName (state, name) {
    state.userName = name
  },
  setOrgUnitName (state, orgUnitName) {
    state.orgUnitName = orgUnitName
  },
  setOrgUnitCode (state, orgUnitCode) {
    state.orgUnitCode = orgUnitCode
  },
  setOrgSectorName (state, orgSectorName) {
    state.orgSectorName = orgSectorName
  },
  setOrgSectorCode (state, orgSectorCode) {
    state.orgSectorCode = orgSectorCode
  },
  setOrgUnitLevel (state, orgUnitLevel) {
    state.orgUnitLevel = orgUnitLevel
  },
  setAdmin (state, isAdmin) {
    state.isAdmin = isAdmin
  },
  setAccess (state, access) {
    state.access = access
  },
  setToken (state, token) {
    state.token = token
    setToken(token)
  },
  setHasGetInfo (state, status) {
    state.hasGetInfo = status
  }
}
const actions = {
  // 登录
  handleLogin ({ commit }, { account, password }) {
    return new Promise((resolve, reject) => {
      $http.post($API.GetUser, {
        userName: account,
        passWord: password
      }).then(data => {
        console.log(data)
        commit('setToken', '12345668')
        commit('setAccount', account)
        resolve()
      }).catch(err => {
        reject(err)
      })
    })
  },
  // 退出登录
  handleLogOut ({ state, commit }) {
    return new Promise((resolve, reject) => {
      commit('setToken', '')
      commit('setAccount', '')
      commit('setAccess', 0)
      resolve()
    })
  },
  // 获取用户信息
  getUserInfo ({ state, commit, dispatch }) {
    const account = getAccount() || 'admin'
    return new Promise((resolve, reject) => {
      try {
        $http.get($API.AAA_GET_USER_INFO, {
          token: state.token
        }).then(response => {
          const data = response.data
          commit('setAvator', data.avator)
          // commit('setOrgUnitName', data.orgUnitName)
          // commit('setOrgUnitCode', data.orgUnitCode)
          commit('setUserId', data.userId)
          commit('setAccess', data.access)
          commit('setHasGetInfo', true)
          if (account === 'tianjun') {
            // admin的场景走mock
            commit('setAccount', data.account)
            commit('setUserName', data.userName)
            resolve(data)
          } else {
            $http.get($API.MDM_GET_USER_ACCOUNT_DETAIL, {
              account: account
            }).then(response => {
              const d = response.data
              if (d) {
                commit('setAccount', d.unifiedIdentityAcc)
                commit('setUserName', d.userName)
                // 获取用户后,获取组织机构
                dispatch('getUserOrgInfo').then(() => {
                  resolve(d)
                }).catch(err => {
                  alert('不能获取用户组织机构')
                  reject(err)
                })
              } else {
                commit('setToken', '')
                commit('setAccount', '')
                commit('setAccess', 0)
                resolve(false)
              }
            })
          }
        }).catch(err => {
          reject(err)
        })
      } catch (error) {
        reject(error)
      }
    })
  }
}
export default {
  state,
  mutations,
  actions
}
src/utils/axios.js
@@ -140,12 +140,13 @@
Service.interceptors.response.use(
  response => {
    const res = response.data
    if (Number(res.code) !== 200 && Number(res.code) !== 0) {
    /* if (Number(res.code) !== 200 && Number(res.code) !== 0) {
      $T.warning(res.message)
      return Promise.reject(res.message)
    } else {
      return res
    }
    } */
    return res
  },
  error => {
    if (error.message && error.message.includes('timeout')) {
src/utils/navigation.js
New file
@@ -0,0 +1,167 @@
import Cookies from 'js-cookie'
const appConfig = require('@/app.config')
const { cookieExpires } = appConfig
export const TOKEN_KEY = 'token'
export const ACCOUNT_KEY = 'account'
export const setToken = (token) => {
  Cookies.set(TOKEN_KEY, token, { expires: cookieExpires || 1 })
}
export const getToken = () => {
  const token = Cookies.get(TOKEN_KEY)
  if (token !== 'undefined') return token
  else return false
}
export const setAccount = (account) => {
  Cookies.set(ACCOUNT_KEY, account, { expires: cookieExpires || 1 })
}
export const getAccount = () => {
  const account = Cookies.get(ACCOUNT_KEY)
  if (account) return account
  else return false
}
export const hasChild = (item) => {
  return item.children && item.children.length !== 0
}
/**
 * @description 本地存储和获取标签导航列表
 */
export const setTagNavListToLocalstorage = list => {
  localStorage.tagNaveList = JSON.stringify(list)
}
/**
 * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项
 */
export const getTagNavListFromLocalstorage = () => {
  const list = localStorage.tagNaveList
  return list ? JSON.parse(list) : []
}
/**
 * @param {Array} routers 路由列表数组
 * @description 用于找到路由列表中name为home的对象
 */
export const getHomeRouter = (routers, homeName = 'Home') => {
  let i = -1
  const len = routers.length
  let homeRoute = {}
  while (++i < len) {
    const item = routers[i]
    if (item.children && item.children.length) {
      const res = getHomeRouter(item.children, homeName)
      if (res.name) return res
    } else {
      if (item.name === homeName) homeRoute = item
    }
  }
  return homeRoute
}
/**
 * @param {*} list 现有标签导航列表
 * @param {*} newRoute 新添加的路由原信息对象
 * @description 如果该newRoute已经存在则不再添加
 */
export const getNewTagList = (list, newRoute) => {
  const { name, path, meta } = newRoute
  const newList = [...list]
  if (newList.findIndex(item => item.name === name) >= 0) return newList
  else newList.push({ name, path, meta })
  return newList
}
/**
 * @param {Number} times 回调函数需要执行的次数
 * @param {Function} callback 回调函数
 */
export const doCustomTimes = (times, callback) => {
  let i = -1
  while (++i < times) {
    callback(i)
  }
}
export const findNodeUpper = (ele, tag) => {
  if (ele.parentNode) {
    if (ele.parentNode.tagName === tag.toUpperCase()) {
      return ele.parentNode
    } else {
      return findNodeUpper(ele.parentNode, tag)
    }
  }
}
export const findNodeUpperByClasses = (ele, classes) => {
  const parentNode = ele.parentNode
  if (parentNode) {
    const classList = parentNode.classList
    if (classList && classes.every(className => classList.contains(className))) {
      return parentNode
    } else {
      return findNodeUpperByClasses(parentNode, classes)
    }
  }
}
export const findNodeDownward = (ele, tag) => {
  const tagName = tag.toUpperCase()
  if (ele.childNodes.length) {
    let i = -1
    const len = ele.childNodes.length
    while (++i < len) {
      const child = ele.childNodes[i]
      if (child.tagName === tagName) return child
      else return findNodeDownward(child, tag)
    }
  }
}
export const localSave = (key, value) => {
  localStorage.setItem(key, value)
}
export const localRead = (key) => {
  return localStorage.getItem(key) || ''
}
// scrollTop animation
export const scrollTop = (el, from = 0, to, duration = 500, endCallback) => {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = (
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        return window.setTimeout(callback, 1000 / 60)
      }
    )
  }
  const difference = Math.abs(from - to)
  const step = Math.ceil(difference / duration * 50)
  const scroll = (start, end, step) => {
    if (start === end) {
      endCallback && endCallback()
      return
    }
    let d = (start + step > end) ? end : start + step
    if (start > end) {
      d = (start - step < end) ? end : start - step
    }
    if (el === window) {
      window.scrollTo(d, d)
    } else {
      el.scrollTop = d
    }
    window.requestAnimationFrame(() => scroll(d, end, step))
  }
  scroll(from, to, step)
}
src/utils/tools.js
@@ -25,7 +25,16 @@
  })
  return arr
}
/**
 * 根据不同的协议,替换env配置文件中的URL协议
 *
 * @return {String}
 */
export function getSchemeHost () {
  const protocol = window.location.protocol
  const host = process.env.VUE_APP_API_HOST
  return host.replace(/scheme/g, protocol)
}
/**
 * collection数据转换为标准JSON
 * @param obj collection数据
src/views/Login.vue
New file
@@ -0,0 +1,124 @@
<template>
    <div class="login-wrap" @keydown.enter="handleSubmit">
        <div class="content">
            <el-card class="box-card">
                <div slot="header" class="login-title clearfix">
                    <el-icon name="star-on"></el-icon>
                    <span>欢迎登录</span>
                </div>
                <div class="form-content">
                    <el-form :model="form" :rules="formRules" ref="loginForm" class="demo-ruleForm">
                        <el-form-item prop="account">
                            <el-input size="small" v-model="form.account" placeholder="请输入用户名">
                                <el-button slot="prepend" icon="el-icon-search" style="padding: 12px 10px;"></el-button>
                            </el-input>
                        </el-form-item>
                        <el-form-item prop="password">
                            <el-input size="small" type="password" v-model="form.password" auto-complete="off"
                                      placeholder="请输入密码">
                                <el-button slot="prepend" icon="el-icon-search" style="padding: 12px 10px;"></el-button>
                            </el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button size="small" type="primary" @click="handleSubmit" style="width: 100%">登录
                            </el-button>
                        </el-form-item>
                    </el-form>
                </div>
                <p class="login-tip">输入任意用户名和密码即可</p>
            </el-card>
        </div>
    </div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
  name: 'Login',
  components: {},
  data () {
    return {
      form: {
        account: 'admin',
        password: 'admin'
      },
      formRules: {
        account: [
          { required: true, message: '账号不能为空', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '密码不能为空', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    ...mapActions([
      'handleLogin',
      'getUserInfo'
    ]),
    handleSubmit () {
      this.$refs.loginForm.validate((valid) => {
        if (valid) {
          this.handleLogin({
            account: this.form.account,
            password: this.form.password
          }).then(response => {
            this.$router.push({
              name: this.$config.homeRouterName
            })
          })
        }
      })
    }
  }
}
</script>
<style lang="less">
    .login-wrap {
        position: relative;
        background-image: url('../assets/images/login-page/page1.jpg');
        background-size: cover;
        background-position: center;
        width: 100%;
        height: 100%;
        overflow: hidden;
        .content {
            position: absolute;
            right: 160px;
            top: 25%;
        }
        .box-card {
            width: 300px;
        }
        .clearfix:before,
        .clearfix:after {
            display: table;
            content: "";
        }
        .clearfix:after {
            clear: both
        }
        .form-content {
            padding: 10px 0 0;
        }
        .login-title {
            width: 100%;
            font-size: 14px;
            color: #1c2438;
            font-weight: 700;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .login-tip {
            font-size: 10px;
            text-align: center;
            color: #c3c3c3;
        }
    }
</style>