This commit is contained in:
Pan 2017-04-19 18:43:57 +08:00
parent 15a7d074d2
commit 89a4c3bda1
19 changed files with 754 additions and 98 deletions

View file

@ -21,6 +21,7 @@
"jquery": "3.1.1",
"js-cookie": "2.1.3",
"jsonlint": "1.6.2",
"mockjs": "^1.0.1-beta3",
"normalize.css": "3.0.2",
"nprogress": "0.2.0",
"showdown": "1.6.4",

29
src/api/article.js Normal file
View file

@ -0,0 +1,29 @@
import fetch, { tpFetch } from 'utils/fetch';
import { param } from 'utils';
export function getList(query) {
return tpFetch({
url: '/article/list',
method: 'get'
});
}
export function upload(data) {
return tpFetch({
url: 'https://upload.qbox.me',
method: 'post',
data
});
}
/* 外部uri转七牛uri*/
export function netUpload(token, net_url) {
const imgData = {
net_url
};
return fetch({
url: '/qiniu/upload/net/async',
method: 'post',
data: imgData
});
}

View file

@ -17,11 +17,11 @@
props: {
className: {
type: String,
default: 'bar-percent-chart'
default: 'chart'
},
id: {
type: String,
default: 'bar-percent-chart'
default: 'chart'
},
width: {
type: String,

View file

@ -17,11 +17,11 @@
props: {
className: {
type: String,
default: 'bar-percent-chart'
default: 'chart'
},
id: {
type: String,
default: 'bar-percent-chart'
default: 'chart'
},
width: {
type: String,

View file

@ -0,0 +1,219 @@
<template>
<div :class="className" :id="id" :style="{height:height,width:width}"></div>
</template>
<script>
// ECharts
const echarts = require('echarts/lib/echarts');
require('echarts/lib/chart/line');
//
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
require('echarts/lib/component/legend');
export default {
name: 'barPercent',
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
},
data() {
return {};
},
mounted() {
this.initChart();
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id));
this.chart.setOption({
backgroundColor: '#394056',
title: {
text: '请求数',
textStyle: {
fontWeight: 'normal',
fontSize: 16,
color: '#F1F1F3'
},
left: '6%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#57617B'
}
}
},
legend: {
icon: 'rect',
itemWidth: 14,
itemHeight: 5,
itemGap: 13,
data: ['移动', '电信', '联通'],
right: '4%',
textStyle: {
fontSize: 12,
color: '#F1F1F3'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#57617B'
}
},
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
}],
yAxis: [{
type: 'value',
name: '单位(%',
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#57617B'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: '#57617B'
}
}
}],
series: [{
name: '移动',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(137, 189, 27, 0.3)'
}, {
offset: 0.8,
color: 'rgba(137, 189, 27, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(137,189,27)',
borderColor: 'rgba(137,189,2,0.27)',
borderWidth: 12
}
},
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
}, {
name: '电信',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 136, 212, 0.3)'
}, {
offset: 0.8,
color: 'rgba(0, 136, 212, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(0,136,212)',
borderColor: 'rgba(0,136,212,0.2)',
borderWidth: 12
}
},
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
}, {
name: '联通',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(219, 50, 51, 0.3)'
}, {
offset: 0.8,
color: 'rgba(219, 50, 51, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(219,50,51)',
borderColor: 'rgba(219,50,51,0.2)',
borderWidth: 12
}
},
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
}]
})
}
}
}
</script>

View file

@ -0,0 +1,266 @@
<template>
<div :class="className" :id="id" :style="{height:height,width:width}"></div>
</template>
<script>
// ECharts
const echarts = require('echarts/lib/echarts');
require('echarts/lib/chart/bar');
require('echarts/lib/chart/line');
//
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
require('echarts/lib/component/legend');
require('echarts/lib/component/dataZoom');
export default {
name: 'barPercent',
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
},
data() {
return {};
},
mounted() {
this.initChart();
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id));
const xData = (function() {
const data = [];
for (let i = 1; i < 13; i++) {
data.push(i + '月份');
}
return data;
}());
this.chart.setOption({
backgroundColor: '#344b58',
title: {
text: '统计',
subtext: 'from http://gallery.echartsjs.com',
x: '4%',
textStyle: {
color: '#fff',
fontSize: '22'
},
subtextStyle: {
color: '#90979c',
fontSize: '16'
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
textStyle: {
color: '#fff'
}
}
},
grid: {
borderWidth: 0,
top: 110,
bottom: 95,
textStyle: {
color: '#fff'
}
},
legend: {
x: '15%',
top: '10%',
textStyle: {
color: '#90979c'
},
data: ['女', '男', '平均']
},
calculable: true,
xAxis: [{
type: 'category',
axisLine: {
lineStyle: {
color: '#90979c'
}
},
splitLine: {
show: false
},
axisTick: {
show: false
},
splitArea: {
show: false
},
axisLabel: {
interval: 0
},
data: xData
}],
yAxis: [{
type: 'value',
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: '#90979c'
}
},
axisTick: {
show: false
},
axisLabel: {
interval: 0
},
splitArea: {
show: false
}
}],
dataZoom: [{
show: true,
height: 30,
xAxisIndex: [
0
],
bottom: 30,
start: 10,
end: 80,
handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
handleSize: '110%',
handleStyle: {
color: '#d3dee5'
},
textStyle: {
color: '#fff' },
borderColor: '#90979c'
}, {
type: 'inside',
show: true,
height: 15,
start: 1,
end: 35
}],
series: [{
name: '女',
type: 'bar',
stack: '总量',
barMaxWidth: 35,
barGap: '10%',
itemStyle: {
normal: {
color: 'rgba(255,144,128,1)',
label: {
show: true,
textStyle: {
color: '#fff'
},
position: 'insideTop',
formatter(p) {
return p.value > 0 ? p.value : '';
}
}
}
},
data: [
709,
1917,
2455,
2610,
1719,
1433,
1544,
3285,
5208,
3372,
2484,
4078
]
},
{
name: '男',
type: 'bar',
stack: '总量',
itemStyle: {
normal: {
color: 'rgba(0,191,183,1)',
barBorderRadius: 0,
label: {
show: true,
position: 'top',
formatter(p) {
return p.value > 0 ? p.value : '';
}
}
}
},
data: [
327,
1776,
507,
1200,
800,
482,
204,
1390,
1001,
951,
381,
220
]
}, {
name: '平均',
type: 'line',
stack: '总量',
symbolSize: 10,
symbol: 'circle',
itemStyle: {
normal: {
color: 'rgba(252,230,48,1)',
barBorderRadius: 0,
label: {
show: true,
position: 'top',
formatter(p) {
return p.value > 0 ? p.value : '';
}
}
}
},
data: [
1036,
3693,
2962,
3810,
2519,
1915,
1748,
4675,
6209,
4323,
2865,
4298
]
}
]
})
}
}
}
</script>

View file

@ -104,7 +104,6 @@
<script>
/* eslint-disable */
import {getToken, upload} from 'api/qiniu';
import {effectRipple, data2blob} from './utils';
import langBag from './lang';
const mimes = {
@ -639,33 +638,74 @@
},
//
upload() {
let that = this,
{
lang,
mime,
createImgUrl
} = this,
formData = new FormData();
//
that.loading = 1;
that.progress = 0;
that.setStep(3);
formData.append('file', data2blob(createImgUrl, mime));
const token = this.$store.getters.token;
getToken(token).then((response)=> {
const url = response.data.qiniu_url;
formData.append('token', response.data.qiniu_token);
formData.append('key', response.data.qiniu_key);
upload(formData).then((response)=> {
that.loading = 2;
that.$emit('crop-upload-success', url);
}).catch(err => {
let that = this,
{
lang,
imgFormat,
mime,
url,
params,
headers,
field,
ki,
createImgUrl
} = this,
fmData = new FormData();
fmData.append(field, data2blob(createImgUrl, mime), field + '.' + imgFormat);
//
if (typeof params == 'object' && params) {
Object.keys(params).forEach((k) => {
fmData.append(k, params[k]);
})
}
//
const uploadProgress = function(event) {
if (event.lengthComputable) {
that.progress = 100 * Math.round(event.loaded) / event.total;
}
};
//
that.reset();
that.loading = 1;
that.setStep(3);
that.$emit('crop-success', createImgUrl, field, ki);
new Promise(function(resolve, reject) {
let client = new XMLHttpRequest();
client.open('POST', url, true);
client.onreadystatechange = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(JSON.parse(this.responseText));
} else {
reject(this.status);
}
};
client.upload.addEventListener("progress", uploadProgress, false); //
// header
if (typeof headers == 'object' && headers) {
Object.keys(headers).forEach((k) => {
client.setRequestHeader(k, headers[k]);
})
}
client.send(fmData);
}).then(
//
function(resData) {
that.loading = 2;
that.$emit('crop-upload-success', url);
},
//
function(sts) {
if (that.value) {
that.loading = 3;
that.hasError = true;
that.errorMsg = lang.fail;
that.$emit('crop-upload-fail');
});
});
that.$emit('crop-upload-fail', sts, field, ki);
}
}
);
}
}
}

View file

@ -5,7 +5,7 @@
<slot>pan</slot>
</div>
</div>
<div class="pan-thumb" :style="{ backgroundImage: 'url('+ image+')' }"></div>
<img class="pan-thumb" :src="image">
</div>
</template>
<script>

View file

@ -20,6 +20,7 @@ import 'vue-multiselect/dist/vue-multiselect.min.css';
import vueWaves from './directive/waves';
import vueSticky from './directive/sticky';
import errLog from 'store/errLog';
import './mock/index.js';
// import './styles/mixin.scss';
// register globally

10
src/mock/index.js Normal file
View file

@ -0,0 +1,10 @@
import Mock from 'mockjs';
Mock.mock(/\/article\/list/, {
'data|20': [{
id: '@id',
content: '@cparagraph',
time: '@datetime'
}]
})
export default Mock;

View file

@ -19,11 +19,17 @@ import reset from '../views/login/reset';
/* components*/
const Tinymce = resolve => require(['../views/components/tinymce'], resolve);
const Markdown = resolve => require(['../views/components/markdown'], resolve);
const Jsoneditor = resolve => require(['../views/components/jsoneditor'], resolve);
const JsonEditor = resolve => require(['../views/components/jsoneditor'], resolve);
const AvatarUpload = resolve => require(['../views/components/avatarupload'], resolve);
/* charts*/
const KeyboardChart = resolve => require(['../views/charts/keyboard'], resolve);
const KeyboardChart2 = resolve => require(['../views/charts/keyboard2'], resolve);
const LineMarker = resolve => require(['../views/charts/line'], resolve);
const MixChart = resolve => require(['../views/charts/mixchart'], resolve);
/* excel*/
const ExcelDownload = resolve => require(['../views/excel/index'], resolve);
/* admin*/
@ -66,7 +72,8 @@ export default new Router({
children: [
{ path: 'tinymce', component: Tinymce, name: '富文本编辑器' },
{ path: 'markdown', component: Markdown, name: 'Markdown' },
{ path: 'jsoneditor', component: Jsoneditor, name: 'json编辑器' }
{ path: 'jsoneditor', component: JsonEditor, name: 'json编辑器' },
{ path: 'avatarupload', component: AvatarUpload, name: '头像上传' }
]
},
@ -78,8 +85,20 @@ export default new Router({
icon: 'tubiaoleixingzhengchang',
children: [
{ path: 'keyboard', component: KeyboardChart, name: '键盘图表' },
{ path: 'keyboard2', component: KeyboardChart2, name: '键盘图表2' }
{ path: 'keyboard2', component: KeyboardChart2, name: '键盘图表2' },
{ path: 'line', component: LineMarker, name: '折线图' },
{ path: 'mixchart', component: MixChart, name: '混合图表' }
]
},
{
path: '/excel',
component: Layout,
redirect: 'noredirect',
name: 'excel',
icon: 'tubiaoleixingzhengchang',
noDropdown: true,
children: [
{ path: 'download', component: ExcelDownload, name: '导出excel' }
]
},
// {

View file

@ -10,12 +10,7 @@
import keyboardChart from 'components/Charts/keyboard';
export default {
components: { keyboardChart },
data() {
return {
}
}
components: { keyboardChart }
};
</script>
@ -23,7 +18,7 @@
.chart-container{
position: relative;
width: 100%;
height: 100%;
height: 90%;
}
</style>

View file

@ -10,12 +10,7 @@
import keyboardChart2 from 'components/Charts/keyboard2';
export default {
components: { keyboardChart2 },
data() {
return {
}
}
components: { keyboardChart2 }
};
</script>
@ -23,7 +18,7 @@
.chart-container{
position: relative;
width: 100%;
height: 100%;
height: 90%;
}
</style>

26
src/views/charts/line.vue Normal file
View file

@ -0,0 +1,26 @@
<template>
<div class="components-container" style='height:100vh'>
https://github.com/ecomfe/echarts/blob/master/index.js
http://echarts.baidu.com/tutorial.html
<div class='chart-container'>
<lineMarker height='100%' width='100%' />
</div>
</div>
</template>
<script>
import lineMarker from 'components/Charts/lineMarker';
export default {
components: { lineMarker }
};
</script>
<style scoped>
.chart-container{
position: relative;
width: 100%;
height: 80%;
}
</style>

View file

@ -1,22 +0,0 @@
<template>
<div class="components-container">
<code>公司做的后台主要是一个cms系统公司也是已自媒体为核心的所以富文本是后台很核心的功能在选择富文本的过程中也走了不少的弯路市面上常见的富文本都基本用过了最终选择了tinymce</code>
<div class="editor-container">
<MdEditor id='contentEditor' ref="contentEditor" v-model='content' :height="150"></MdEditor>
</div>
</div>
</template>
<script>
import MdEditor from 'components/MdEditor';
export default {
components: { MdEditor },
data() {
return {
content: 'Simplemde'
}
}
};
</script>

View file

@ -0,0 +1,25 @@
<template>
<div class="components-container" style='height:100vh'>
<div class='chart-container'>
<mixchart id='apple' height='100%' width='100%' />
</div>
</div>
</template>
<script>
import mixchart from 'components/Charts/mixchart';
export default {
components: { mixchart }
};
</script>
<style scoped>
.chart-container{
position: relative;
width: 100%;
height: 90%;
padding-bottom: 40px;
}
</style>

View file

@ -1,28 +0,0 @@
<template>
<div class="components-container">
<code>公司做的后台主要是一个cms系统公司也是已自媒体为核心的所以富文本是后台很核心的功能在选择富文本的过程中也走了不少的弯路市面上常见的富文本都基本用过了最终选择了tinymce</code>
<div class="editor-container">
<Tinymce :height=200 ref="editor" v-model="content"></Tinymce>
</div>
<!--<div class='editor-content'>
{{content}}
</div>-->
</div>
</template>
<script>
import Tinymce from 'components/Tinymce';
export default {
components: { Tinymce },
data() {
return {
content: 'Tinymce'
}
},
methods: {
}
};
</script>

View file

@ -0,0 +1,42 @@
<template>
<div class="components-container">
<code>这里核心代码用的是<a class='link-type' href='//github.com/dai-siki/vue-image-crop-upload'>vue-image-crop-upload</a>
由于我在使用时它只有vue@1版本而且有些业务的需求耦合到七牛等等原因吧自己改造了一下如果大家要使用的话优先还是使用官方component
</code>
<PanThumb image='https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191'>
</PanThumb>
<el-button type="primary" icon="upload" style="position: absolute;bottom: 15px;margin-left: 40px;" @click="imagecropperShow=true">修改头像
</el-button>
<ImageCropper :width="300" :height="300" url="https://httpbin.org/post" @crop-upload-success="cropSuccess" :key="imagecropperKey"
v-show="imagecropperShow" />
</div>
</template>
<script>
import ImageCropper from 'components/ImageCropper';
import PanThumb from 'components/PanThumb';
export default {
components: { ImageCropper, PanThumb },
data() {
return {
imagecropperShow: false,
imagecropperKey: 0
}
},
methods: {
cropSuccess() {
this.imagecropperShow = false;
this.imagecropperKey = this.imagecropperKey + 1;
}
}
};
</script>
<style scoped>
.avatar{
width: 200px;
height: 200px;
border-radius: 50%;
}
</style>

38
src/views/excel/index.vue Normal file
View file

@ -0,0 +1,38 @@
<template>
<div class="errPage-container">
aaa
</div>
</template>
<script>
import { getList } from 'api/article'
export default {
data() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
area: undefined,
department: undefined
}
}
},
created() {
this.fetchData();
},
methods: {
fetchData() {
this.listLoading = true;
getList(this.listQuery).then(response => {
console.log(response)
const data = response.data;
this.list = data.items;
this.total = data.item_count;
this.listLoading = false;
})
}
}
};
</script>