feat: npm部分内容

This commit is contained in:
chenjinsong
2021-07-05 17:40:43 +08:00
parent c35fb070a5
commit c426084934
10 changed files with 251 additions and 156 deletions

View File

@@ -27,7 +27,7 @@
class="inputstyle login__button"
@click="login"
style=" font-size: 16px;"
>登陆</el-button
>{{$t('common.login')}}</el-button
>
</el-form-item>
</el-form>
@@ -38,8 +38,6 @@
<script>
import { mapActions } from 'vuex'
import { post } from '@/utils/http'
import bus from '@/utils/bus'
import { Loading } from 'element-ui'
export default {
name: 'Login',
@@ -119,10 +117,7 @@ export default {
background: #0091ff;
color: #fff;
border-radius: 4px;
border: 0px;
font-family: PingFangSC-Regular;
text-align: left;
line-height: 22px;
border: 0;
font-weight: 400;
text-align: center;
}

View File

@@ -1,18 +0,0 @@
<template>
<el-tabs class="cn-chart cn-chart__tabs" v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
<el-tab-pane label="配置管理" name="second">配置管理</el-tab-pane>
<el-tab-pane label="角色管理" name="third">角色管理</el-tab-pane>
<el-tab-pane label="定时任务补偿" name="fourth">定时任务补偿</el-tab-pane>
</el-tabs>
</template>
<script>
export default {
name: 'ChartTabs'
}
</script>
<style>
</style>

View File

@@ -45,6 +45,38 @@ const line = {
}
]
}
const lineWithStatistics = {
xAxis: {
type: 'time'
},
yAxis: {
type: 'value'
},
legend: {
show: true,
top: 'top',
orient: 'horizontal',
icon: 'circle',
itemGap: 20,
itemWidth: 10,
textStyle: {
padding: [0, 0, 0, 5],
fontSize: 14
}
},
axisLabel: {
fontSize: 14
},
series: [
{
name: '',
type: 'line',
smooth: true,
symbol: 'none',
data: []
}
]
}
const lineStack = {
xAxis: {
type: 'time'
@@ -144,7 +176,8 @@ const pieWithTable = {
}
const typeOptionMappings = [
{ value: 11, option: line }, // 常规折线图
{ value: 13, option: lineStack }, // 常规折线图
{ value: 12, option: lineWithStatistics }, // 带统计表格的折线图
{ value: 13, option: lineStack }, // 折线堆叠图
{ value: 31, option: pieWithTable } // 常规折线图
]
const typeCategory = {

View File

@@ -1,4 +1,4 @@
.cn-panel {
.cn-panel, .cn-panel>.cn-chart__tabs>.el-tabs__content>.el-tab-pane {
display: grid;
grid-template-columns: repeat(30, 1fr);
grid-auto-flow: row;

View File

@@ -36,7 +36,6 @@ app.directive('has', hasPermission) // 注册指令
app.directive('click-outside', clickOutside)
app.directive('ele-click-outside', ClickOutside)
app.directive('cancel', cancelWithChange)
app.config.globalProperties.$_ = _
app.mixin(commonMixin)

View File

@@ -1,7 +1,8 @@
import router from './router'
import store from './store'
import { ElMessage } from 'element-plus'
import { getConfigJson, getPermission, loadIso36112 } from '@/utils/api'
import { getConfigJson, getPermission } from '@/utils/api'
import { loadGeoData } from '@/utils/tools'
import axios from 'axios'
import { storageKey } from '@/utils/constants'
import { loadI18n } from '@/i18n'
@@ -11,9 +12,7 @@ const permissionWhiteList = [...loginWhiteList] // 权限白名单
router.beforeEach(async (to, from, next) => {
// 加载iso-3166-2资源
if (!sessionStorage.getItem(storageKey.iso36112)) {
loadIso36112()
}
loadGeoData()
// 加载baseUrl
if (!axios.defaults.baseURL) {
const config = await getConfigJson()

View File

@@ -5,7 +5,7 @@
*/
import { get, post } from '@/utils/http'
import { sortByOrderNum } from '@/permission'
import {storageKey} from "@/utils/constants";
import { storageKey, iso36112 } from '@/utils/constants'
export const api = {
// 系统相关
@@ -79,8 +79,12 @@ export async function getI18n () {
return await request
}
export function loadIso36112 () {
get(`${process.env.BASE_URL}geojson/data/countriesWithCapital.json`).then(response => {
sessionStorage.setItem(storageKey.iso36112, JSON.stringify(response))
/* 获得原始的3611-2 json字符串数据 */
export async function getIso36112JsonData (suffix) {
const request = new Promise(resolve => {
get(`${process.env.BASE_URL}geojson/${suffix}`).then(response => {
resolve(JSON.stringify(response))
})
})
return await request
}

View File

@@ -1,7 +1,8 @@
export const defaultPageSize = 20
export const storageKey = {
iso36112: 'cn-iso3611-2',
iso36112Capital: 'cn-iso3611-2-capital',
iso36112WorldLow: 'cn-iso3611-2-world-low',
i18n: 'cn-i18n',
language: 'cn-language',
timezone: 'cn-timezone',
@@ -17,6 +18,11 @@ export const storageKey = {
unsavedChange: 'cn-unsaved-change'
}
export const iso36112 = {
[storageKey.iso36112Capital]: 'data/countriesWithCapital.json',
[storageKey.iso36112WorldLow]: 'worldChinaLow.json'
}
// 统一定义跳转来源
export const fromRoute = {
trafficSummary: 'trafficSummary',

View File

@@ -1,8 +1,8 @@
import { ElMessageBox } from 'element-plus'
import i18n from '@/i18n'
import _ from 'lodash'
import { storageKey } from '@/utils/constants'
import { getCache, setCache } from '@/utils/cache'
import { storageKey, iso36112 } from '@/utils/constants'
import { getIso36112JsonData } from '@/utils/api'
export const tableSort = {
// 是否需要排序
@@ -399,7 +399,46 @@ export function humpToLine (name) {
return name.replace(/([A-Z])/g, '_$1').toLowerCase()
}
export function getCapitalGeo (countryId) {
!getCache('capitalGeo') && setCache('capitalGeo', JSON.parse(sessionStorage.getItem(storageKey.iso36112)))
return getCache('capitalGeo')[countryId]
// 加载geo数据
export function loadGeoData (key) {
const keys = []
if (key) {
keys.push(key)
} else {
keys.push(storageKey.iso36112Capital)
keys.push(storageKey.iso36112WorldLow)
}
keys.forEach(async k => {
if (!localStorage.getItem(k)) {
const data = await getIso36112JsonData(iso36112[k])
if (data) {
localStorage.setItem(k, JSON.stringify(data))
}
}
})
return localStorage.getItem(key)
}
/* 返回geodata对象 */
export function getGeoData (key) {
const data = localStorage.getItem(key)
if (data) {
return JSONParse(data)
} else {
return JSONParse(loadGeoData(key))
}
}
export function getCapitalGeo (countryId) {
const data = getGeoData(storageKey.iso36112Capital)
return data[countryId]
}
export function JSONParse (data) {
const firstParse = JSON.parse(data)
if (typeof firstParse === 'string') {
return JSON.parse(firstParse)
} else {
return firstParse
}
}

View File

@@ -5,12 +5,21 @@
class="cn-chart cn-chart__title"
:style="computePosition">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div>
<!-- Tabs -->
<chart-tabs
<el-tabs
v-else-if="isTabs"
class="cn-chart cn-chart__tabs"
:tabs="chartInfo"
style="grid-area: 1 / 1 / 2 / 7;"
></chart-tabs>
v-model="activeTab"
@tab-click="changeTab"
:style="computePosition"
>
<el-tab-pane
v-for="(tab, index) in chartInfo.children"
:label="tab.i18n ? $t(tab.i18n) : tab.name" :name="`${tab.id}`"
:key="tab.id"
>
<chart v-for="(chart, index) in tab.children" :key="index" :chart="chart" :start-time="startTime" :end-time="endTime"></chart>
</el-tab-pane>
</el-tabs>
<!-- 地图 -->
<chart-map
v-else-if="isMap"
@@ -132,7 +141,6 @@ import SingleValue from '@/components/charts/ChartSingleValue'
import ChartTable from '@/components/charts/ChartTable'
import ChartMap from '@/components/charts/ChartMap'
import PieTable from '@/components/charts/PieTable'
import ChartTabs from '@/components/charts/ChartTabs'
import ChartTablePagination from '@/components/charts/ChartTablePagination'
import { chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
import { get } from '@/utils/http'
@@ -155,8 +163,7 @@ export default {
ChartTablePagination,
ChartTable,
PieTable,
ChartMap,
ChartTabs
ChartMap
},
data () {
return {
@@ -170,6 +177,7 @@ export default {
},
pieTableData: [],
singleValue: '-',
activeTab: '',
myChart: null
}
},
@@ -178,89 +186,91 @@ export default {
const chartParams = this.chartInfo.params ? JSON.parse(this.chartInfo.params) : null // 图表参数
if (this.isMap) {
this.myChart = this.initMap(`chart${this.chartInfo.id}`)
const queryParams = { startTime: 1593070343, endTime: this.endTime, country: '', region: '' } // 统计数据的查询参数
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), country: '', region: '' } // 统计数据的查询参数
if (chartParams) {
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
const data = response.data.result
data.forEach(r => {
const serverCountryCapital = r.serverId && getCapitalGeo(r.serverId)
const clientCountryCapital = r.clientId && getCapitalGeo(r.clientId)
serverCountryCapital && (r.serverLongitude = serverCountryCapital.capitalLongitude)
serverCountryCapital && (r.serverLatitude = serverCountryCapital.capitalLatitude)
clientCountryCapital && (r.clientLongitude = clientCountryCapital.capitalLongitude)
clientCountryCapital && (r.clientLatitude = clientCountryCapital.capitalLatitude)
})
if (this.isMapLine) {
const lineSeries = this.myChart.series.push(new am4Maps.MapLineSeries())
const gradient = new am4Core.LinearGradient()
gradient.stops.push({ color: am4Core.color() })
gradient.stops.push({ color: am4Core.color() })
gradient.stops.push({ color: am4Core.color() })
if (response.code === 200) {
const data = response.data.result
data.forEach(r => {
const serverCountryCapital = r.serverId && getCapitalGeo(r.serverId)
const clientCountryCapital = r.clientId && getCapitalGeo(r.clientId)
serverCountryCapital && (r.serverLongitude = serverCountryCapital.capitalLongitude)
serverCountryCapital && (r.serverLatitude = serverCountryCapital.capitalLatitude)
clientCountryCapital && (r.clientLongitude = clientCountryCapital.capitalLongitude)
clientCountryCapital && (r.clientLatitude = clientCountryCapital.capitalLatitude)
})
if (this.isMapLine) {
const lineSeries = this.myChart.series.push(new am4Maps.MapLineSeries())
const gradient = new am4Core.LinearGradient()
gradient.stops.push({ color: am4Core.color() })
gradient.stops.push({ color: am4Core.color() })
gradient.stops.push({ color: am4Core.color() })
const lineTemplate = lineSeries.mapLines.template
lineTemplate.stroke = am4Core.color('#A258EC')
lineTemplate.line.nonScalingStroke = true
lineTemplate.line.strokeDasharray = '4 3'
lineTemplate.nonScalingStroke = true
lineTemplate.arrow.nonScaling = true
lineTemplate.arrow.width = 4
lineTemplate.arrow.height = 6
lineSeries.data = [
{
multiGeoLine: data.map(d => {
return [
{
latitude: parseFloat(d.serverLatitude),
longitude: parseFloat(d.serverLongitude)
},
{
latitude: parseFloat(d.clientLatitude),
longitude: parseFloat(d.clientLongitude)
}
]
const lineTemplate = lineSeries.mapLines.template
lineTemplate.stroke = am4Core.color('#A258EC')
lineTemplate.line.nonScalingStroke = true
lineTemplate.line.strokeDasharray = '4 3'
lineTemplate.nonScalingStroke = true
lineTemplate.arrow.nonScaling = true
lineTemplate.arrow.width = 4
lineTemplate.arrow.height = 6
lineSeries.data = [
{
multiGeoLine: data.map(d => {
return [
{
latitude: parseFloat(d.serverLatitude),
longitude: parseFloat(d.serverLongitude)
},
{
latitude: parseFloat(d.clientLatitude),
longitude: parseFloat(d.clientLongitude)
}
]
})
}
]
const imageSeries = this.myChart.series.push(new am4Maps.MapImageSeries())
imageSeries.dataFields.value = 'sessions'
const imageSeriesTemplate = imageSeries.mapImages.template
const circle = imageSeriesTemplate.createChild(am4Core.Circle)
circle.fillOpacity = 0.7
circle.nonScaling = true
circle.tooltipText = '{title}'
const radiusHeat = imageSeries.heatRules.push({
target: circle,
property: 'radius',
min: 8,
max: 30
})
const colorHeat = imageSeries.heatRules.push({
target: circle,
property: 'fill',
min: am4Core.color('#D2A8FF'),
max: am4Core.color('#A258EC')
})
imageSeriesTemplate.propertyFields.latitude = 'latitude'
imageSeriesTemplate.propertyFields.longitude = 'longitude'
const pointData = []
data.forEach(d => {
pointData.push({
...d,
latitude: parseFloat(d.serverLatitude),
longitude: parseFloat(d.serverLongitude),
title: this.getTitle(d)
})
pointData.push({
...d,
latitude: parseFloat(d.clientLatitude),
longitude: parseFloat(d.clientLongitude),
title: this.getTitle(d)
})
}
]
const imageSeries = this.myChart.series.push(new am4Maps.MapImageSeries())
imageSeries.dataFields.value = 'sessions'
const imageSeriesTemplate = imageSeries.mapImages.template
const circle = imageSeriesTemplate.createChild(am4Core.Circle)
circle.fillOpacity = 0.7
circle.nonScaling = true
circle.tooltipText = '{title}'
const radiusHeat = imageSeries.heatRules.push({
target: circle,
property: 'radius',
min: 8,
max: 30
})
const colorHeat = imageSeries.heatRules.push({
target: circle,
property: 'fill',
min: am4Core.color('#D2A8FF'),
max: am4Core.color('#A258EC')
})
imageSeriesTemplate.propertyFields.latitude = 'latitude'
imageSeriesTemplate.propertyFields.longitude = 'longitude'
const pointData = []
data.forEach(d => {
pointData.push({
...d,
latitude: parseFloat(d.serverLatitude),
longitude: parseFloat(d.serverLongitude),
title: this.getTitle(d)
})
pointData.push({
...d,
latitude: parseFloat(d.clientLatitude),
longitude: parseFloat(d.clientLongitude),
title: this.getTitle(d)
})
})
imageSeries.data = pointData
imageSeries.data = pointData
}
}
})
}
@@ -269,42 +279,51 @@ export default {
this.myChart = echarts.init(dom)
if (chartParams) {
if (this.isEchartsWithTable) {
const queryParams = { startTime: 1593070343, endTime: this.endTime, limit: 10 } // 统计数据的查询参数
const tableQueryParams = { startTime: 1593070343, endTime: this.endTime, limit: 10 } // 统计数据的查询参数
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: 10 } // 统计数据的查询参数
const tableQueryParams = { startTime: parseInt(this.startTime / 1000), endTime: this.endTime, limit: 10 } // 统计数据的查询参数
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
const data = response.data.result
this.chartOption.legend.formatter = (name) => { // 根据图表宽 显示legend的字数
let str = name
const length = Math.floor(dom.offsetWidth / 75)
if (name.length > length) {
str = name.substring(0, length - 3) + '...'
if (response.code === 200) {
const data = response.data.result
this.chartOption.legend.formatter = (name) => { // 根据图表宽 显示legend的字数
let str = name
const length = Math.floor(dom.offsetWidth / 75)
if (name.length > length) {
str = name.substring(0, length - 3) + '...'
}
return str
}
return str
}
this.chartOption.series[0].data = data.map(d => {
return {
data: d,
name: d[chartParams.nameColumn],
value: parseInt(d[chartParams.valueColumn])
this.chartOption.series[0].data = data.map(d => {
return {
data: d,
name: d[chartParams.nameColumn],
value: parseInt(d[chartParams.valueColumn])
}
})
if (this.chartOption.series[0].data && this.chartOption.series[0].data.length > 10) { // pieWithTable 图例超过10个改为滚动显示
this.chartOption.legend.type = 'scroll'
}
})
if (this.chartOption.series[0].data && this.chartOption.series[0].data.length > 10) { // pieWithTable 图例超过10个改为滚动显示
this.chartOption.legend.type = 'scroll'
this.myChart.setOption(this.chartOption)
this.$nextTick(() => {
this.myChart.resize()
})
tableQueryParams[chartParams.nameColumn] = data[0][chartParams.nameColumn]
get(replaceUrlPlaceholder(chartParams.urlTable, tableQueryParams)).then(response2 => {
if (response2.code === 200) {
this.pieTableData = response2.data.result
}
})
}
this.myChart.setOption(this.chartOption)
tableQueryParams[chartParams.nameColumn] = data[0][chartParams.nameColumn]
get(replaceUrlPlaceholder(chartParams.urlTable, tableQueryParams)).then(response2 => {
this.pieTableData = response2.data.result
})
})
this.myChart.on('click', function (echartParams) {
get(replaceUrlPlaceholder(chartParams.urlTable, tableQueryParams)).then(response => {
this.pieTableData = response.data.result
if (response.code === 200) {
this.pieTableData = response.data.result
}
})
})
} else {
const queryParams = { startTime: 1593070343, endTime: this.endTime }
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000) }
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) {
const seriesTemplate = this.chartOption.series[0]
@@ -316,13 +335,15 @@ export default {
}
})
}
this.myChart.setOption(this.chartOption)
this.$nextTick(() => {
this.myChart.resize()
})
})
}
}
} else if (this.isTable) {
if (chartParams) {
const queryParams = { startTime: 1593070343, endTime: this.endTime, limit: 100, order: 'sessions' }
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: 100, order: 'sessions' }
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) {
const tableColumns = new Set()
@@ -340,13 +361,17 @@ export default {
}
} else if (this.isSingleValue) {
if (chartParams) {
const queryParams = { startTime: 1593070343, endTime: this.endTime }
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000) }
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) {
this.singleValue = response.data.result
}
})
}
} else if (this.isTabs) {
if (!this.$_.isEmpty(this.chartInfo.children)) {
this.activeTab = `${this.chartInfo.children[0].id}`
}
}
},
getTitle (data) {
@@ -355,6 +380,9 @@ export default {
Sessions: ${data.sessions}
Bytes: ${data.bytes}`
},
changeTab (tab) {
this.activeTab = tab.paneName
},
initMap (id) {
const chart = am4Core.create(id, am4Maps.MapChart)
chart.geodata = am4GeoDataWorldLow
@@ -412,6 +440,16 @@ export default {
}
</script>
<style>
<style lang="scss">
.cn-chart__tabs {
padding: 10px 25px 10px 15px;
overflow: auto;
.el-tabs__nav-wrap::after {
height: 1px;
}
&>.el-tabs__header {
margin-bottom: 10px;
}
}
</style>