Browse Source

Merge branch 'master' of http://git.zthymaoyi.com/gongdecai/wangluohuoyun-htqd

ccj 2 years ago
parent
commit
e72db5c1ff

+ 2 - 2
public/index.html

@@ -5,13 +5,13 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
     <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
-  <meta http-equiv="Content-Security-Policy" >
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= webpackConfig.name %></title>
   </head>
   <body>
     <noscript>
-      <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+      <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable
+        it to continue.</strong>
     </noscript>
     <div id="app"></div>
     <!-- built files will be auto injected -->

+ 1 - 0
src/api/operationLog.js

@@ -22,5 +22,6 @@ export function exportInfo(data) {
       url: '/hyOperLog/api/export',
       method: 'post',
       data: data,
+      responseType: 'arraybuffer'
     })
   }

+ 76 - 0
src/permission - 副本.js

@@ -0,0 +1,76 @@
+import router from './router'
+import store from './store'
+import {
+  Message
+} from 'element-ui'
+import NProgress from 'nprogress' // progress bar
+import 'nprogress/nprogress.css' // progress bar style
+import {
+  getToken
+} from '@/utils/auth' // get token from cookie
+import getPageTitle from '@/utils/get-page-title'
+
+NProgress.configure({
+  showSpinner: false
+}) // NProgress Configuration
+
+const whiteList = ['/login', '/dashboard'] // no redirect whitelist
+
+router.beforeEach(async (to, from, next) => {
+  // start progress bar
+  NProgress.start()
+
+  // set page title
+  document.title = getPageTitle(to.meta.title)
+
+  // determine whether the user has logged in
+  const hasToken = getToken()
+  debugger
+  if (hasToken) {
+    if (to.path === '/login') {
+      // if is logged in, redirect to the home page
+      next({
+        path: '/'
+      })
+      NProgress.done()
+    } else {
+      const hasGetUserInfo = store.getters.name
+      if (store.getters.token) {
+        next()
+      } else {
+        try {
+          // get user info
+          const accessRoutes = await store.dispatch('permission/generateRoutes');
+          router.addRoutes(accessRoutes);
+          // const {
+          //   roles
+          // } = await store.dispatch('user/getInfo')
+
+          next()
+        } catch (error) {
+          // remove token and go to login page to re-login
+          await store.dispatch('user/resetToken')
+          Message.error(error || 'Has Error')
+          next(`/login?redirect=${to.path}`)
+          NProgress.done()
+        }
+      }
+    }
+  } else {
+    /* has no token*/
+
+    if (whiteList.indexOf(to.path) !== -1) {
+      // in the free login whitelist, go directly
+      next()
+    } else {
+      // other pages that do not have permission to access are redirected to the login page.
+      next(`/login?redirect=${to.path}`)
+      NProgress.done()
+    }
+  }
+})
+
+router.afterEach(() => {
+  // finish progress bar
+  NProgress.done()
+})

+ 1 - 0
src/router/index.js

@@ -55,6 +55,7 @@ export const constantRoutes = [{
   officialWebsiteManagement,
   parkReportManagement,
   settlementManagement,
+  operationLog,
   {
     path: '/permissionSetting',
     component: Layout,

+ 259 - 0
src/store/modules/user - 副本.js

@@ -0,0 +1,259 @@
+import {
+  login,
+  logout,
+  getInfo,
+  getRoule,
+  isLandBased,
+  companyInfo
+} from '@/api/user'
+import {
+  getToken,
+  setToken,
+  removeToken
+} from '@/utils/auth'
+import {
+  resetRouter
+} from '@/router'
+
+const getDefaultState = () => {
+  return {
+    token: getToken(),
+    name: '',
+    avatar: '',
+    roles: [],
+  }
+}
+
+const state = getDefaultState()
+
+const mutations = {
+  RESET_STATE: (state) => {
+    Object.assign(state, getDefaultState())
+  },
+  SET_TOKEN: (state, token) => {
+    state.token = token
+  },
+  SET_NAME: (state, name) => {
+    state.name = name
+  },
+  SET_AVATAR: (state, avatar) => {
+    state.avatar = avatar
+  },
+  SET_ROLES: (state, roles) => {
+    state.roles = roles
+  },
+}
+
+const actions = {
+  // user login
+  async login({
+    commit,
+    dispatch
+  }, userInfo) {
+    const {
+      companyName,
+      username,
+      password
+    } = userInfo
+    // return new Promise((resolve, reject) => {
+    const data = await login({
+      companyName: companyName,
+      username: username.trim(),
+      password: password
+    })
+    // .then(response => {
+    // const { data } = response
+    // commit('SET_TOKEN', data.token)
+    // setToken(data.token)
+    // commit('SET_TOKEN', 'Admin-Token')
+    // setToken('Admin-Token')
+    // resolve(response)
+    // }).catch(error => {
+    // reject(error)
+    // })
+    const {
+      compId,
+      tenantId,
+      vesselId,
+      vesselBankFlag,
+      clientFag,
+      userId
+    } = data.data
+    localStorage.setItem('ws-pf_compId', compId)
+    localStorage.setItem('ws-pf_userId', userId)
+    localStorage.setItem('ws-pf_tenantId', tenantId)
+    localStorage.setItem('ws-pf_vesselId', vesselId) // 仅适用于一条船
+    localStorage.setItem('ws-pf_vesselBankFlag', vesselBankFlag) // 当前登录人是船端还是岸端的人员
+    localStorage.setItem('ws-pf_clientFag', clientFag)
+    // notification.setSessionId(userId) // 设置通知唯一标识
+    // notification.start() // 开始监听通知
+    // })
+    await isLandBased().then(response => {
+      localStorage.setItem('ws-pf_serviceTypeFlag', response)
+    })
+    const {
+      organizationMonetaryKey,
+      compName,
+      compDomainName,
+      organizationMonetaryValue
+    } = await companyInfo({
+      compId: compId
+    })
+    localStorage.setItem('ws-pf_organMonetaryKey', organizationMonetaryKey)
+    localStorage.setItem('ws-pf_compName', compName)
+    localStorage.setItem('ws-pf_compDomainName', compDomainName)
+    localStorage.setItem('ws-pf_organMonetaryValue', organizationMonetaryValue)
+    dispatch('getInfo', {
+      vesselBankFlag,
+      compName
+    })
+  },
+  async getInfo({
+    commit,
+    dispatch
+  }, {
+    vesselBankFlag = 'B',
+    compName = ''
+  }) {
+    debugger
+    const response = await getInfo()
+    const {
+      staffName,
+      deptId,
+      deptName,
+      deptNameEn,
+      vessels = [],
+      majorRole: {
+        roleName = '',
+        roleId = '',
+        dutyId = ''
+      },
+      roles
+    } = response.data
+    const content = {
+      ...response.data,
+      showRoleName: roleName || roles[0].roleName,
+      showRoleId: roleId || roles[0].roleId,
+      showCompName: vesselBankFlag === 'V' ? vessels[0].vesselName : compName,
+      avatar: 'img/user.png'
+    }
+    // setStore({
+    //     name: 'userInfo',
+    //     content: content,
+    //     type: 'session'
+    // })
+    // dispatch('common/setLocalVessels', vessels, { root: true })
+    // commit('SET_USER_INFO', content)
+
+    localStorage.setItem('ws-pf_dutyId', dutyId || response.data.roles[0].dutyId)
+    localStorage.setItem('ws-pf_roleName', roleName || roles[0].roleName)
+
+    localStorage.setItem('ws-pf_staffName', staffName)
+    localStorage.setItem('ws-pf_deptId', deptId)
+    localStorage.setItem('ws-pf_deptName', deptName)
+    localStorage.setItem('ws-pf_deptNameEn', deptNameEn)
+    localStorage.setItem('ws-pf_vessels', JSON.stringify(vessels))
+    localStorage.setItem('ws-pf_roleId', roleId || roles[0].roleId)
+
+  },
+  // // get user info
+  // async getInfo({
+  //   commit,
+  //   state,
+  //   dispatch
+  // }) {
+  //   return new Promise((resolve, reject) => {
+
+  //     getInfo().then(response => {
+  //       const {
+  //         data
+  //       } = response
+  //       if (!data) {
+  //         reject('Verification failed, please Login again.')
+  //       }
+  //       const {
+  //         staffName,
+  //         deptId,
+  //         deptName,
+  //         deptNameEn,
+  //         vessels = [],
+  //         majorRole: {
+  //           roleName = '',
+  //           roleId = '',
+  //           dutyId = ''
+  //         },
+  //         roles
+  //       } = data
+
+  //       // roles must be a non-empty array
+  //       // if (!roles || roles.length <= 0) {
+  //       //   reject('getInfo: roles must be a non-null array!')
+  //       // }
+
+  //       localStorage.setItem('ws-pf_dutyId', dutyId || data.roles[0].dutyId)
+  //       localStorage.setItem('ws-pf_roleName', roleName || roles[0].roleName)
+
+  //       localStorage.setItem('ws-pf_staffName', staffName)
+  //       localStorage.setItem('ws-pf_deptId', deptId)
+  //       localStorage.setItem('ws-pf_deptName', deptName)
+  //       localStorage.setItem('ws-pf_deptNameEn', deptNameEn)
+  //       localStorage.setItem('ws-pf_vessels', JSON.stringify(vessels))
+  //       localStorage.setItem('ws-pf_roleId', roleId || roles[0].roleId)
+  //       resolve(data)
+  //     }).catch(error => {
+  //       reject(error)
+  //     })
+  //   })
+  // },
+  getRoule({
+    commit,
+    state
+  }) {
+    return new Promise(async (resolve, reject) => {
+      try {
+        const data = await getRoule(state.roles)
+        data.forEach(route => {
+          asyncRoutes.push(route)
+        })
+        commit('SET_ROUTES', asyncRoutes)
+        resolve(asyncRoutes)
+      } catch (error) {
+        reject(error)
+      }
+    })
+  },
+  // user logout
+  logout({
+    commit,
+    state
+  }) {
+    return new Promise((resolve, reject) => {
+      logout(state.token).then(() => {
+        removeToken() // must remove  token  first
+        resetRouter()
+        commit('RESET_STATE')
+        resolve()
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+
+  // remove token
+  resetToken({
+    commit
+  }) {
+    return new Promise(resolve => {
+      removeToken() // must remove  token  first
+      commit('RESET_STATE')
+      resolve()
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 3 - 1
src/utils/request.js

@@ -44,6 +44,9 @@ service.interceptors.response.use(
   response => {
     const res = response.data
     // if the custom code is not 20000, it is judged as an error.
+     if(res.data instanceof Blob){
+      return res.data
+    }
     if (res.code && res.code !== 200 && res.code !== '200') {
       Message({
         message: res.message || 'Error',
@@ -71,7 +74,6 @@ service.interceptors.response.use(
       }else{
         return res
       }
-      
     }
   },
   error => {

+ 375 - 0
src/views/login/index - 副本.vue

@@ -0,0 +1,375 @@
+<template>
+  <div class="login-container">
+    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
+      label-position="left">
+      <div class="title-container">
+        <h3 class="title">畅运通管理平台</h3>
+      </div>
+
+      <el-form-item prop="username">
+        <span class="svg-container">
+          <svg-icon icon-class="user" />
+        </span>
+        <el-input ref="username" v-model="loginForm.username" placeholder="请输入您的账号" name="username" type="text"
+          maxlength="11" tabindex="1" auto-complete="on" />
+      </el-form-item>
+
+      <el-form-item prop="password">
+        <span class="svg-container">
+          <svg-icon icon-class="password" />
+        </span>
+        <el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType"
+          placeholder="请输入登录密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" />
+        <span class="show-pwd" @click="showPwd">
+          <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
+        </span>
+      </el-form-item>
+      <el-form-item prop="code">
+        <el-row :span="24" style="display: flex;align-items: center;">
+          <el-col :span="12">
+            <el-input v-model="loginForm.code" auto-complete="off" placeholder="请输入验证码" size=""
+              @keyup.enter.native="submitForm('loginForm')"></el-input>
+          </el-col>
+          <el-col :span="12" style="display: flex;justify-content: flex-end;">
+            <div class="login-code" @click="refreshCode">
+              <!--验证码组件-->
+              <s-identify :identifyCode="identifyCode"></s-identify>
+            </div>
+          </el-col>
+        </el-row>
+      </el-form-item>
+      <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;"
+        @click.native.prevent="handleLogin">进入</el-button>
+
+      <!-- <div class="tips">
+        <span style="margin-right:20px;">username: admin</span>
+        <span>password: any</span>
+      </div> -->
+    </el-form>
+  </div>
+</template>
+
+<script>
+  import Cookies from 'js-cookie'
+  import {
+    mapActions
+  } from 'vuex'
+  import {
+    validUsername,
+    isLoginName
+  } from '@/utils/validate'
+  import SIdentify from './sidentify'
+  export default {
+    name: 'Login',
+    components: {
+      SIdentify
+    },
+    data() {
+      const validateUsername = (rule, value, callback) => {
+        if (!validUsername(value)) {
+          callback(new Error('请输入正确的账号'))
+        } else {
+          callback()
+        }
+      }
+      const validatePassword = (rule, value, callback) => {
+        if (value.length < 6) {
+          callback(new Error('请输入正确的密码'))
+        } else {
+          callback()
+        }
+      }
+      const validateCode = (rule, value, callback) => {
+        if (this.identifyCode !== value) {
+          this.loginForm.code = ''
+          this.refreshCode()
+          callback(new Error('请输入正确的验证码'))
+        } else {
+          callback()
+        }
+      }
+      return {
+        isDebugLogin: false,
+        loginForm: {
+          username: '',
+          password: '',
+          code: ''
+        },
+        identifyCodes: '1234567890',
+        identifyCode: '',
+        loginRules: {
+          username: [{
+              required: true,
+              trigger: 'blur',
+              message: '请输入用户名'
+            },
+            {
+              min: 1,
+              max: 200,
+              message: '长度在1-200字符之间',
+              trigger: 'blur'
+            },
+            {
+              validator: isLoginName,
+              trigger: 'blur'
+            }
+          ],
+          password: [{
+              required: true,
+              message: '请输入密码',
+              trigger: 'blur'
+            },
+            {
+              min: 1,
+              max: 100,
+              message: '长度在1-100字符之间',
+              trigger: 'blur'
+            }
+          ],
+          code: [{
+              required: true,
+              message: '请输入验证码',
+              trigger: 'blur'
+            },
+            {
+              validator: validateCode,
+              trigger: 'blur'
+            }
+          ]
+        },
+        loading: false,
+        rememberMe: true,
+        passwordType: 'password',
+        redirect: undefined
+      }
+    },
+    watch: {
+      $route: {
+        handler: function(route) {
+          this.redirect = route.query && route.query.redirect
+        },
+        immediate: true
+      },
+      isDebugLogin(v) {
+        if (v) {
+          this.loginForm.password = '123'
+          this.refreshCode()
+        }
+      },
+      identifyCode(v) {
+        this.isDebugLogin && (this.loginForm.code = v)
+      }
+    },
+    methods: {
+      ...mapActions('user', ['login']),
+      randomNum(min, max) {
+        return Math.floor(Math.random() * (max - min) + min)
+      },
+      refreshCode() {
+        this.identifyCode = ''
+        this.makeCode(this.identifyCodes, 4)
+      },
+      makeCode(o, l) {
+        for (let i = 0; i < l; i++) {
+          this.identifyCode += this.identifyCodes[
+            this.randomNum(0, this.identifyCodes.length)
+          ]
+        }
+      },
+      showPwd() {
+        if (this.passwordType === 'password') {
+          this.passwordType = ''
+        } else {
+          this.passwordType = 'password'
+        }
+        this.$nextTick(() => {
+          this.$refs.password.focus()
+        })
+      },
+      handleLogin() {
+        this.$refs.loginForm.validate(async (valid) => {
+          if (valid) {
+            this.loginForm.companyName = '黑龙江中天昊元贸易有限公司'
+            this.loading = true
+            // this.$store.dispatch('user/login', this.loginForm)
+            // const res = await this.$store.dispatch('user/login', this.loginForm)
+            const res = await this.login(this.loginForm)
+            debugger
+            localStorage.setItem('ws_login_type', 2)
+            Cookies.set('ws_login_companyShortName', this.loginForm.companyName, {
+              expires: 365,
+            })
+            Cookies.set('ws_login_account', this.loginForm.username, {
+              expires: 365,
+            })
+            if (this.rememberMe) {
+              Cookies.set('ws_login_pwd', this.loginForm.password, {
+                expires: 365,
+              })
+              Cookies.set('ws_login_rememberMe', 1, {
+                expires: 365
+              })
+            } else {
+              Cookies.remove('ws_login_companyShortName')
+              Cookies.remove('ws_login_account')
+              Cookies.remove('ws_login_pwd')
+              Cookies.set('ws_login_rememberMe', 0, {
+                expires: 365
+              })
+            }
+            const redirect = this.$route.query.redirect
+            if (redirect) {
+              this.$router.push(redirect)
+            } else {
+              this.$router.push('/')
+            }
+            // .then(response => {
+            //   localStorage.setItem('UserInfo', JSON.stringify(response.data))
+            //   this.$router.push({
+            //     path: this.redirect || '/'
+            //   })
+            //   this.loading = false
+            // })
+            // .catch(() => {
+            //   this.loading = false
+            // })
+          } else {
+            console.log('error submit!!')
+            return false
+          }
+        })
+      }
+    },
+    created() {
+      this.refreshCode()
+    }
+  }
+</script>
+
+<style lang="scss">
+  /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
+
+  $bg: #283443;
+  $light_gray: #fff;
+  $cursor: #fff;
+
+  @supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
+    .login-container .el-input input {
+      color: $cursor;
+    }
+  }
+
+  /* reset element-ui css */
+  .login-container {
+    .el-input {
+      display: inline-block;
+      height: 47px;
+      width: 85%;
+
+      input {
+        background: transparent;
+        border: 0px;
+        -webkit-appearance: none;
+        border-radius: 0px;
+        padding: 12px 5px 12px 15px;
+        color: $light_gray;
+        height: 47px;
+        caret-color: $cursor;
+
+        &:-webkit-autofill {
+          box-shadow: 0 0 0px 1000px $bg inset !important;
+          -webkit-text-fill-color: $cursor !important;
+        }
+      }
+    }
+
+    .el-form-item {
+      border: 1px solid rgba(255, 255, 255, 0.1);
+      background: rgba(0, 0, 0, 0.1);
+      border-radius: 5px;
+      color: #454545;
+    }
+  }
+</style>
+
+<style lang="scss" scoped>
+  $bg: #2d3a4b;
+  $dark_gray: #889aa4;
+  $light_gray: #eee;
+
+  .login-container {
+    min-height: 100%;
+    width: 100%;
+    background-color: $bg;
+    overflow: hidden;
+
+    .login-form {
+      position: relative;
+      width: 520px;
+      max-width: 100%;
+      padding: 160px 35px 0;
+      margin: 0 auto;
+      overflow: hidden;
+    }
+
+    .tips {
+      font-size: 14px;
+      color: #fff;
+      margin-bottom: 10px;
+
+      span {
+        &:first-of-type {
+          margin-right: 16px;
+        }
+      }
+    }
+
+    .svg-container {
+      padding: 6px 5px 6px 15px;
+      color: $dark_gray;
+      vertical-align: middle;
+      width: 30px;
+      display: inline-block;
+    }
+
+    .title-container {
+      position: relative;
+
+      .title {
+        font-size: 26px;
+        color: $light_gray;
+        margin: 0px auto 40px auto;
+        text-align: center;
+        font-weight: bold;
+      }
+    }
+
+    .show-pwd {
+      position: absolute;
+      right: 10px;
+      top: 7px;
+      font-size: 16px;
+      color: $dark_gray;
+      cursor: pointer;
+      user-select: none;
+    }
+  }
+
+  .login-code {
+    cursor: pointer;
+    margin-right: 5px;
+
+    .login-code-img {
+      width: 100px;
+      height: 38px;
+      background-color: #eee;
+      border: 1px solid #f0f0f0;
+      color: #333;
+      font-size: 18px;
+      font-weight: bold;
+      letter-spacing: 2px;
+      text-indent: 2px;
+      text-align: center;
+    }
+  }
+</style>

+ 6 - 11
src/views/operationLog/logManagement.vue

@@ -4,7 +4,7 @@
     <div class="center_css">
       <div class="top_css">
         <el-row>
-          <el-col :span="16" style="height: 45px">
+          <el-col :span="14" style="height: 45px">
             <span type="primary" class="batch_text">
               <i class="el-icon-tickets"></i>数据列表</span>
             <el-button type="danger" plain icon="el-icon-delete" size="small" @click="delBtn()">删除</el-button>
@@ -14,7 +14,7 @@
               range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
             </el-date-picker>
           </el-col>
-          <el-col :span="8" style="height: 45px">
+          <el-col :span="10" style="height: 45px">
             <div class="screen">
               <el-input class="find" placeholder="可按系统模块,操作人员进行筛选" @keyup.enter.native="find" v-model="searchkeyWord"
                 clearable @change="find"></el-input>
@@ -185,9 +185,9 @@
           let a = document.createElement("a");
           //由于后台返回文件名称是通过response返回的
           //因此需要从response headers中content-disposition响应头中获取文件名称fileName,如上图所示
-          let headers = response.headers;
-          let fileName = headers["content-disposition"];
-          fileName = fileName.split('=')[1]
+          // let headers = response.headers;
+          // let fileName = headers["content-disposition"];
+          // fileName = fileName.split('=')[1]
           //download是a标签的一个属性,可以自定义文件名称
           a.download = "日志记录.xlsx";
           let binaryData = [];
@@ -197,12 +197,6 @@
           document.body.appendChild(a);
           a.click();
           document.body.removeChild(a);
-          //  downloadFile({
-          // res: response,
-          // fileName: `导出日志记录`,
-          // type: "xls",
-          // });
-
         });
         // const {
         //   data
@@ -362,6 +356,7 @@
         text-align: center;
         line-height: 40px;
         color: #666666;
+        min-width: 80px;
       }
     }
 

+ 8 - 1
src/views/parkReportManagement/driverInformationReporting.vue

@@ -98,7 +98,14 @@
             </el-tooltip>
           </template>
         </el-table-column>
-        <el-table-column prop="escalationStatus" label="状态" min-width="100"></el-table-column>
+        <el-table-column prop="escalationStatus" label="状态" min-width="100">
+          <template slot-scope="scope">
+            <span>{{scope.row.escalationStatus}}</span>
+              <el-tooltip class="item" effect="dark" content="提示文字" placement="top" v-if="scope.row.escalationStatus == '未通过'">
+                 <img src="../../../public/img/wenhao.png" alt="" class="ask_css" />
+              </el-tooltip>
+          </template>
+        </el-table-column>
         <el-table-column label="操作" min-width="200">
           <template slot-scope="scope">
             <el-link target="_blank" @click="see(scope.row)" type="primary" :underline="false"

+ 1 - 1
vue.config.js

@@ -55,7 +55,7 @@ module.exports = {
         },
         proxy: {
             '/pb': {
-                target: 'http://192.168.110.67:8999/', 
+                target: 'http://192.168.110.9:8099/', 
                 // target: 'http://192.168.110.9:8099/',       
                 // target: 'https://apitest.eliangeyun.com',
                 changeOrigin: true, // 开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题