forked from AkkomaGang/admin-fe
Remove unused files
This commit is contained in:
parent
96e52a14cc
commit
dea231688f
40 changed files with 0 additions and 3137 deletions
|
@ -1,41 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function fetchList(query) {
|
||||
return request({
|
||||
url: '/article/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchArticle(id) {
|
||||
return request({
|
||||
url: '/article/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchPv(pv) {
|
||||
return request({
|
||||
url: '/article/pv',
|
||||
method: 'get',
|
||||
params: { pv }
|
||||
})
|
||||
}
|
||||
|
||||
export function createArticle(data) {
|
||||
return request({
|
||||
url: '/article/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateArticle(data) {
|
||||
return request({
|
||||
url: '/article/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getToken() {
|
||||
return request({
|
||||
url: '/qiniu/upload/token', // 假地址 自行替换
|
||||
method: 'get'
|
||||
})
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function userSearch(name) {
|
||||
return request({
|
||||
url: '/search/user',
|
||||
method: 'get',
|
||||
params: { name }
|
||||
})
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/** When your routing table is too long, you can split it into small modules**/
|
||||
|
||||
import Layout from '@/views/layout/Layout'
|
||||
|
||||
const componentsRouter = {
|
||||
path: '/components',
|
||||
component: Layout,
|
||||
redirect: 'noredirect',
|
||||
name: 'ComponentDemo',
|
||||
meta: {
|
||||
title: 'components',
|
||||
icon: 'component'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'tinymce',
|
||||
component: () => import('@/views/components-demo/tinymce'),
|
||||
name: 'TinymceDemo',
|
||||
meta: { title: 'tinymce' }
|
||||
},
|
||||
{
|
||||
path: 'markdown',
|
||||
component: () => import('@/views/components-demo/markdown'),
|
||||
name: 'MarkdownDemo',
|
||||
meta: { title: 'markdown' }
|
||||
},
|
||||
{
|
||||
path: 'json-editor',
|
||||
component: () => import('@/views/components-demo/jsonEditor'),
|
||||
name: 'JsonEditorDemo',
|
||||
meta: { title: 'jsonEditor' }
|
||||
},
|
||||
{
|
||||
path: 'splitpane',
|
||||
component: () => import('@/views/components-demo/splitpane'),
|
||||
name: 'SplitpaneDemo',
|
||||
meta: { title: 'splitPane' }
|
||||
},
|
||||
{
|
||||
path: 'avatar-upload',
|
||||
component: () => import('@/views/components-demo/avatarUpload'),
|
||||
name: 'AvatarUploadDemo',
|
||||
meta: { title: 'avatarUpload' }
|
||||
},
|
||||
{
|
||||
path: 'dropzone',
|
||||
component: () => import('@/views/components-demo/dropzone'),
|
||||
name: 'DropzoneDemo',
|
||||
meta: { title: 'dropzone' }
|
||||
},
|
||||
{
|
||||
path: 'sticky',
|
||||
component: () => import('@/views/components-demo/sticky'),
|
||||
name: 'StickyDemo',
|
||||
meta: { title: 'sticky' }
|
||||
},
|
||||
{
|
||||
path: 'count-to',
|
||||
component: () => import('@/views/components-demo/countTo'),
|
||||
name: 'CountToDemo',
|
||||
meta: { title: 'countTo' }
|
||||
},
|
||||
{
|
||||
path: 'mixin',
|
||||
component: () => import('@/views/components-demo/mixin'),
|
||||
name: 'ComponentMixinDemo',
|
||||
meta: { title: 'componentMixin' }
|
||||
},
|
||||
{
|
||||
path: 'back-to-top',
|
||||
component: () => import('@/views/components-demo/backToTop'),
|
||||
name: 'BackToTopDemo',
|
||||
meta: { title: 'backToTop' }
|
||||
},
|
||||
{
|
||||
path: 'drag-dialog',
|
||||
component: () => import('@/views/components-demo/dragDialog'),
|
||||
name: 'DragDialogDemo',
|
||||
meta: { title: 'dragDialog' }
|
||||
},
|
||||
{
|
||||
path: 'drag-select',
|
||||
component: () => import('@/views/components-demo/dragSelect'),
|
||||
name: 'DragSelectDemo',
|
||||
meta: { title: 'dragSelect' }
|
||||
},
|
||||
{
|
||||
path: 'dnd-list',
|
||||
component: () => import('@/views/components-demo/dndList'),
|
||||
name: 'DndListDemo',
|
||||
meta: { title: 'dndList' }
|
||||
},
|
||||
{
|
||||
path: 'drag-kanban',
|
||||
component: () => import('@/views/components-demo/dragKanban'),
|
||||
name: 'DragKanbanDemo',
|
||||
meta: { title: 'dragKanban' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default componentsRouter
|
|
@ -1,53 +0,0 @@
|
|||
/** When your routing table is too long, you can split it into small modules**/
|
||||
|
||||
import Layout from '@/views/layout/Layout'
|
||||
|
||||
const tableRouter = {
|
||||
path: '/table',
|
||||
component: Layout,
|
||||
redirect: '/table/complex-table',
|
||||
name: 'Table',
|
||||
meta: {
|
||||
title: 'Table',
|
||||
icon: 'table'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'dynamic-table',
|
||||
component: () => import('@/views/table/dynamicTable/index'),
|
||||
name: 'DynamicTable',
|
||||
meta: { title: 'dynamicTable' }
|
||||
},
|
||||
{
|
||||
path: 'drag-table',
|
||||
component: () => import('@/views/table/dragTable'),
|
||||
name: 'DragTable',
|
||||
meta: { title: 'dragTable' }
|
||||
},
|
||||
{
|
||||
path: 'inline-edit-table',
|
||||
component: () => import('@/views/table/inlineEditTable'),
|
||||
name: 'InlineEditTable',
|
||||
meta: { title: 'inlineEditTable' }
|
||||
},
|
||||
{
|
||||
path: 'tree-table',
|
||||
component: () => import('@/views/table/treeTable/treeTable'),
|
||||
name: 'TreeTableDemo',
|
||||
meta: { title: 'treeTable' }
|
||||
},
|
||||
{
|
||||
path: 'custom-tree-table',
|
||||
component: () => import('@/views/table/treeTable/customTreeTable'),
|
||||
name: 'CustomTreeTableDemo',
|
||||
meta: { title: 'customTreeTable' }
|
||||
},
|
||||
{
|
||||
path: 'complex-table',
|
||||
component: () => import('@/views/table/complexTable'),
|
||||
name: 'ComplexTable',
|
||||
meta: { title: 'complexTable' }
|
||||
}
|
||||
]
|
||||
}
|
||||
export default tableRouter
|
|
@ -1,59 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<code>This is based on
|
||||
<a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>.
|
||||
{{ $t('components.imageUploadTips') }}
|
||||
</code>
|
||||
|
||||
<pan-thumb :image="image"/>
|
||||
|
||||
<el-button type="primary" icon="upload" style="position: absolute;bottom: 15px;margin-left: 40px;" @click="imagecropperShow=true">Change Avatar
|
||||
</el-button>
|
||||
|
||||
<image-cropper
|
||||
v-show="imagecropperShow"
|
||||
:width="300"
|
||||
:height="300"
|
||||
:key="imagecropperKey"
|
||||
url="https://httpbin.org/post"
|
||||
lang-type="en"
|
||||
@close="close"
|
||||
@crop-upload-success="cropSuccess"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ImageCropper from '@/components/ImageCropper'
|
||||
import PanThumb from '@/components/PanThumb'
|
||||
|
||||
export default {
|
||||
name: 'AvatarUploadDemo',
|
||||
components: { ImageCropper, PanThumb },
|
||||
data: function() {
|
||||
return {
|
||||
imagecropperShow: false,
|
||||
imagecropperKey: 0,
|
||||
image: 'https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
cropSuccess(resData) {
|
||||
this.imagecropperShow = false
|
||||
this.imagecropperKey = this.imagecropperKey + 1
|
||||
this.image = resData.files.avatar
|
||||
},
|
||||
close() {
|
||||
this.imagecropperShow = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.avatar{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<code>{{ $t('components.backToTopTips1') }}</code>
|
||||
<code>{{ $t('components.backToTopTips2') }}</code>
|
||||
<div class="placeholder-container">
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
</div>
|
||||
<!--可自定义按钮的样式、show/hide临界点、返回的位置 -->
|
||||
<!--如需文字提示,可在外部添加element的<el-tooltip></el-tooltip>元素 -->
|
||||
<el-tooltip placement="top" content="tooltip">
|
||||
<back-to-top :custom-style="myBackToTopStyle" :visibility-height="300" :back-position="50" transition-name="fade"/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BackToTop from '@/components/BackToTop'
|
||||
|
||||
export default {
|
||||
name: 'BackToTopDemo',
|
||||
components: { BackToTop },
|
||||
data: function() {
|
||||
return {
|
||||
myBackToTopStyle: {
|
||||
right: '50px',
|
||||
bottom: '50px',
|
||||
width: '40px',
|
||||
height: '40px',
|
||||
'border-radius': '4px',
|
||||
'line-height': '45px', // 请保持与高度一致以垂直居中 Please keep consistent with height to center vertically
|
||||
background: '#e7eaf1'// 按钮的背景颜色 The background color of the button
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.placeholder-container div {
|
||||
margin: 10px;
|
||||
}
|
||||
</style>
|
|
@ -1,213 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<p class="warn-content">
|
||||
<a href="https://github.com/PanJiaChen/vue-countTo" target="_blank">countTo-component</a>
|
||||
</p>
|
||||
<count-to
|
||||
ref="example"
|
||||
:start-val="_startVal"
|
||||
:end-val="_endVal"
|
||||
:duration="_duration"
|
||||
:decimals="_decimals"
|
||||
:separator="_separator"
|
||||
:prefix="_prefix"
|
||||
:suffix="_suffix"
|
||||
:autoplay="false"
|
||||
class="example"/>
|
||||
<div style="margin-left: 25%;margin-top: 40px;">
|
||||
<label class="label" for="startValInput">startVal:
|
||||
<input v-model.number="setStartVal" type="number" name="startValInput" >
|
||||
</label>
|
||||
<label class="label" for="endValInput">endVal:
|
||||
<input v-model.number="setEndVal" type="number" name="endVaInput" >
|
||||
</label>
|
||||
<label class="label" for="durationInput">duration:
|
||||
<input v-model.number="setDuration" type="number" name="durationInput" >
|
||||
</label>
|
||||
<div class="startBtn example-btn" @click="start">开始</div>
|
||||
<div class="pause-resume-btn example-btn" @click="pauseResume">暂停/恢复</div>
|
||||
<br>
|
||||
<label class="label" for="decimalsInput">decimals:
|
||||
<input v-model.number="setDecimals" type="number" name="decimalsInput" >
|
||||
</label>
|
||||
<label class="label" for="separatorInput">separator:
|
||||
<input v-model="setSeparator" name="separatorInput" >
|
||||
</label>
|
||||
<label class="label" for="prefixInput">prefix:
|
||||
<input v-model="setPrefix" name="prefixInput" >
|
||||
</label>
|
||||
<label class="label" for="suffixInput">suffix:
|
||||
<input v-model="setSuffix" name="suffixInput" >
|
||||
</label>
|
||||
</div>
|
||||
<code><count-to :start-val='{{ _startVal }}' :end-val='{{ _endVal }}' :duration='{{ _duration }}'
|
||||
:decimals='{{ _decimals }}' :separator='{{ _separator }}' :prefix='{{ _prefix }}' :suffix='{{ _suffix }}'
|
||||
:autoplay=false></code>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countTo from 'vue-count-to'
|
||||
|
||||
export default {
|
||||
name: 'CountToDemo',
|
||||
components: { countTo },
|
||||
data: function() {
|
||||
return {
|
||||
setStartVal: 0,
|
||||
setEndVal: 2017,
|
||||
setDuration: 4000,
|
||||
setDecimals: 0,
|
||||
setSeparator: ',',
|
||||
setSuffix: ' rmb',
|
||||
setPrefix: '¥ '
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
_startVal() {
|
||||
if (this.setStartVal) {
|
||||
return this.setStartVal
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
_endVal() {
|
||||
if (this.setEndVal) {
|
||||
return this.setEndVal
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
_duration() {
|
||||
if (this.setDuration) {
|
||||
return this.setDuration
|
||||
} else {
|
||||
return 100
|
||||
}
|
||||
},
|
||||
_decimals() {
|
||||
if (this.setDecimals) {
|
||||
if (this.setDecimals < 0 || this.setDecimals > 20) {
|
||||
alert('digits argument must be between 0 and 20')
|
||||
return 0
|
||||
}
|
||||
return this.setDecimals
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
_separator() {
|
||||
return this.setSeparator
|
||||
},
|
||||
_suffix() {
|
||||
return this.setSuffix
|
||||
},
|
||||
_prefix() {
|
||||
return this.setPrefix
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
start() {
|
||||
this.$refs.example.start()
|
||||
},
|
||||
pauseResume() {
|
||||
this.$refs.example.pauseResume()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.example-btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
white-space: nowrap;
|
||||
line-height: 1.5;
|
||||
padding: 4px 15px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
position: relative;
|
||||
color: rgba(0, 0, 0, .65);
|
||||
background-color: #fff;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
|
||||
.example-btn:hover {
|
||||
color: #4AB7BD;
|
||||
background-color: #fff;
|
||||
border-color: #4AB7BD;
|
||||
}
|
||||
.example {
|
||||
font-size: 50px;
|
||||
color: #F6416C;
|
||||
display: block;
|
||||
margin: 10px 0;
|
||||
text-align: center;
|
||||
font-size: 80px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #2f4f4f;
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
margin: 15px 30px 15px 0;
|
||||
}
|
||||
|
||||
input {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 4px 7px;
|
||||
width: 70px;
|
||||
height: 28px;
|
||||
cursor: text;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
color: rgba(0, 0, 0, .65);
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
-webkit-transition: all .3s;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
.startBtn {
|
||||
margin-left: 20px;
|
||||
font-size: 20px;
|
||||
color: #30B08F;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.startBtn:hover {
|
||||
background-color: #30B08F;
|
||||
color: #fff;
|
||||
border-color: #30B08F;
|
||||
}
|
||||
|
||||
.pause-resume-btn {
|
||||
font-size: 20px;
|
||||
color: #E65D6E;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.pause-resume-btn:hover {
|
||||
background-color: #E65D6E;
|
||||
color: #fff;
|
||||
border-color: #E65D6E;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<code>drag-list base on
|
||||
<a href="https://github.com/SortableJS/Vue.Draggable" target="_blank">Vue.Draggable</a>
|
||||
</code>
|
||||
<div class="editor-container">
|
||||
<dnd-list :list1="list1" :list2="list2" list1-title="List" list2-title="Article pool"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DndList from '@/components/DndList'
|
||||
import { fetchList } from '@/api/article'
|
||||
|
||||
export default {
|
||||
name: 'DndListDemo',
|
||||
components: { DndList },
|
||||
data: function() {
|
||||
return {
|
||||
list1: [],
|
||||
list2: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getData()
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
this.listLoading = true
|
||||
fetchList().then(response => {
|
||||
this.list1 = response.data.items.splice(0, 5)
|
||||
this.list2 = response.data.items
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<el-button type="primary" @click="dialogTableVisible = true">open a Drag Dialog</el-button>
|
||||
<el-dialog v-el-drag-dialog :visible.sync="dialogTableVisible" title="Shipping address" @dragDialog="handleDrag">
|
||||
<el-select ref="select" v-model="value" placeholder="请选择">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
<el-table :data="gridData">
|
||||
<el-table-column property="date" label="Date" width="150"/>
|
||||
<el-table-column property="name" label="Name" width="200"/>
|
||||
<el-table-column property="address" label="Address"/>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import elDragDialog from '@/directive/el-dragDialog' // base on element-ui
|
||||
|
||||
export default {
|
||||
name: 'DragDialogDemo',
|
||||
directives: { elDragDialog },
|
||||
data: function() {
|
||||
return {
|
||||
dialogTableVisible: false,
|
||||
options: [
|
||||
{ value: '选项1', label: '黄金糕' },
|
||||
{ value: '选项2', label: '双皮奶' },
|
||||
{ value: '选项3', label: '蚵仔煎' },
|
||||
{ value: '选项4', label: '龙须面' }
|
||||
],
|
||||
value: '',
|
||||
gridData: [{
|
||||
date: '2016-05-02',
|
||||
name: 'John Smith',
|
||||
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||
}, {
|
||||
date: '2016-05-04',
|
||||
name: 'John Smith',
|
||||
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||
}, {
|
||||
date: '2016-05-01',
|
||||
name: 'John Smith',
|
||||
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||
}, {
|
||||
date: '2016-05-03',
|
||||
name: 'John Smith',
|
||||
address: 'No.1518, Jinshajiang Road, Putuo District'
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// v-el-drag-dialog onDrag callback function
|
||||
handleDrag() {
|
||||
this.$refs.select.blur()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,68 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container board">
|
||||
<Kanban :key="1" :list="list1" :options="options" class="kanban todo" header-text="Todo"/>
|
||||
<Kanban :key="2" :list="list2" :options="options" class="kanban working" header-text="Working"/>
|
||||
<Kanban :key="3" :list="list3" :options="options" class="kanban done" header-text="Done"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Kanban from '@/components/Kanban'
|
||||
|
||||
export default {
|
||||
name: 'DragKanbanDemo',
|
||||
components: {
|
||||
Kanban
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
options: {
|
||||
group: 'mission'
|
||||
},
|
||||
list1: [
|
||||
{ name: 'Mission', id: 1 },
|
||||
{ name: 'Mission', id: 2 },
|
||||
{ name: 'Mission', id: 3 },
|
||||
{ name: 'Mission', id: 4 }
|
||||
],
|
||||
list2: [
|
||||
{ name: 'Mission', id: 5 },
|
||||
{ name: 'Mission', id: 6 },
|
||||
{ name: 'Mission', id: 7 }
|
||||
],
|
||||
list3: [
|
||||
{ name: 'Mission', id: 8 },
|
||||
{ name: 'Mission', id: 9 },
|
||||
{ name: 'Mission', id: 10 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.board {
|
||||
width: 1000px;
|
||||
margin-left: 20px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.kanban {
|
||||
&.todo {
|
||||
.board-column-header {
|
||||
background: #4A9FF9;
|
||||
}
|
||||
}
|
||||
&.working {
|
||||
.board-column-header {
|
||||
background: #f9944a;
|
||||
}
|
||||
}
|
||||
&.done {
|
||||
.board-column-header {
|
||||
background: #2ac06d;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
|
||||
<el-drag-select v-model="value" style="width:500px;" multiple placeholder="请选择">
|
||||
<el-option v-for="item in options" :label="item.label" :value="item.value" :key="item.value" />
|
||||
</el-drag-select>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<el-tag v-for="item of value" :key="item" style="margin-right:15px;">{{ item }}</el-tag>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ElDragSelect from '@/components/DragSelect' // base on element-ui
|
||||
|
||||
export default {
|
||||
name: 'DragSelectDemo',
|
||||
components: { ElDragSelect },
|
||||
data: function() {
|
||||
return {
|
||||
value: ['Apple', 'Banana', 'Orange'],
|
||||
options: [{
|
||||
value: 'Apple',
|
||||
label: 'Apple'
|
||||
}, {
|
||||
value: 'Banana',
|
||||
label: 'Banana'
|
||||
}, {
|
||||
value: 'Orange',
|
||||
label: 'Orange'
|
||||
}, {
|
||||
value: 'Pear',
|
||||
label: 'Pear'
|
||||
}, {
|
||||
value: 'Strawberry',
|
||||
label: 'Strawberry'
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,31 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<code>
|
||||
Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>.
|
||||
{{ $t('components.dropzoneTips') }}
|
||||
</code>
|
||||
<div class="editor-container">
|
||||
<dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dropzone from '@/components/Dropzone'
|
||||
|
||||
export default {
|
||||
name: 'DropzoneDemo',
|
||||
components: { Dropzone },
|
||||
methods: {
|
||||
dropzoneS(file) {
|
||||
console.log(file)
|
||||
this.$message({ message: 'Upload success', type: 'success' })
|
||||
},
|
||||
dropzoneR(file) {
|
||||
console.log(file)
|
||||
this.$message({ message: 'Delete success', type: 'success' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<code>JsonEditor is base on <a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirrorr</a> , lint base on json-lint </code>
|
||||
<div class="editor-container">
|
||||
<json-editor ref="jsonEditor" v-model="value"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JsonEditor from '@/components/JsonEditor'
|
||||
|
||||
const jsonData = '[{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"CORN"}],"name":""},{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"XAGUSD"},{"market_type":"forexdata","symbol":"AUTD"},{"market_type":"forexdata","symbol":"AGTD"}],"name":"贵金属"},{"items":[{"market_type":"forexdata","symbol":"CORN"},{"market_type":"forexdata","symbol":"WHEAT"},{"market_type":"forexdata","symbol":"SOYBEAN"},{"market_type":"forexdata","symbol":"SUGAR"}],"name":"农产品"},{"items":[{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"USOIL"},{"market_type":"forexdata","symbol":"NGAS"}],"name":"能源化工"}]'
|
||||
|
||||
export default {
|
||||
name: 'JsonEditorDemo',
|
||||
components: { JsonEditor },
|
||||
data: function() {
|
||||
return {
|
||||
value: JSON.parse(jsonData)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.editor-container{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
|
||||
<code>Markdown is based on
|
||||
<a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> ,Simply encapsulated in Vue.
|
||||
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html">
|
||||
Documentation </a>
|
||||
</code>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">Basic:</el-tag>
|
||||
<markdown-editor v-model="content" height="300px"/>
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">Markdown Mode:</el-tag>
|
||||
<markdown-editor ref="markdownEditor" v-model="content" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px"/>
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">Customize Toolbar:</el-tag>
|
||||
<markdown-editor
|
||||
ref="markdownEditor"
|
||||
v-model="content"
|
||||
:options="{ toolbarItems: ['heading','bold','italic']}"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<el-tag class="tag-title">I18n:</el-tag>
|
||||
<el-alert :closable="false" title="You can change the language of the admin system to see the effect" type="success"/>
|
||||
<markdown-editor v-model="content" :language="language" height="300px"/>
|
||||
</div>
|
||||
|
||||
<el-button style="margin-top:80px;" type="primary" icon="el-icon-document" @click="getHtml">Get HTML</el-button>
|
||||
<div v-html="html"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MarkdownEditor from '@/components/MarkdownEditor'
|
||||
|
||||
const content = `
|
||||
**This is test**
|
||||
|
||||
* vue
|
||||
* element
|
||||
* webpack
|
||||
|
||||
`
|
||||
export default {
|
||||
name: 'MarkdownDemo',
|
||||
components: { MarkdownEditor },
|
||||
data: function() {
|
||||
return {
|
||||
content: content,
|
||||
html: '',
|
||||
languageTypeList: {
|
||||
'en': 'en_US',
|
||||
'zh': 'zh_CN',
|
||||
'es': 'es_ES'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language() {
|
||||
return this.languageTypeList[this.$store.getters.language]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getHtml() {
|
||||
this.html = this.$refs.markdownEditor.getHtml()
|
||||
console.log(this.html)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.editor-container{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.tag-title{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
|
@ -1,153 +0,0 @@
|
|||
<template>
|
||||
<div class="mixin-components-container">
|
||||
<el-row>
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>Buttons</span>
|
||||
</div>
|
||||
<div style="margin-bottom:50px;">
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn blue-btn" to="/documentation/index">Documentation</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn light-blue-btn" to="/icon/index">Icons</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn pink-btn" to="/excel/export-excel">Excel</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn green-btn" to="/table/complex-table">Table</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn tiffany-btn" to="/example/create">Form</router-link>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-center">
|
||||
<router-link class="pan-btn yellow-btn" to="/theme/index">Theme</router-link>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20" style="margin-top:50px;">
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>Material Design 的input</span>
|
||||
</div>
|
||||
<div style="height:100px;">
|
||||
<el-form :model="demo" :rules="demoRules">
|
||||
<el-form-item prop="title">
|
||||
<md-input v-model="demo.title" icon="search" name="title" placeholder="输入标题">标题</md-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>图片hover效果</span>
|
||||
</div>
|
||||
<div class="component-item">
|
||||
<pan-thumb width="100px" height="100px" image="https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191">
|
||||
vue-element-admin
|
||||
</pan-thumb>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>水波纹 waves v-directive</span>
|
||||
</div>
|
||||
<div class="component-item">
|
||||
<el-button v-waves type="primary">水波纹效果</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>hover text</span>
|
||||
</div>
|
||||
<div class="component-item">
|
||||
<mallki class-name="mallki-text" text="vue-element-admin"/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20" style="margin-top:50px;">
|
||||
<el-col :span="8">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>Share</span>
|
||||
</div>
|
||||
<div class="component-item" style="height:420px;">
|
||||
<dropdown-menu :items="articleList" style="margin:0 auto;" title="系列文章"/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PanThumb from '@/components/PanThumb'
|
||||
import MdInput from '@/components/MDinput'
|
||||
import Mallki from '@/components/TextHoverEffect/Mallki'
|
||||
import DropdownMenu from '@/components/Share/dropdownMenu'
|
||||
import waves from '@/directive/waves/index.js' // 水波纹指令
|
||||
|
||||
export default {
|
||||
name: 'ComponentMixinDemo',
|
||||
components: {
|
||||
PanThumb,
|
||||
MdInput,
|
||||
Mallki,
|
||||
DropdownMenu
|
||||
},
|
||||
directives: {
|
||||
waves
|
||||
},
|
||||
data: function() {
|
||||
const validate = (rule, value, callback) => {
|
||||
if (value.length !== 6) {
|
||||
callback(new Error('请输入六个字符'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
demo: {
|
||||
title: ''
|
||||
},
|
||||
demoRules: {
|
||||
title: [{ required: true, trigger: 'change', validator: validate }]
|
||||
},
|
||||
articleList: [
|
||||
{ title: '基础篇', href: 'https://juejin.im/post/59097cd7a22b9d0065fb61d2' },
|
||||
{ title: '登录权限篇', href: 'https://juejin.im/post/591aa14f570c35006961acac' },
|
||||
{ title: '实战篇', href: 'https://juejin.im/post/593121aa0ce4630057f70d35' },
|
||||
{ title: 'vue-admin-template 篇', href: 'https://juejin.im/post/595b4d776fb9a06bbe7dba56' },
|
||||
{ title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mixin-components-container {
|
||||
background-color: #f0f2f5;
|
||||
padding: 30px;
|
||||
min-height: calc(100vh - 84px);
|
||||
}
|
||||
.component-item{
|
||||
min-height: 100px;
|
||||
}
|
||||
</style>
|
|
@ -1,67 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<code><strong>SplitPane</strong> If you've used
|
||||
<a href="http://codepen.io/" target="_blank"> codepen</a>,
|
||||
<a href="https://jsfiddle.net/" target="_blank"> jsfiddle </a>will not be unfamiliar.
|
||||
<a href="https://github.com/PanJiaChen/vue-split-pane" target="_blank"> Github repository</a>
|
||||
</code>
|
||||
<split-pane split="vertical" @resize="resize">
|
||||
<template slot="paneL">
|
||||
<div class="left-container"/>
|
||||
</template>
|
||||
<template slot="paneR">
|
||||
<split-pane split="horizontal">
|
||||
<template slot="paneL">
|
||||
<div class="top-container"/>
|
||||
</template>
|
||||
<template slot="paneR">
|
||||
<div class="bottom-container"/>
|
||||
</template>
|
||||
</split-pane>
|
||||
</template>
|
||||
</split-pane>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import splitPane from 'vue-splitpane'
|
||||
|
||||
export default {
|
||||
name: 'SplitpaneDemo',
|
||||
components: { splitPane },
|
||||
methods: {
|
||||
resize() {
|
||||
console.log('resize')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.components-container {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.left-container {
|
||||
background-color: #F38181;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.right-container {
|
||||
background-color: #FCE38A;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.top-container {
|
||||
background-color: #FCE38A;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bottom-container {
|
||||
width: 100%;
|
||||
background-color: #95E1D3;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -1,128 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<sticky class-name="sub-navbar">
|
||||
<el-dropdown trigger="click">
|
||||
<el-button plain>
|
||||
Platform<i class="el-icon-caret-bottom el-icon--right"/>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown" class="no-border">
|
||||
<el-checkbox-group v-model="platforms" style="padding: 5px 15px;">
|
||||
<el-checkbox v-for="item in platformsOptions" :label="item.key" :key="item.key">
|
||||
{{ item.name }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<el-dropdown trigger="click">
|
||||
<el-button plain>
|
||||
Link<i class="el-icon-caret-bottom el-icon--right"/>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:300px">
|
||||
<el-input v-model="url" placeholder="Please enter the content">
|
||||
<template slot="prepend">Url</template>
|
||||
</el-input>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<div class="time-container">
|
||||
<el-date-picker v-model="time" :picker-options="pickerOptions" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Release time"/>
|
||||
</div>
|
||||
|
||||
<el-button style="margin-left: 10px;" type="success">publish
|
||||
</el-button>
|
||||
</sticky>
|
||||
|
||||
<div class="components-container">
|
||||
<code>Sticky header, {{ $t('components.stickyTips') }}</code>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
<div>placeholder</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sticky from '@/components/Sticky'
|
||||
|
||||
export default {
|
||||
name: 'StickyDemo',
|
||||
components: { Sticky },
|
||||
data: function() {
|
||||
return {
|
||||
time: '',
|
||||
url: '',
|
||||
platforms: ['a-platform'],
|
||||
platformsOptions: [
|
||||
{ key: 'a-platform', name: 'platformA' },
|
||||
{ key: 'b-platform', name: 'platformB' },
|
||||
{ key: 'c-platform', name: 'platformC' }
|
||||
],
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() > Date.now()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.components-container div {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.time-container {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||
<template>
|
||||
<div class="components-container">
|
||||
<code>
|
||||
{{ $t('components.tinymceTips') }}
|
||||
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html"> {{ $t('components.documentation') }}</a>
|
||||
</code>
|
||||
<div>
|
||||
<tinymce :height="300" v-model="content"/>
|
||||
</div>
|
||||
<div class="editor-content" v-html="content"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Tinymce from '@/components/Tinymce'
|
||||
|
||||
export default {
|
||||
name: 'TinymceDemo',
|
||||
components: { Tinymce },
|
||||
data: function() {
|
||||
return {
|
||||
content:
|
||||
`<h1 style="text-align: center;">Welcome to the TinyMCE demo!</h1><p style="text-align: center; font-size: 15px;"><img title="TinyMCE Logo" src="//www.tinymce.com/images/glyph-tinymce@2x.png" alt="TinyMCE Logo" width="110" height="97" /><ul>
|
||||
<li>Our <a href="//www.tinymce.com/docs/">documentation</a> is a great resource for learning how to configure TinyMCE.</li><li>Have a specific question? Visit the <a href="https://community.tinymce.com/forum/">Community Forum</a>.</li><li>We also offer enterprise grade support as part of <a href="https://tinymce.com/pricing">TinyMCE premium subscriptions</a>.</li>
|
||||
</ul>`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.editor-content{
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
<template>
|
||||
<div class="createPost-container">
|
||||
<el-form ref="postForm" :model="postForm" :rules="rules" class="form-container">
|
||||
|
||||
<sticky :class-name="'sub-navbar '+postForm.status">
|
||||
<CommentDropdown v-model="postForm.comment_disabled" />
|
||||
<PlatformDropdown v-model="postForm.platforms" />
|
||||
<SourceUrlDropdown v-model="postForm.source_uri" />
|
||||
<el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">发布
|
||||
</el-button>
|
||||
<el-button v-loading="loading" type="warning" @click="draftForm">草稿</el-button>
|
||||
</sticky>
|
||||
|
||||
<div class="createPost-main-container">
|
||||
<el-row>
|
||||
|
||||
<Warning />
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item style="margin-bottom: 40px;" prop="title">
|
||||
<MDinput v-model="postForm.title" :maxlength="100" name="name" required>
|
||||
标题
|
||||
</MDinput>
|
||||
</el-form-item>
|
||||
|
||||
<div class="postInfo-container">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label-width="45px" label="作者:" class="postInfo-container-item">
|
||||
<el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable remote placeholder="搜索用户">
|
||||
<el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="10">
|
||||
<el-form-item label-width="80px" label="发布时间:" class="postInfo-container-item">
|
||||
<el-date-picker v-model="postForm.display_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label-width="60px" label="重要性:" class="postInfo-container-item">
|
||||
<el-rate
|
||||
v-model="postForm.importance"
|
||||
:max="3"
|
||||
:colors="['#99A9BF', '#F7BA2A', '#FF9900']"
|
||||
:low-threshold="1"
|
||||
:high-threshold="3"
|
||||
style="margin-top:8px;"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item style="margin-bottom: 40px;" label-width="45px" label="摘要:">
|
||||
<el-input :rows="1" v-model="postForm.content_short" type="textarea" class="article-textarea" autosize placeholder="请输入内容"/>
|
||||
<span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}字</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="content" style="margin-bottom: 30px;">
|
||||
<Tinymce ref="editor" :height="400" v-model="postForm.content" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="image_uri" style="margin-bottom: 30px;">
|
||||
<Upload v-model="postForm.image_uri" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Tinymce from '@/components/Tinymce'
|
||||
import Upload from '@/components/Upload/singleImage3'
|
||||
import MDinput from '@/components/MDinput'
|
||||
import Sticky from '@/components/Sticky' // 粘性header组件
|
||||
import { validateURL } from '@/utils/validate'
|
||||
import { fetchArticle } from '@/api/article'
|
||||
import { userSearch } from '@/api/remoteSearch'
|
||||
import Warning from './Warning'
|
||||
import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
|
||||
|
||||
const defaultForm = {
|
||||
status: 'draft',
|
||||
title: '', // 文章题目
|
||||
content: '', // 文章内容
|
||||
content_short: '', // 文章摘要
|
||||
source_uri: '', // 文章外链
|
||||
image_uri: '', // 文章图片
|
||||
display_time: undefined, // 前台展示时间
|
||||
id: undefined,
|
||||
platforms: ['a-platform'],
|
||||
comment_disabled: false,
|
||||
importance: 0
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'ArticleDetail',
|
||||
components: { Tinymce, MDinput, Upload, Sticky, Warning, CommentDropdown, PlatformDropdown, SourceUrlDropdown },
|
||||
props: {
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
const validateRequire = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
this.$message({
|
||||
message: rule.field + '为必传项',
|
||||
type: 'error'
|
||||
})
|
||||
callback(new Error(rule.field + '为必传项'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validateSourceUri = (rule, value, callback) => {
|
||||
if (value) {
|
||||
if (validateURL(value)) {
|
||||
callback()
|
||||
} else {
|
||||
this.$message({
|
||||
message: '外链url填写不正确',
|
||||
type: 'error'
|
||||
})
|
||||
callback(new Error('外链url填写不正确'))
|
||||
}
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
postForm: Object.assign({}, defaultForm),
|
||||
loading: false,
|
||||
userListOptions: [],
|
||||
rules: {
|
||||
image_uri: [{ validator: validateRequire }],
|
||||
title: [{ validator: validateRequire }],
|
||||
content: [{ validator: validateRequire }],
|
||||
source_uri: [{ validator: validateSourceUri, trigger: 'blur' }]
|
||||
},
|
||||
tempRoute: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
contentShortLength() {
|
||||
return this.postForm.content_short.length
|
||||
},
|
||||
lang() {
|
||||
return this.$store.getters.language
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.isEdit) {
|
||||
const id = this.$route.params && this.$route.params.id
|
||||
this.fetchData(id)
|
||||
} else {
|
||||
this.postForm = Object.assign({}, defaultForm)
|
||||
}
|
||||
|
||||
// Why need to make a copy of this.$route here?
|
||||
// Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page
|
||||
// https://github.com/PanJiaChen/vue-element-admin/issues/1221
|
||||
this.tempRoute = Object.assign({}, this.$route)
|
||||
},
|
||||
methods: {
|
||||
fetchData(id) {
|
||||
fetchArticle(id).then(response => {
|
||||
this.postForm = response.data
|
||||
// Just for test
|
||||
this.postForm.title += ` Article Id:${this.postForm.id}`
|
||||
this.postForm.content_short += ` Article Id:${this.postForm.id}`
|
||||
|
||||
// Set tagsview title
|
||||
this.setTagsViewTitle()
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
setTagsViewTitle() {
|
||||
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
|
||||
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
|
||||
this.$store.dispatch('updateVisitedView', route)
|
||||
},
|
||||
submitForm() {
|
||||
this.postForm.display_time = parseInt(this.display_time / 1000)
|
||||
console.log(this.postForm)
|
||||
this.$refs.postForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '发布文章成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
this.postForm.status = 'published'
|
||||
this.loading = false
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
draftForm() {
|
||||
if (this.postForm.content.length === 0 || this.postForm.title.length === 0) {
|
||||
this.$message({
|
||||
message: '请填写必要的标题和内容',
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
message: '保存成功',
|
||||
type: 'success',
|
||||
showClose: true,
|
||||
duration: 1000
|
||||
})
|
||||
this.postForm.status = 'draft'
|
||||
},
|
||||
getRemoteUserList(query) {
|
||||
userSearch(query).then(response => {
|
||||
if (!response.data.items) return
|
||||
this.userListOptions = response.data.items.map(v => v.name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
@import "~@/styles/mixin.scss";
|
||||
.createPost-container {
|
||||
position: relative;
|
||||
.createPost-main-container {
|
||||
padding: 40px 45px 20px 50px;
|
||||
.postInfo-container {
|
||||
position: relative;
|
||||
@include clearfix;
|
||||
margin-bottom: 10px;
|
||||
.postInfo-container-item {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
.word-counter {
|
||||
width: 40px;
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 0px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,36 +0,0 @@
|
|||
<template>
|
||||
<el-dropdown :show-timeout="100" trigger="click">
|
||||
<el-button plain>{{ !comment_disabled?'评论已打开':'评论已关闭' }}
|
||||
<i class="el-icon-caret-bottom el-icon--right"/>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown" class="no-padding">
|
||||
<el-dropdown-item>
|
||||
<el-radio-group v-model="comment_disabled" style="padding: 10px;">
|
||||
<el-radio :label="true">关闭评论</el-radio>
|
||||
<el-radio :label="false">打开评论</el-radio>
|
||||
</el-radio-group>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
comment_disabled: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,46 +0,0 @@
|
|||
<template>
|
||||
<el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click">
|
||||
<el-button plain>
|
||||
平台({{ platforms.length }})
|
||||
<i class="el-icon-caret-bottom el-icon--right"/>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown" class="no-border">
|
||||
<el-checkbox-group v-model="platforms" style="padding: 5px 15px;">
|
||||
<el-checkbox v-for="item in platformsOptions" :label="item.key" :key="item.key">
|
||||
{{ item.name }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
required: true,
|
||||
default: () => [],
|
||||
type: Array
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
platformsOptions: [
|
||||
{ key: 'a-platform', name: 'a-platform' },
|
||||
{ key: 'b-platform', name: 'b-platform' },
|
||||
{ key: 'c-platform', name: 'c-platform' }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
platforms: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,36 +0,0 @@
|
|||
<template>
|
||||
<el-dropdown :show-timeout="100" trigger="click">
|
||||
<el-button plain>
|
||||
外链
|
||||
<i class="el-icon-caret-bottom el-icon--right"/>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px">
|
||||
<el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri">
|
||||
<el-input v-model="source_uri" placeholder="请输入内容">
|
||||
<template slot="prepend">填写url</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
source_uri: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,3 +0,0 @@
|
|||
export { default as CommentDropdown } from './Comment'
|
||||
export { default as PlatformDropdown } from './Platform'
|
||||
export { default as SourceUrlDropdown } from './SourceUrl'
|
|
@ -1,10 +0,0 @@
|
|||
<template>
|
||||
<p class="warn-content">
|
||||
创建和编辑页面是不能被keep-alive 缓存的,因为keep-alive 的include 目前不支持根据路由来缓存,所以目前都是基于component name 来缓存的,如果你想要实现缓存的效果,可以使用localstorage 等浏览器缓存方案。或者不要使用keep-alive
|
||||
的include,直接缓存所有页面。详情见
|
||||
<a
|
||||
href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html"
|
||||
target="_blank">文档</a>
|
||||
</p>
|
||||
</template>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<template>
|
||||
<article-detail :is-edit="false"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ArticleDetail from './components/ArticleDetail'
|
||||
|
||||
export default {
|
||||
name: 'CreateForm',
|
||||
components: { ArticleDetail }
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<template>
|
||||
<article-detail :is-edit="true"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ArticleDetail from './components/ArticleDetail'
|
||||
|
||||
export default {
|
||||
name: 'EditForm',
|
||||
components: { ArticleDetail }
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column align="center" label="ID" width="80">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="180px" align="center" label="Date">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="120px" align="center" label="Author">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.author }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="100px" label="Importance">
|
||||
<template slot-scope="scope">
|
||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column class-name="status-col" label="Status" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column min-width="300px" label="Title">
|
||||
<template slot-scope="scope">
|
||||
|
||||
<router-link :to="'/example/edit/'+scope.row.id" class="link-type">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="Actions" width="120">
|
||||
<template slot-scope="scope">
|
||||
<router-link :to="'/example/edit/'+scope.row.id">
|
||||
<el-button type="primary" size="small" icon="el-icon-edit">Edit</el-button>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/article'
|
||||
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
|
||||
|
||||
export default {
|
||||
name: 'ArticleList',
|
||||
components: { Pagination },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
list: null,
|
||||
total: 0,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.limit = val
|
||||
this.getList()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.page = val
|
||||
this.getList()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.edit-input {
|
||||
padding-right: 100px;
|
||||
}
|
||||
.cancel-btn {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 10px;
|
||||
}
|
||||
</style>
|
|
@ -1,30 +0,0 @@
|
|||
<template>
|
||||
<div style="display:inline-block;">
|
||||
<label class="radio-label">Cell Auto-Width: </label>
|
||||
<el-radio-group v-model="autoWidth">
|
||||
<el-radio :label="true" border>True</el-radio>
|
||||
<el-radio :label="false" border>False</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
autoWidth: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,38 +0,0 @@
|
|||
<template>
|
||||
<div style="display:inline-block;">
|
||||
<label class="radio-label">Book Type: </label>
|
||||
<el-select v-model="bookType" style="width:120px;" >
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: 'xlsx'
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
options: ['xlsx', 'csv', 'txt']
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
bookType: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,28 +0,0 @@
|
|||
<template>
|
||||
<div style="display:inline-block;">
|
||||
<!-- $t is vue-i18n global function to translate lang -->
|
||||
<label class="radio-label" style="padding-left:0;">Filename: </label>
|
||||
<el-input :placeholder="$t('excel.placeholder')" v-model="filename" style="width:340px;" prefix-icon="el-icon-document"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filename: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,117 +0,0 @@
|
|||
<template>
|
||||
<!-- $t is vue-i18n global function to translate lang -->
|
||||
<div class="app-container">
|
||||
|
||||
<div>
|
||||
<FilenameOption v-model="filename" />
|
||||
<AutoWidthOption v-model="autoWidth" />
|
||||
<BookTypeOption v-model="bookType" />
|
||||
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="handleDownload">{{ $t('excel.export') }} Excel</el-button>
|
||||
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||
<el-tag type="info">Documentation</el-tag>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
|
||||
<el-table-column align="center" label="Id" width="95">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.$index }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Title">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.title }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Author" width="110" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag>{{ scope.row.author }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Readings" width="115" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.pageviews }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="Date" width="220">
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-time"/>
|
||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/article'
|
||||
import { parseTime } from '@/utils'
|
||||
|
||||
// options components
|
||||
import FilenameOption from './components/FilenameOption'
|
||||
import AutoWidthOption from './components/AutoWidthOption'
|
||||
import BookTypeOption from './components/BookTypeOption'
|
||||
|
||||
export default {
|
||||
name: 'ExportExcel',
|
||||
components: { FilenameOption, AutoWidthOption, BookTypeOption },
|
||||
data: function() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
downloadLoading: false,
|
||||
filename: '',
|
||||
autoWidth: true,
|
||||
bookType: 'xlsx'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.listLoading = true
|
||||
fetchList().then(response => {
|
||||
this.list = response.data.items
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
|
||||
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
||||
const list = this.list
|
||||
const data = this.formatJson(filterVal, list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: this.filename,
|
||||
autoWidth: this.autoWidth,
|
||||
bookType: this.bookType
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.radio-label {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
line-height: 40px;
|
||||
padding: 0 12px 0 30px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<!-- $t is vue-i18n global function to translate lang -->
|
||||
<el-input :placeholder="$t('excel.placeholder')" v-model="filename" style="width:340px;" prefix-icon="el-icon-document"/>
|
||||
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="document" @click="handleDownload">{{ $t('excel.selectedExport') }}</el-button>
|
||||
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||
<el-tag type="info">Documentation</el-tag>
|
||||
</a>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
ref="multipleTable"
|
||||
:data="list"
|
||||
element-loading-text="拼命加载中"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" align="center"/>
|
||||
<el-table-column align="center" label="Id" width="95">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.$index }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Title">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.title }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Author" width="110" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag>{{ scope.row.author }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Readings" width="115" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.pageviews }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="PDate" width="220">
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-time"/>
|
||||
<span>{{ scope.row.display_time }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/article'
|
||||
|
||||
export default {
|
||||
name: 'SelectExcel',
|
||||
data: function() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
multipleSelection: [],
|
||||
downloadLoading: false,
|
||||
filename: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
},
|
||||
handleDownload() {
|
||||
if (this.multipleSelection.length) {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
|
||||
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
||||
const list = this.multipleSelection
|
||||
const data = this.formatJson(filterVal, list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: this.filename
|
||||
})
|
||||
this.$refs.multipleTable.clearSelection()
|
||||
this.downloadLoading = false
|
||||
})
|
||||
} else {
|
||||
this.$message({
|
||||
message: 'Please select at least one item',
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => v[j]))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,42 +0,0 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload"/>
|
||||
<el-table :data="tableData" border highlight-current-row style="width: 100%;margin-top:20px;">
|
||||
<el-table-column v-for="item of tableHeader" :prop="item" :label="item" :key="item"/>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UploadExcelComponent from '@/components/UploadExcel/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'UploadExcel',
|
||||
components: { UploadExcelComponent },
|
||||
data: function() {
|
||||
return {
|
||||
tableData: [],
|
||||
tableHeader: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeUpload(file) {
|
||||
const isLt1M = file.size / 1024 / 1024 < 1
|
||||
|
||||
if (isLt1M) {
|
||||
return true
|
||||
}
|
||||
|
||||
this.$message({
|
||||
message: 'Please do not upload files larger than 1m in size.',
|
||||
type: 'warning'
|
||||
})
|
||||
return false
|
||||
},
|
||||
handleSuccess({ results, header }) {
|
||||
this.tableData = results
|
||||
this.tableHeader = header
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,102 +0,0 @@
|
|||
<template>
|
||||
<el-table :data="list" border fit highlight-current-row style="width: 100%">
|
||||
|
||||
<el-table-column
|
||||
v-loading="loading"
|
||||
align="center"
|
||||
label="ID"
|
||||
width="65"
|
||||
element-loading-text="请给我点时间!">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="180px" align="center" label="Date">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column min-width="300px" label="Title">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
<el-tag>{{ scope.row.type }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="110px" align="center" label="Author">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.author }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="120px" label="Importance">
|
||||
<template slot-scope="scope">
|
||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="Readings" width="95">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.pageviews }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column class-name="status-col" label="Status" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/article'
|
||||
|
||||
export default {
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'CN'
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
list: null,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 5,
|
||||
type: this.type,
|
||||
sort: '+id'
|
||||
},
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true
|
||||
this.$emit('create') // for test
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
<template>
|
||||
<div class="tab-container">
|
||||
<el-tag>mounted times :{{ createdTimes }}</el-tag>
|
||||
<el-alert :closable="false" style="width:200px;display:inline-block;vertical-align: middle;margin-left:30px;" title="Tab with keep-alive" type="success"/>
|
||||
<el-tabs v-model="activeName" style="margin-top:15px;" type="border-card">
|
||||
<el-tab-pane v-for="item in tabMapOptions" :label="item.label" :key="item.key" :name="item.key">
|
||||
<keep-alive>
|
||||
<tab-pane v-if="activeName==item.key" :type="item.key" @create="showCreatedTimes"/>
|
||||
</keep-alive>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tabPane from './components/tabPane'
|
||||
|
||||
export default {
|
||||
name: 'Tab',
|
||||
components: { tabPane },
|
||||
data: function() {
|
||||
return {
|
||||
tabMapOptions: [
|
||||
{ label: 'China', key: 'CN' },
|
||||
{ label: 'USA', key: 'US' },
|
||||
{ label: 'Japan', key: 'JP' },
|
||||
{ label: 'Eurozone', key: 'EU' }
|
||||
],
|
||||
activeName: 'CN',
|
||||
createdTimes: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showCreatedTimes() {
|
||||
this.createdTimes = this.createdTimes + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tab-container{
|
||||
margin: 30px;
|
||||
}
|
||||
</style>
|
|
@ -1,362 +0,0 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input :placeholder="$t('table.title')" v-model="listQuery.title" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter"/>
|
||||
<el-select v-model="listQuery.importance" :placeholder="$t('table.importance')" clearable style="width: 90px" class="filter-item">
|
||||
<el-option v-for="item in importanceOptions" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
<el-select v-model="listQuery.type" :placeholder="$t('table.type')" clearable class="filter-item" style="width: 130px">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name+'('+item.key+')'" :value="item.key"/>
|
||||
</el-select>
|
||||
<el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
|
||||
<el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key"/>
|
||||
</el-select>
|
||||
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
|
||||
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">{{ $t('table.add') }}</el-button>
|
||||
<el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">{{ $t('table.export') }}</el-button>
|
||||
<el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">{{ $t('table.reviewer') }}</el-checkbox>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:key="tableKey"
|
||||
:data="list"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
style="width: 100%;"
|
||||
@sort-change="sortChange">
|
||||
<el-table-column :label="$t('table.id')" prop="id" sortable="custom" align="center" width="65">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.date')" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.title')" min-width="150px">
|
||||
<template slot-scope="scope">
|
||||
<span class="link-type" @click="handleUpdate(scope.row)">{{ scope.row.title }}</span>
|
||||
<el-tag>{{ scope.row.type | typeFilter }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.author')" width="110px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.author }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="showReviewer" :label="$t('table.reviewer')" width="110px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span style="color:red;">{{ scope.row.reviewer }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.importance')" width="80px">
|
||||
<template slot-scope="scope">
|
||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.readings')" align="center" width="95">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.pageviews" class="link-type" @click="handleFetchPv(scope.row.pageviews)">{{ scope.row.pageviews }}</span>
|
||||
<span v-else>0</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.status')" class-name="status-col" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.actions')" align="center" width="230" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">{{ $t('table.edit') }}</el-button>
|
||||
<el-button v-if="scope.row.status!='published'" size="mini" type="success" @click="handleModifyStatus(scope.row,'published')">{{ $t('table.publish') }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.status!='draft'" size="mini" @click="handleModifyStatus(scope.row,'draft')">{{ $t('table.draft') }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.status!='deleted'" size="mini" type="danger" @click="handleModifyStatus(scope.row,'deleted')">{{ $t('table.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
|
||||
|
||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
||||
<el-form-item :label="$t('table.type')" prop="type">
|
||||
<el-select v-model="temp.type" class="filter-item" placeholder="Please select">
|
||||
<el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.date')" prop="timestamp">
|
||||
<el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.title')" prop="title">
|
||||
<el-input v-model="temp.title"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.status')">
|
||||
<el-select v-model="temp.status" class="filter-item" placeholder="Please select">
|
||||
<el-option v-for="item in statusOptions" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.importance')">
|
||||
<el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('table.remark')">
|
||||
<el-input :autosize="{ minRows: 2, maxRows: 4}" v-model="temp.remark" type="textarea" placeholder="Please input"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">{{ $t('table.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
|
||||
<el-table :data="pvData" border fit highlight-current-row style="width: 100%">
|
||||
<el-table-column prop="key" label="Channel"/>
|
||||
<el-table-column prop="pv" label="Pv"/>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
|
||||
import waves from '@/directive/waves' // Waves directive
|
||||
import { parseTime } from '@/utils'
|
||||
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
|
||||
|
||||
const calendarTypeOptions = [
|
||||
{ key: 'CN', display_name: 'China' },
|
||||
{ key: 'US', display_name: 'USA' },
|
||||
{ key: 'JP', display_name: 'Japan' },
|
||||
{ key: 'EU', display_name: 'Eurozone' }
|
||||
]
|
||||
|
||||
// arr to obj ,such as { CN : "China", US : "USA" }
|
||||
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
||||
acc[cur.key] = cur.display_name
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
export default {
|
||||
name: 'ComplexTable',
|
||||
components: { Pagination },
|
||||
directives: { waves },
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
},
|
||||
typeFilter(type) {
|
||||
return calendarTypeKeyValue[type]
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
tableKey: 0,
|
||||
list: null,
|
||||
total: 0,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
importance: undefined,
|
||||
title: undefined,
|
||||
type: undefined,
|
||||
sort: '+id'
|
||||
},
|
||||
importanceOptions: [1, 2, 3],
|
||||
calendarTypeOptions,
|
||||
sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
|
||||
statusOptions: ['published', 'draft', 'deleted'],
|
||||
showReviewer: false,
|
||||
temp: {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
type: '',
|
||||
status: 'published'
|
||||
},
|
||||
dialogFormVisible: false,
|
||||
dialogStatus: '',
|
||||
textMap: {
|
||||
update: 'Edit',
|
||||
create: 'Create'
|
||||
},
|
||||
dialogPvVisible: false,
|
||||
pvData: [],
|
||||
rules: {
|
||||
type: [{ required: true, message: 'type is required', trigger: 'change' }],
|
||||
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
|
||||
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
|
||||
},
|
||||
downloadLoading: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
|
||||
// Just to simulate the time of the request
|
||||
setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 1.5 * 1000)
|
||||
})
|
||||
},
|
||||
handleFilter() {
|
||||
this.listQuery.page = 1
|
||||
this.getList()
|
||||
},
|
||||
handleModifyStatus(row, status) {
|
||||
this.$message({
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
row.status = status
|
||||
},
|
||||
sortChange(data) {
|
||||
const { prop, order } = data
|
||||
if (prop === 'id') {
|
||||
this.sortByID(order)
|
||||
}
|
||||
},
|
||||
sortByID(order) {
|
||||
if (order === 'ascending') {
|
||||
this.listQuery.sort = '+id'
|
||||
} else {
|
||||
this.listQuery.sort = '-id'
|
||||
}
|
||||
this.handleFilter()
|
||||
},
|
||||
resetTemp() {
|
||||
this.temp = {
|
||||
id: undefined,
|
||||
importance: 1,
|
||||
remark: '',
|
||||
timestamp: new Date(),
|
||||
title: '',
|
||||
status: 'published',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
handleCreate() {
|
||||
this.resetTemp()
|
||||
this.dialogStatus = 'create'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
createData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
|
||||
this.temp.author = 'vue-element-admin'
|
||||
createArticle(this.temp).then(() => {
|
||||
this.list.unshift(this.temp)
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '创建成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.temp = Object.assign({}, row) // copy obj
|
||||
this.temp.timestamp = new Date(this.temp.timestamp)
|
||||
this.dialogStatus = 'update'
|
||||
this.dialogFormVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs['dataForm'].clearValidate()
|
||||
})
|
||||
},
|
||||
updateData() {
|
||||
this.$refs['dataForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
const tempData = Object.assign({}, this.temp)
|
||||
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
|
||||
updateArticle(tempData).then(() => {
|
||||
for (const v of this.list) {
|
||||
if (v.id === this.temp.id) {
|
||||
const index = this.list.indexOf(v)
|
||||
this.list.splice(index, 1, this.temp)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.dialogFormVisible = false
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$notify({
|
||||
title: '成功',
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
const index = this.list.indexOf(row)
|
||||
this.list.splice(index, 1)
|
||||
},
|
||||
handleFetchPv(pv) {
|
||||
fetchPv(pv).then(response => {
|
||||
this.pvData = response.data.pvData
|
||||
this.dialogPvVisible = true
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Excel').then(excel => {
|
||||
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
|
||||
const data = this.formatJson(filterVal, this.list)
|
||||
excel.export_json_to_excel({
|
||||
header: tHeader,
|
||||
data,
|
||||
filename: 'table-list'
|
||||
})
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => {
|
||||
if (j === 'timestamp') {
|
||||
return parseTime(v[j])
|
||||
} else {
|
||||
return v[j]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,152 +0,0 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<!-- Note that row-key is necessary to get a correct row order. -->
|
||||
<el-table v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
|
||||
|
||||
<el-table-column align="center" label="ID" width="65">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="180px" align="center" label="Date">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column min-width="300px" label="Title">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.title }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="110px" align="center" label="Author">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.author }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="100px" label="Importance">
|
||||
<template slot-scope="scope">
|
||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="icon-star"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="Readings" width="95">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.pageviews }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column class-name="status-col" label="Status" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="Drag" width="80">
|
||||
<template slot-scope="{}">
|
||||
<svg-icon class="drag-handler" icon-class="drag"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<!-- $t is vue-i18n global function to translate lang (lang in @/lang) -->
|
||||
<div class="show-d">{{ $t('table.dragTips1') }} : {{ oldList }}</div>
|
||||
<div class="show-d">{{ $t('table.dragTips2') }} : {{ newList }}</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/article'
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
export default {
|
||||
name: 'DragTable',
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 10
|
||||
},
|
||||
sortable: null,
|
||||
oldList: [],
|
||||
newList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.list = response.data.items
|
||||
this.total = response.data.total
|
||||
this.listLoading = false
|
||||
this.oldList = this.list.map(v => v.id)
|
||||
this.newList = this.oldList.slice()
|
||||
this.$nextTick(() => {
|
||||
this.setSort()
|
||||
})
|
||||
})
|
||||
},
|
||||
setSort() {
|
||||
const el = document.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
|
||||
this.sortable = Sortable.create(el, {
|
||||
ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
|
||||
setData: function(dataTransfer) {
|
||||
dataTransfer.setData('Text', '')
|
||||
// to avoid Firefox bug
|
||||
// Detail see : https://github.com/RubaXa/Sortable/issues/1012
|
||||
},
|
||||
onEnd: evt => {
|
||||
const targetRow = this.list.splice(evt.oldIndex, 1)[0]
|
||||
this.list.splice(evt.newIndex, 0, targetRow)
|
||||
|
||||
// for show the changes, you can delete in you code
|
||||
const tempIndex = this.newList.splice(evt.oldIndex, 1)[0]
|
||||
this.newList.splice(evt.newIndex, 0, tempIndex)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.sortable-ghost{
|
||||
opacity: .8;
|
||||
color: #fff!important;
|
||||
background: #42b983!important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.icon-star{
|
||||
margin-right:2px;
|
||||
}
|
||||
.drag-handler{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.show-d{
|
||||
margin-top: 15px;
|
||||
}
|
||||
</style>
|
|
@ -1,127 +0,0 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
|
||||
<el-table-column align="center" label="ID" width="80">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="180px" align="center" label="Date">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="120px" align="center" label="Author">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.author }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="100px" label="Importance">
|
||||
<template slot-scope="scope">
|
||||
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column class-name="status-col" label="Status" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column min-width="300px" label="Title">
|
||||
<template slot-scope="scope">
|
||||
<template v-if="scope.row.edit">
|
||||
<el-input v-model="scope.row.title" class="edit-input" size="small"/>
|
||||
<el-button class="cancel-btn" size="small" icon="el-icon-refresh" type="warning" @click="cancelEdit(scope.row)">cancel</el-button>
|
||||
</template>
|
||||
<span v-else>{{ scope.row.title }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="Actions" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="scope.row.edit" type="success" size="small" icon="el-icon-circle-check-outline" @click="confirmEdit(scope.row)">Ok</el-button>
|
||||
<el-button v-else type="primary" size="small" icon="el-icon-edit" @click="scope.row.edit=!scope.row.edit">Edit</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/article'
|
||||
|
||||
export default {
|
||||
name: 'InlineEditTable',
|
||||
filters: {
|
||||
statusFilter(status) {
|
||||
const statusMap = {
|
||||
published: 'success',
|
||||
draft: 'info',
|
||||
deleted: 'danger'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.listLoading = true
|
||||
fetchList(this.listQuery).then(response => {
|
||||
const items = response.data.items
|
||||
this.list = items.map(v => {
|
||||
this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html
|
||||
v.originalTitle = v.title // will be used when user click the cancel botton
|
||||
return v
|
||||
})
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
cancelEdit(row) {
|
||||
row.title = row.originalTitle
|
||||
row.edit = false
|
||||
this.$message({
|
||||
message: 'The title has been restored to the original value',
|
||||
type: 'warning'
|
||||
})
|
||||
},
|
||||
confirmEdit(row) {
|
||||
row.edit = false
|
||||
row.originalTitle = row.title
|
||||
this.$message({
|
||||
message: 'The title has been edited',
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.edit-input {
|
||||
padding-right: 100px;
|
||||
}
|
||||
.cancel-btn {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 10px;
|
||||
}
|
||||
</style>
|
|
@ -1,77 +0,0 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<!-- $t is vue-i18n global function to translate lang -->
|
||||
<el-input :placeholder="$t('zip.placeholder')" v-model="filename" style="width:300px;" prefix-icon="el-icon-document"/>
|
||||
<el-button :loading="downloadLoading" style="margin-bottom:20px;" type="primary" icon="document" @click="handleDownload">{{ $t('zip.export') }} zip</el-button>
|
||||
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
|
||||
<el-table-column align="center" label="ID" width="95">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.$index }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Title">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.title }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Author" width="95" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag>{{ scope.row.author }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Readings" width="115" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.pageviews }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="Date" width="220">
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-time"/>
|
||||
<span>{{ scope.row.display_time }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList } from '@/api/article'
|
||||
|
||||
export default {
|
||||
name: 'ExportZip',
|
||||
data: function() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
downloadLoading: false,
|
||||
filename: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.listLoading = true
|
||||
fetchList().then(response => {
|
||||
this.list = response.data.items
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
handleDownload() {
|
||||
this.downloadLoading = true
|
||||
import('@/vendor/Export2Zip').then(zip => {
|
||||
const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
|
||||
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
|
||||
const list = this.list
|
||||
const data = this.formatJson(filterVal, list)
|
||||
zip.export_txt_to_zip(tHeader, data, this.filename, this.filename)
|
||||
this.downloadLoading = false
|
||||
})
|
||||
},
|
||||
formatJson(filterVal, jsonData) {
|
||||
return jsonData.map(v => filterVal.map(j => v[j]))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in a new issue