This commit is contained in:
熊成强 2020-10-14 14:34:58 +08:00
parent 856c467d12
commit b4c31f9383
20 changed files with 503 additions and 94 deletions

View File

@ -50,6 +50,14 @@ module.exports = {
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/icons')],
options: {
symbolId: 'icon-[name]'
}
},
{
test: /\.js$/,
loader: 'babel-loader',
@ -58,6 +66,7 @@ module.exports = {
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
exclude: [resolve('src/icons')],
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')

View File

@ -3,5 +3,6 @@ const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
NODE_ENV: '"development"',
APP_BASE_API:'/linzi-kpi'
})

View File

@ -10,7 +10,12 @@ module.exports = {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
proxyTable: {
'/linzi-kpi': {
target: `http://tbaidu.com`,
changeOrigin: true
}
},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST

View File

@ -1,4 +1,5 @@
'use strict'
module.exports = {
NODE_ENV: '"production"'
NODE_ENV: '"production"',
APP_BASE_API:'/linzi-kpi'
}

View File

@ -14,9 +14,11 @@
"build": "node build/build.js"
},
"dependencies": {
"axios": "^0.20.0",
"element-ui": "^2.13.2",
"less": "3.9",
"less-loader": "5.0.0",
"svg-sprite-loader": "^5.0.0",
"vue": "^2.5.2",
"vue-router": "^3.0.1"
},

18
src/api/data.js Normal file
View File

@ -0,0 +1,18 @@
import request from '@/utils/request'
const baseUrl = process.env.APP_BASE_API
export function getCaseCollectorListPage (query) {
return request({
url: baseUrl + '/caseCollector/caseCollectorListPage',
method: 'get',
params: query
})
}
export function apiCaseCenterExport (query) {
return request({
url: '/market-api/marketCaseExport/exportMarketCaseDataList',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@ -0,0 +1,43 @@
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"/>
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
iconName () {
return `#icon-${this.iconClass}`
},
svgClass () {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>

View File

@ -1,7 +1,9 @@
<!-- -->
<template>
<div class="appamin">
<transition name="fade" mode="out-in">
<router-view ></router-view>
</transition>
</div>
</template>
@ -28,6 +30,20 @@ export default {
background: transparent;
flex: 1;
box-sizing: border-box;
padding: 60px 40px 0;
padding: 60px 80px 0;
}
</style>
<style lang="less">
.fade-enter {
opacity: 0;
transform: translateX(10px);
}
.fade-leave{
transform: translateX(10px);
opacity: 1;
}
.fade-leave-active,.fade-enter-active {
transition:all 0.1s;
}
</style>

View File

@ -0,0 +1,163 @@
<!-- -->
<template>
<div class="navBar">
<transition name="fade" mode="out-in">
<ul v-if="isNav" class='navBar-left'>
<li
v-for="(i,index) in routeList"
:key="index"
:class="{active:title.includes(i.name)}"
@click="handleToRouter(i.name)"
>
{{i.meta.title}}</li>
</ul>
<div class="noNav" v-if="!isNav">
<div class="noNav-left">
<i @click="handleBack" class="el-icon-arrow-left"></i>
</div>
<!-- <svg-icon icon-class="analyze" /> -->
<div>{{name}}</div>
</div>
</transition>
<div class="navBar-right" v-if="isNav">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2346299354,1694591848&fm=26&gp=0.jpg" alt="">
</div>
</div>
</template>
<script>
import routeList from '@/router/kpi_route'
console.log('_route: ', routeList[0].children)
export default {
name: 'NavBar',
data () {
return {
routeList: routeList[0].children.filter(i => i.meta.isNav),
activeIndex: '1',
activeIndex2: '1'
}
},
computed: {
isPopup () {
return !!this.$route.meta.pop
},
name () {
return this.$route.meta.title
},
isNav () {
return !!this.$route.meta.isNav
},
title () {
return this.$route.fullPath
}
},
beforeMount () {},
mounted () {
console.log('this.$route', this.$route)
},
methods: {
handleBack () {
if (this.isPopup) return this.open()
this.$router.go(-1)
},
handleToRouter (item) {
if (this.title.includes(item)) return
this.$router.push({name: item})
},
handleSelect (key, keyPath) {
console.log(key, keyPath)
},
open () {
const obj = {
popupTitle: this.$route.meta.popupTitle || '有修改的内容未保存,确认离开吗?',
popupContent: this.$route.meta.popupContent || '系统可能不会保存您做的更改。'
}
this.$confirm(obj.popupContent, obj.popupTitle, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$router.go(-1)
}).catch(() => { })
}
},
watch: {
}
}
</script>
<style lang='less' scoped>
.navBar{
width: 100%;
height: 60px;
box-sizing: border-box;
justify-content: space-between;
display: flex;
align-items: center;
background: #ffffff;
padding: 0 40px;
box-shadow: 0 1px 6px 0 rgba(0,0,0,.12), 0 1px 6px 0 rgba(0,0,0,.12);
&-right{
img{
width: 40px;
height: 40px;
border-radius: 50%;
}
}
&-left{
display: flex;
align-items: center;
li{
padding-right: 20px;
cursor:pointer;
}
}
}
.active{
color: #09f;
}
.noNav{
height: 40px;
display: flex;
align-items: center;
&-left{
width: 60px;
height: 30px;
display: flex;
align-items: center;
border-right: 1px solid #c0c0c0;
margin-right: 20px;
i{
font-size: 22px;
cursor:pointer;
}
}
}
</style>
<style lang='less' scoped>
.appamin{
background: transparent;
flex: 1;
box-sizing: border-box;
padding: 60px 80px 0;
}
</style>
<style lang="less">
.fade-enter {
opacity: 0;
transform: translateX(10px);
}
.fade-leave{
transform: translateX(10px);
opacity: 1;
}
.fade-leave-active,.fade-enter-active {
transition:all 0.1s;
}
</style>

View File

@ -1,75 +0,0 @@
<!-- -->
<template>
<div class="navBar">
<ul class='navBar-left'>
<li
v-for="(i,index) in routeList"
:key="index"
:class="{active:title.includes(i.name)}"
@click="handleToRouter(i.name)"
>
{{i.meta.title}}</li>
</ul>
</div>
</template>
<script>
import routeList from '@/router/kpi_route'
console.log('_route: ', routeList[0].children)
export default {
name: 'NavBar',
data () {
return {
routeList: routeList[0].children,
activeIndex: '1',
activeIndex2: '1'
}
},
computed: {
title () {
return this.$route.fullPath
}
},
beforeMount () {},
mounted () {
console.log('this.$route', this.$route)
},
methods: {
handleToRouter (item) {
if (this.title.includes(item)) return
this.$router.push({name: item})
},
handleSelect (key, keyPath) {
console.log(key, keyPath)
}
},
watch: {}
}
</script>
<style lang='less' scoped>
.navBar{
width: 100%;
height: 60px;
box-sizing: border-box;
padding: 0 40px;
display: flex;
align-items: center;
background: #ffffff;
box-shadow: 0 1px 6px 0 rgba(0,0,0,.12), 0 1px 6px 0 rgba(0,0,0,.12);
&-left{
display: flex;
align-items: center;
li{
padding-right: 20px;
cursor:pointer;
}
}
}
.active{
color: #09f;
}
</style>

10
src/icons/index.js Normal file
View File

@ -0,0 +1,10 @@
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon' // svg组件
// register globally
Vue.component('svg-icon', SvgIcon)
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)
console.log('requireAll(req): ', requireAll(req))

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><path d="M21.333 42.667h21.333V21.333H21.333v21.334zm32 63.999h21.333V85.334H53.333v21.332zm-32 0h21.333V85.334H21.333v21.332zm0-32h21.333V53.333H21.333v21.333zm32 0h21.333V53.333H53.333v21.333zm32.001-53.333v21.333h21.332V21.333H85.334zM53.333 42.667h21.333V21.333H53.333v21.334zm32.001 31.999h21.332V53.333H85.334v21.333zm0 32h21.332V85.334H85.334v21.332z"/></svg>

After

Width:  |  Height:  |  Size: 431 B

22
src/icons/svgo.yml Normal file
View File

@ -0,0 +1,22 @@
# replace default config
# multipass: true
# full: true
plugins:
# - name
#
# or:
# - name: false
# - name: true
#
# or:
# - name:
# param1: 1
# param2: 2
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'

View File

@ -3,13 +3,19 @@
import Vue from 'vue'
import App from './App'
import router from './router'
import { Menu, MenuItem, Submenu } from 'element-ui'
import {
Button,
MessageBox,
Message
} from 'element-ui'
import './style/public.css'
import '@/icons'
Vue.use(Menu)
Vue.use(MenuItem)
Vue.use(Submenu)
Vue.use(Button)
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm
Vue.prototype.$alert = MessageBox.alert
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({

View File

@ -2,7 +2,7 @@ export default [
{
path: '/kpi',
name: 'kpi',
component: (resolve) => require(['@/components/layout/index.vue'], resolve),
component: (resolve) => require(['@/components/kpi-layout/index.vue'], resolve),
redirect: 'kpi/workbench',
meta: {
title: '智能绩效',
@ -13,35 +13,55 @@ export default [
name: 'workbench',
component: (resolve) => require(['@/views/kpi/workbench/index.vue'], resolve),
meta: {
title: '工作台'
title: '工作台',
isNav: true
}
}, {
path: 'assessment',
name: 'assessment',
component: (resolve) => require(['@/views/kpi/assessment/index.vue'], resolve),
meta: {
title: '考核管理'
title: '考核管理',
isNav: true
}
}, {
path: 'okr',
name: 'okr',
component: (resolve) => require(['@/views/kpi/okr/index.vue'], resolve),
meta: {
title: 'OKR'
title: 'OKR',
isNav: true
}
}, {
path: 'report',
name: 'report',
component: (resolve) => require(['@/views/kpi/report/index.vue'], resolve),
meta: {
title: '绩效报表'
title: '绩效报表',
isNav: true
}
}, {
path: 'set',
name: 'set',
component: (resolve) => require(['@/views/kpi/set/index.vue'], resolve),
meta: {
title: '设置'
title: '设置',
isNav: true
}
}, {
path: 'home',
name: 'home',
component: (resolve) => require(['@/views/kpi/home/index.vue'], resolve),
meta: {
title: '智能测试'
}
}, {
path: 'home1',
name: 'home1',
component: (resolve) => require(['@/views/kpi/home1/index.vue'], resolve),
meta: {
title: '智能测试带弹窗',
pop: true
}
} ]
}

86
src/utils/request.js Normal file
View File

@ -0,0 +1,86 @@
import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
// axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
// baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 1500000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
// const isToken = (config.headers || {}).isToken === false
// if (getToken() && !isToken) {
// config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
// }
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
if (code === 401) {
// MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
// confirmButtonText: '重新登录',
// cancelButtonText: '取消',
// type: 'warning'
// }
// ).then(() => {
// store.dispatch('LogOut').then(() => {
// location.href = '/market-ui/login';
// })
// })
} else if (code === 500) {
Message({
message: msg,
type: 'error'
})
return Promise.reject(new Error(msg))
} else if (code !== 200) {
Notification.error({
title: msg
})
return Promise.reject('error')
} else {
if(res.config.responseType === 'blob'){
return res
}
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service

View File

@ -2,6 +2,8 @@
<template>
<div>
考核管理
<el-button type="success" @click="handleToHome('home')">去二级页面</el-button>
<el-button type="success" @click="handleToHome('home1')">去二级页面带弹窗</el-button>
</div>
</template>
@ -15,7 +17,11 @@ export default {
computed: {},
beforeMount () {},
mounted () {},
methods: {},
methods: {
handleToHome (i) {
this.$router.push({name: i})
}
},
watch: {}
}

View File

@ -0,0 +1,29 @@
<!-- -->
<template>
<div>
home
</div>
</template>
<script>
export default {
data () {
return {
}
},
computed: {},
beforeMount () {},
mounted () {
console.log('this.$route', this.$route)
},
methods: {},
watch: {}
}
</script>
<style lang='' scoped>
</style>

View File

@ -0,0 +1,46 @@
<!-- -->
<template>
<div>
home
</div>
</template>
<script>
export default {
data () {
return {
}
},
// beforeRouteLeave (to, from, next) {
// console.log('123')
// next(false)
// // ...
// },
computed: {},
beforeMount () {},
mounted () {
console.log('this.$route', this.$route)
},
methods: {
open () {
this.$alert('这是一段内容', '标题名称', {
confirmButtonText: '确定',
callback: action => {
this.$message({
type: 'info',
message: `action: ${action}`
})
}
})
}
},
watch: {}
}
</script>
<style lang='' scoped>
</style>