Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/H5/shehong-vehicle-supervision
| | |
| | | <template>
|
| | | <div>
|
| | | <div class="header">
|
| | | <div class="sticky top0">
|
| | | <div class="header relative">
|
| | | <div class="title">
|
| | | <img src="@/assets/logo.png" alt="">
|
| | | 射洪“两客一危”监管平台
|
| | | </div>
|
| | | <div></div>
|
| | | <div class="flex a-center pr--40">
|
| | | <div class="flex a-center mr--72">
|
| | | <img src="@/assets/header/photo.png" class="w--32 h--32 shrink0 mr--10" />
|
| | | <div class="fs-- 18 lh--25 color2">admin</div>
|
| | | </div>
|
| | | <div class="dropdown" @mouseenter="toggleDropdown(true)" @mouseleave="toggleDropdown(false)">
|
| | | <img src="@/assets/header/more.png" class="w--16 h--16" />
|
| | | <div v-if="isOpen" class="dropdown-menu">
|
| | | <div class="dropdown-item" v-for="item in menuItems" :key="item.text">
|
| | | <i :class="item.icon"></i> {{ item.text }}
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | <div class="menu w100 bgColor1">
|
| | |
|
| | | <div v-for="(item, index) in routesList" :key="index" class="flex a-center h100">
|
| | | <div v-for="(item2, index2) in item.children" :key="index2" class="h100">
|
| | | <div v-if="!item2.hide" class="flex a-center h100 px--40 menuItemHover pointer"
|
| | | :class="item2.path == $route.path && 'bgColor2'">
|
| | | <img :src="require(`@/assets/routerIcon/${item2.icon}.png`)"
|
| | | class="w--15 h--15 mr--12 shrink0" />
|
| | | <div class="color1">
|
| | | {{ item2.title }}
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | <router-view :key="key"></router-view>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script>
|
| | | import routes from '@/router/router'
|
| | | export default {
|
| | | data() {
|
| | | return {
|
| | | activeIndex2: '1'
|
| | | routesList: routes,
|
| | | isOpen: false,
|
| | | menuItems: [
|
| | | { text: '密码设置' },
|
| | | { text: '退出登录' },
|
| | | ]
|
| | | };
|
| | | },
|
| | | computed: {
|
| | | key() {
|
| | | return this.$route.path
|
| | | },
|
| | | created() {
|
| | | },
|
| | | methods: {
|
| | | handleSelect(key, keyPath) {
|
| | | console.log(key, keyPath);
|
| | | toggleDropdown(state) {
|
| | | this.isOpen = state;
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | background-color: #0E6EFD;
|
| | | }
|
| | |
|
| | | .bgColor2 {
|
| | | background: #0D55B9;
|
| | | }
|
| | |
|
| | | .color1 {
|
| | | color: #fff;
|
| | | }
|
| | |
|
| | | .color2 {
|
| | | color: rgba(0, 0, 0, .6);
|
| | | }
|
| | |
|
| | | .header {
|
| | | height: 80px;
|
| | | background: #fff;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | justify-content: space-between;
|
| | |
|
| | | .title {
|
| | | display: flex;
|
| | |
| | | font-weight: 600;
|
| | | font-size: 24px;
|
| | | align-items: center;
|
| | | position: absolute;
|
| | | top: 50%;
|
| | | left: 50%;
|
| | | transform: translate(-50%, -50%);
|
| | | color: rgba(0, 0, 0, .8);
|
| | |
|
| | | img {
|
| | | width: 40px;
|
| | |
| | |
|
| | | .menu {
|
| | | height: 60px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: center;
|
| | | }
|
| | |
|
| | | .menuItemHover:hover {
|
| | | background: #0D55B9;
|
| | | }
|
| | |
|
| | | .dropdown {
|
| | | position: relative;
|
| | | display: inline-block;
|
| | | cursor: pointer;
|
| | | }
|
| | |
|
| | | .dropdown-menu {
|
| | | position: absolute;
|
| | | top: 100%;
|
| | | left: 0;
|
| | | transform: translateX(-50%);
|
| | | background: white;
|
| | | border: 1px solid #ccc;
|
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
| | | z-index: 1000;
|
| | | border-radius: 8px;
|
| | | }
|
| | |
|
| | | .dropdown-item {
|
| | | padding: 8px 16px;
|
| | | white-space: nowrap;
|
| | | /* 防止文本换行 */
|
| | | }
|
| | |
|
| | | .dropdown-item:hover {
|
| | | background-color: #f0f0f0;
|
| | | /* 添加 hover 效果 */
|
| | | }
|
| | | </style> |
| | |
| | | import Vue from 'vue'
|
| | | import App from './App.vue'
|
| | |
|
| | | import './assets/tailwind.css'
|
| | | import router from './router'
|
| | | import store from './store'
|
| | |
|
| | | import cookies from 'vue-cookies'
|
| | | Vue.prototype.$cookies = cookies;
|
| | |
|
| | | import ElementUI from 'element-ui';
|
| | | import cookies from 'vue-cookies'
|
| | | import apiConfig from './utils/baseurl'
|
| | |
|
| | | Vue.use(ElementUI)
|
| | |
|
| | | Vue.prototype.$cookies = cookies;
|
| | | Vue.prototype.$baseURL = apiConfig.baseURL
|
| | | Vue.config.productionTip = false
|
| | | Vue.filter('formatNumber', (num) => {
|
| | | if (num != 0 && num < 1000 && num.toString().split('.').length == 1) {
|
| | | return num + '.0'
|
| | | }
|
| | | if (num && num >= 1000) {
|
| | | if (num.toString().split('.').length == 1) {
|
| | | return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ".0"
|
| | | }
|
| | | return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
| | | }
|
| | | return num || 0
|
| | | })
|
| | |
|
| | |
|
| | | new Vue({
|
| | |
| | | import Vue from 'vue'
|
| | | import Router from 'vue-router'
|
| | | import routes from './router'
|
| | | import store from '@/store' // 导入 Vuex store
|
| | |
|
| | | const changePush = Router.prototype.push;
|
| | | Router.prototype.push = function push(location) {
|
| | |
| | | })
|
| | |
|
| | | const router = createRouter()
|
| | | export function resetRouter() {
|
| | | const newRouter = createRouter()
|
| | | router.matcher = newRouter.matcher // reset router
|
| | | }
|
| | |
|
| | | // 路由守卫
|
| | | // router.beforeEach((to, from, next) => {
|
| | | // const token = store.state.token
|
| | | // if (!token && to.path != '/') {
|
| | | // // 如果没有 token 并且不是去登录页,重定向到登录页
|
| | | // next('/')
|
| | | // } else if (token && to.path === '/') {
|
| | | // // 如果有 token 并且要去登录页,重定向到首页
|
| | | // next('/home')
|
| | | // } else {
|
| | | // // 清理 localStorage
|
| | | // localStorage.removeItem('registerForm')
|
| | | // next()
|
| | | // }
|
| | | // })
|
| | |
|
| | | export default router
|
| | |
| | | import Layout from '@/layouts'
|
| | | /**
|
| | | * icon
|
| | | * home: 首页
|
| | | * alarm: 报警
|
| | | * car: 车辆
|
| | | * company: 公司
|
| | | * complaint: 投诉
|
| | | * sys: 系统
|
| | | * order: 订单
|
| | | * |
| | | * hide: true, // 是否隐藏
|
| | | * |
| | | */
|
| | |
|
| | | export default [
|
| | | {
|
| | | path: '/',
|
| | | component: () => import('@/view/login'),
|
| | | },
|
| | | {
|
| | | path: '/home',
|
| | | component: Layout,
|
| | | children: [
|
| | | {
|
| | | path: '/',
|
| | | path: '/home',
|
| | | component: () => import('@/view/home'),
|
| | | title: '首页',
|
| | | icon: 'home'
|
| | | },
|
| | | {
|
| | | path: '/early-warning',
|
| | | component: () => import('@/view/early-warning'),
|
| | | meta: {
|
| | | title: '首页'
|
| | | title: '报警记录',
|
| | | icon: 'home'
|
| | | }
|
| | | },
|
| | | {
|
| | | path: '/complaint',
|
| | | component: () => import('@/view/complaint/index'),
|
| | | meta: {
|
| | | title: '投诉记录'
|
| | | }
|
| | | }
|
| | | ]
|
| | | },
|
| | | ] |
| | | |
| | | ]
|
| | |
| | | import Vue from 'vue'
|
| | | import Vuex from 'vuex'
|
| | | Vue.use(Vuex)
|
| | | import Vue from 'vue';
|
| | | import Vuex from 'vuex';
|
| | |
|
| | | const store = new Vuex.Store({
|
| | | Vue.use(Vuex);
|
| | |
|
| | | export default new Vuex.Store({
|
| | | state: {
|
| | | loginOrIndex: 'Login',
|
| | | subjectUI: 'darkBlue', // darkBlue BlueIndex Green Purple
|
| | | selectGoodsList: [],
|
| | | date: '',
|
| | | changeRouterClass: 'statistics'
|
| | | token: localStorage.getItem('token') || sessionStorage.getItem('token') || '',
|
| | | userInfo: {}
|
| | | },
|
| | | mutations: {
|
| | | SET_LOGIN_OR_INDEX(state, data) {
|
| | | state.loginOrIndex = data;
|
| | | setToken(state, token) {
|
| | | state.token = token;
|
| | | localStorage.setItem('token', token);
|
| | | },
|
| | | SET_SUBJECT_UI(state, data) {
|
| | | state.subjectUI = data;
|
| | | clearToken(state) {
|
| | | state.token = '';
|
| | | localStorage.clear();
|
| | | },
|
| | | SET_SELECT_GOODS_LIST(state, data) {
|
| | | state.selectGoodsList = data;
|
| | | },
|
| | | SET_DATE(state, data) {
|
| | | state.date = data;
|
| | | },
|
| | | SET_CHANGE_ROUTER_CLASS(state, data) {
|
| | | state.changeRouterClass = data;
|
| | | setUserInfo(state, userInfo) {
|
| | | state.userInfo = userInfo;
|
| | | }
|
| | | },
|
| | | actions: {
|
| | | setLoginOrIndex({ commit }, data) {
|
| | | commit('SET_LOGIN_OR_INDEX', data);
|
| | | },
|
| | | setSubjectUI({ commit }, data) {
|
| | | commit('SET_SUBJECT_UI', data);
|
| | | },
|
| | | setSelectGoodsList({ commit }, data) {
|
| | | commit('SET_SELECT_GOODS_LIST', data);
|
| | | },
|
| | | setDate({ commit }, data) {
|
| | | commit('SET_DATE', data);
|
| | | },
|
| | | setChangeRouterClass({ commit }, data) {
|
| | | commit('SET_CHANGE_ROUTER_CLASS', data);
|
| | | }
|
| | | }
|
| | | })
|
| | |
|
| | | export default store |
| | | actions: {},
|
| | | modules: {}
|
| | | }); |
| | |
| | | .flex-w {
|
| | | flex-wrap: wrap;
|
| | | }
|
| | | .flex-start{
|
| | |
|
| | | .flex-start {
|
| | | align-items: flex-start;
|
| | | }
|
| | |
|
| | | .j-between {
|
| | | justify-content: space-between;
|
| | | }
|
| | |
| | | position: absolute;
|
| | | }
|
| | |
|
| | | .sticky {
|
| | | position: -webkit-sticky;
|
| | | position: sticky;
|
| | | }
|
| | |
|
| | | .top0 {
|
| | | top: 0;
|
| | | }
|
| | |
|
| | | .h100 {
|
| | | height: 100%;
|
| | | }
|
New file |
| | |
| | | const apiConfig = { |
| | | // 开发环境 |
| | | development: { |
| | | baseURL: "", |
| | | }, |
| | | // 生产环境 |
| | | production: { |
| | | }, |
| | | }; |
| | | export default apiConfig[process.env.NODE_ENV]; |
| | |
| | | import axios from 'axios'
|
| | | import store from '@/store'
|
| | | import apiConfig from './baseurl'
|
| | | import store from '@/store' // 导入 Vuex store
|
| | |
|
| | | import {
|
| | | Message
|
| | | } from 'element-ui'
|
| | |
|
| | |
|
| | | const service = axios.create({
|
| | | // baseURL: `http://vwpmxwbhv59i.guyubao.com`,
|
| | | baseURL: `http://192.168.110.34:8081`,
|
| | | // baseURL: 'http://112.44.213.180:8081',
|
| | | baseURL: apiConfig.baseURL,
|
| | | withCredentials: false, // 当跨域请求时发送cookie
|
| | | timeout: 30000, // request timeout
|
| | | })
|
| | |
| | | // 请求拦截
|
| | | service.interceptors.request.use(
|
| | | config => {
|
| | | let token = ''
|
| | | let shopType = localStorage.getItem('shopStyle')
|
| | | switch (shopType) {
|
| | | case '1':
|
| | | token = localStorage.getItem('tokenBlue')
|
| | | break;
|
| | | case '2':
|
| | | token = localStorage.getItem('tokenGreen')
|
| | | break;
|
| | | case '3':
|
| | | token = localStorage.getItem('tokenDarkBlue')
|
| | | break;
|
| | | case '4':
|
| | | token = localStorage.getItem('tokenPurple')
|
| | | break;
|
| | | default:
|
| | | break;
|
| | | }
|
| | |
|
| | | // console.log(shopType,'shopType shopType shopType',token,'token token token');
|
| | | config['headers']['Authorization'] = `${token}`
|
| | | config.headers['Authorization'] = 'Bearer ' + store.state.token
|
| | | if (config.method == 'get') {
|
| | | if (!config.params) config.params = {};
|
| | | config.params = {
|
| | |
| | | }
|
| | | const res = response;
|
| | | if (res.data.code == 200) {
|
| | | if (!res.data) {
|
| | | if (!res.data.data) {
|
| | | return Promise.resolve({})
|
| | | }
|
| | | return Promise.resolve(res.data)
|
| | | return Promise.resolve(res.data.data)
|
| | | } else {
|
| | | if (res.data.code == 103 || res.data.code == 401) {
|
| | | Message({
|
| | |
| | | type: 'warning',
|
| | | duration: 2000
|
| | | })
|
| | | setTimeout(() => {
|
| | | let subjectUI = store.state.subjectUI
|
| | | switch (subjectUI) {
|
| | | case 'BlueIndex':
|
| | | localStorage.removeItem('shopStyle')
|
| | | localStorage.removeItem('tokenBlue')
|
| | | window.location.replace('/shop1/#/');
|
| | | break;
|
| | | case 'Green':
|
| | | localStorage.removeItem('shopStyle')
|
| | | localStorage.removeItem('tokenGreen')
|
| | | window.location.replace('/shop2/#/');
|
| | | break;
|
| | | case 'darkBlue':
|
| | | let obj = JSON.parse(localStorage.getItem('acountObj'))
|
| | | localStorage.setItem('acountObj', JSON.stringify(obj))
|
| | | localStorage.removeItem('shopStyle')
|
| | | localStorage.removeItem('tokenDarkBlue')
|
| | | window.location.replace('/shop3/#/');
|
| | | break;
|
| | | case 'Purple':
|
| | | localStorage.removeItem('shopStyle')
|
| | | localStorage.removeItem('tokenPurple')
|
| | | window.location.replace('/shop4/#/');
|
| | | break;
|
| | |
|
| | | default:
|
| | | break;
|
| | | }
|
| | | // if (store.state.subjectUI == 'BlueIndex' || store.state.subjectUI == 'Green' || store.state.subjectUI == 'Purple') {
|
| | | // localStorage.clear();
|
| | | // window.location.replace('/');
|
| | | // }
|
| | | // if (store.state.subjectUI == 'darkBlue') {
|
| | | // let obj = JSON.parse(localStorage.getItem('acountObj'))
|
| | | // localStorage.clear();
|
| | | // localStorage.setItem('acountObj', JSON.stringify(obj))
|
| | | // window.location.replace('/');
|
| | | // }
|
| | | }, 2000)
|
| | | return Promise.reject(res.data)
|
| | | store.commit('clearToken')
|
| | | window.location.replace(`/`);
|
| | | return Promise.reject(res.data.data)
|
| | | }
|
| | | Message({
|
| | | message: res.data.msg || '服务器错误',
|
| | | type: 'error',
|
| | | duration: 2000
|
| | | })
|
| | | return Promise.reject(res.data)
|
| | | return Promise.reject(res.data.data)
|
| | | }
|
| | | },
|
| | | error => {
|
| | | return Promise.reject(error.message)
|
| | | Message({
|
| | | message: error.message,
|
| | | type: 'error',
|
| | | duration: 5000
|
| | | })
|
| | | return Promise.reject(error)
|
| | | }
|
| | | )
|
| | |
|
| | | export default service
|
New file |
| | |
| | | <template> |
| | | <div> |
| | | <div class="form flex a-center j-between mt--23"> |
| | | <div class="form-left ml--30"> |
| | | <el-form :inline="true" :model="searchForm" class="demo-form-inline"> |
| | | <el-form-item label="预警类型:" prop="type" class="unset_m" style="margin-right: 15px;"> |
| | | <el-select :popper-append-to-body="false" v-model="searchForm.type" placeholder="请选择"> |
| | | <el-option label="全部" value=""></el-option> |
| | | <el-option label="预警" value="1"></el-option> |
| | | <el-option label="报警" value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="车辆号牌:" prop="level" class="unset_m" style="margin-right: 15px;"> |
| | | <el-input v-model="searchForm.level" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="驾驶员姓名:" prop="name" class="unset_m" style="margin-right: 15px;"> |
| | | <el-input v-model="searchForm.name" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="公司名称:" prop="name" class="unset_m" style="margin-right: 15px;"> |
| | | <el-input v-model="searchForm.name" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="预警时间:" prop="date" class="unset_m" style="margin-right: 15px;"> |
| | | <el-date-picker :append-to-body="false" v-model="searchForm.date" type="daterange" |
| | | range-separator=" " start-placeholder="开始日期" end-placeholder="结束日期"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="form-right mr--24 mb--22"> |
| | | <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-search" type="primary" size="small" |
| | | @click="search">查询</el-button> |
| | | <el-button @click="reset" icon="el-icon-refresh-right" class="reset-button h--40 w--90 fs--14" |
| | | size="small">重置</el-button> |
| | | </div> |
| | | |
| | | </div> |
| | | |
| | | <div class="table-box-btn mt--23 ml--30"> |
| | | <el-button class="search-button h--40 w--90 fs--14" icon="el-icon-top" type="primary" size="small" |
| | | @click="exportExcell">导出</el-button> |
| | | </div> |
| | | <div class="table-box ml--30 mt--23 mr--30"> |
| | | <el-table :data="tableData" border stripe style="width: 100%"> |
| | | <el-table-column prop="date" label="序号"></el-table-column> |
| | | <el-table-column prop="name" label="车辆名称"></el-table-column> |
| | | <el-table-column prop="name" label="车牌号码"></el-table-column> |
| | | <el-table-column prop="name" label="投诉内容"></el-table-column> |
| | | <el-table-column prop="name" label="投诉人电话"></el-table-column> |
| | | <el-table-column prop="name" label="被投诉所属公司"></el-table-column> |
| | | <el-table-column prop="name" label="被投诉驾驶员"></el-table-column> |
| | | <el-table-column prop="name" label="投诉时间"></el-table-column> |
| | | <el-table-column prop="name" label="操作"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="handle(scope.$index, scope.row)">处理</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div class="pagination-box relative mt--23 flex j-end"> |
| | | <el-pagination :popper-append-to-body="false" @size-change="handleSizeChange" @current-change="handleCurrentChange" |
| | | :current-page="searchForm.page" background layout="total,sizes,prev, pager, next,jumper" |
| | | :total="searchForm.total" > |
| | | </el-pagination> |
| | | </div> |
| | | </div> |
| | | |
| | | |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { search } from 'core-js/fn/symbol'; |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | searchForm: { |
| | | date: '', |
| | | type: '', |
| | | level: '', |
| | | name: '', |
| | | total: 40, |
| | | page: 1, |
| | | pageSize: 10 |
| | | }, |
| | | tableData: [], |
| | | }; |
| | | }, |
| | | methods: { |
| | | reset() { |
| | | }, |
| | | search() { |
| | | |
| | | }, |
| | | exportExcell() { |
| | | |
| | | }, |
| | | handleSizeChange(e) { |
| | | this.searchForm.pageSize = e |
| | | }, |
| | | handleCurrentChange(e) { |
| | | this.searchForm.page = e |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .search-button { |
| | | height: 40px !important; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template>
|
| | | <div>
|
| | | <p>当前路径:{{ $route.path }}</p>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script>
|
| | | export default {
|
| | | data() {
|
| | | return {
|
| | | activeIndex: '1',
|
| | | activeIndex2: '1'
|
| | | };
|
| | | },
|
| | | methods: {
|
| | | handleSelect(key, keyPath) {
|
| | | console.log(key, keyPath);
|
| | | }
|
| | | }
|
| | | }
|
| | | </script>
|
| | |
|
| | | <style></style> |
New file |
| | |
| | | <template> |
| | | <div class="flex a-center"> |
| | | <div>射洪“两客一危”监管平台</div> |
| | | <div></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | components: {}, |
| | | props: {}, |
| | | data() { |
| | | return {}; |
| | | }, |
| | | computed: {}, |
| | | watch: {}, |
| | | created() { }, |
| | | mounted() { }, |
| | | methods: {}, |
| | | }; |
| | | </script> |
| | | <style scoped lang="less"></style> |
New file |
| | |
| | | import axios from '@/utils/request'; |
| | | |
| | | // 密码登录 |
| | | export const loginPwd = (data) => { |
| | | return axios.post('/auth/companyLogin', data) |
| | | } |
| | |
| | | devServer: {
|
| | | proxy: { //跨域配置
|
| | | "/api": { //是自定义的本地请求时的名字
|
| | | // target: "http://192.168.110.64:8000",
|
| | | target: "http://vwpmxwbhv59i.guyubao.com",
|
| | | target: "",
|
| | | changeOrigin: true, //在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
|
| | | pathRewrite: { //路径重写
|
| | | "^/api": "/" // '^/api'是一个正则表达式,表示要匹配请求的url中,全部 '/api' 转接为 '/'
|
| | |
| | | }
|
| | | }
|
| | | },
|
| | | configureWebpack: {
|
| | | resolve: {
|
| | | alias: {
|
| | | '@': resolve('src'),
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|