Browse Source

task list

master
zhizhi wu 4 years ago
parent
commit
188aae2e8a
  1. 0
      scheduler/src/main/java/com/ccsens/scheduler/bean/dto/QuartzJobDto.java
  2. 4
      scheduler/vue-element-admin-master/.env.development
  3. 6
      scheduler/vue-element-admin-master/src/api/remote-search.js
  4. 65
      scheduler/vue-element-admin-master/src/api/task.js
  5. 2
      scheduler/vue-element-admin-master/src/api/user.js
  6. 2
      scheduler/vue-element-admin-master/src/components/HeaderSearch/index.vue
  7. 2
      scheduler/vue-element-admin-master/src/components/Screenfull/index.vue
  8. 2
      scheduler/vue-element-admin-master/src/components/SizeSelect/index.vue
  9. 2
      scheduler/vue-element-admin-master/src/main.js
  10. 333
      scheduler/vue-element-admin-master/src/router/index.js
  11. 36
      scheduler/vue-element-admin-master/src/router/modules/charts.js
  12. 102
      scheduler/vue-element-admin-master/src/router/modules/components.js
  13. 66
      scheduler/vue-element-admin-master/src/router/modules/nested.js
  14. 41
      scheduler/vue-element-admin-master/src/router/modules/table.js
  15. 1
      scheduler/vue-element-admin-master/src/store/modules/permission.js
  16. 2
      scheduler/vue-element-admin-master/src/utils/request.js
  17. 23
      scheduler/vue-element-admin-master/src/views/charts/keyboard.vue
  18. 23
      scheduler/vue-element-admin-master/src/views/charts/line.vue
  19. 23
      scheduler/vue-element-admin-master/src/views/charts/mix-chart.vue
  20. 49
      scheduler/vue-element-admin-master/src/views/clipboard/index.vue
  21. 61
      scheduler/vue-element-admin-master/src/views/components-demo/avatar-upload.vue
  22. 154
      scheduler/vue-element-admin-master/src/views/components-demo/back-to-top.vue
  23. 218
      scheduler/vue-element-admin-master/src/views/components-demo/count-to.vue
  24. 39
      scheduler/vue-element-admin-master/src/views/components-demo/dnd-list.vue
  25. 61
      scheduler/vue-element-admin-master/src/views/components-demo/drag-dialog.vue
  26. 66
      scheduler/vue-element-admin-master/src/views/components-demo/drag-kanban.vue
  27. 43
      scheduler/vue-element-admin-master/src/views/components-demo/drag-select.vue
  28. 31
      scheduler/vue-element-admin-master/src/views/components-demo/dropzone.vue
  29. 36
      scheduler/vue-element-admin-master/src/views/components-demo/json-editor.vue
  30. 101
      scheduler/vue-element-admin-master/src/views/components-demo/markdown.vue
  31. 169
      scheduler/vue-element-admin-master/src/views/components-demo/mixin.vue
  32. 67
      scheduler/vue-element-admin-master/src/views/components-demo/split-pane.vue
  33. 135
      scheduler/vue-element-admin-master/src/views/components-demo/sticky.vue
  34. 36
      scheduler/vue-element-admin-master/src/views/components-demo/tinymce.vue
  35. 57
      scheduler/vue-element-admin-master/src/views/documentation/index.vue
  36. 289
      scheduler/vue-element-admin-master/src/views/example/components/ArticleDetail.vue
  37. 41
      scheduler/vue-element-admin-master/src/views/example/components/Dropdown/Comment.vue
  38. 46
      scheduler/vue-element-admin-master/src/views/example/components/Dropdown/Platform.vue
  39. 38
      scheduler/vue-element-admin-master/src/views/example/components/Dropdown/SourceUrl.vue
  40. 3
      scheduler/vue-element-admin-master/src/views/example/components/Dropdown/index.js
  41. 13
      scheduler/vue-element-admin-master/src/views/example/components/Warning.vue
  42. 13
      scheduler/vue-element-admin-master/src/views/example/create.vue
  43. 13
      scheduler/vue-element-admin-master/src/views/example/edit.vue
  44. 112
      scheduler/vue-element-admin-master/src/views/example/list.vue
  45. 34
      scheduler/vue-element-admin-master/src/views/excel/components/AutoWidthOption.vue
  46. 39
      scheduler/vue-element-admin-master/src/views/excel/components/BookTypeOption.vue
  47. 27
      scheduler/vue-element-admin-master/src/views/excel/components/FilenameOption.vue
  48. 116
      scheduler/vue-element-admin-master/src/views/excel/export-excel.vue
  49. 101
      scheduler/vue-element-admin-master/src/views/excel/merge-header.vue
  50. 107
      scheduler/vue-element-admin-master/src/views/excel/select-excel.vue
  51. 42
      scheduler/vue-element-admin-master/src/views/excel/upload-excel.vue
  52. 36
      scheduler/vue-element-admin-master/src/views/guide/index.vue
  53. 53
      scheduler/vue-element-admin-master/src/views/guide/steps.js
  54. 3
      scheduler/vue-element-admin-master/src/views/icons/element-icons.js
  55. 101
      scheduler/vue-element-admin-master/src/views/icons/index.vue
  56. 10
      scheduler/vue-element-admin-master/src/views/icons/svg-icons.js
  57. 52
      scheduler/vue-element-admin-master/src/views/login/index.vue
  58. 7
      scheduler/vue-element-admin-master/src/views/nested/menu1/index.vue
  59. 7
      scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-1/index.vue
  60. 7
      scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-2/index.vue
  61. 5
      scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-2/menu1-2-1/index.vue
  62. 5
      scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-2/menu1-2-2/index.vue
  63. 5
      scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-3/index.vue
  64. 5
      scheduler/vue-element-admin-master/src/views/nested/menu2/index.vue
  65. 58
      scheduler/vue-element-admin-master/src/views/pdf/content.js
  66. 201
      scheduler/vue-element-admin-master/src/views/pdf/download.vue
  67. 13
      scheduler/vue-element-admin-master/src/views/pdf/index.vue
  68. 32
      scheduler/vue-element-admin-master/src/views/permission/components/SwitchRoles.vue
  69. 111
      scheduler/vue-element-admin-master/src/views/permission/directive.vue
  70. 19
      scheduler/vue-element-admin-master/src/views/permission/page.vue
  71. 271
      scheduler/vue-element-admin-master/src/views/permission/role.vue
  72. 38
      scheduler/vue-element-admin-master/src/views/profile/components/Account.vue
  73. 185
      scheduler/vue-element-admin-master/src/views/profile/components/Activity.vue
  74. 43
      scheduler/vue-element-admin-master/src/views/profile/components/Timeline.vue
  75. 134
      scheduler/vue-element-admin-master/src/views/profile/components/UserCard.vue
  76. 68
      scheduler/vue-element-admin-master/src/views/profile/index.vue
  77. 5
      scheduler/vue-element-admin-master/src/views/project/index.vue
  78. 41
      scheduler/vue-element-admin-master/src/views/qiniu/upload.vue
  79. 12
      scheduler/vue-element-admin-master/src/views/redirect/index.vue
  80. 103
      scheduler/vue-element-admin-master/src/views/tab/components/TabPane.vue
  81. 57
      scheduler/vue-element-admin-master/src/views/tab/index.vue
  82. 379
      scheduler/vue-element-admin-master/src/views/table/complex-table.vue
  83. 153
      scheduler/vue-element-admin-master/src/views/table/drag-table.vue
  84. 62
      scheduler/vue-element-admin-master/src/views/table/dynamic-table/components/FixedThead.vue
  85. 50
      scheduler/vue-element-admin-master/src/views/table/dynamic-table/components/UnfixedThead.vue
  86. 24
      scheduler/vue-element-admin-master/src/views/table/dynamic-table/index.vue
  87. 149
      scheduler/vue-element-admin-master/src/views/table/inline-edit-table.vue
  88. 600
      scheduler/vue-element-admin-master/src/views/task/index.vue
  89. 120
      scheduler/vue-element-admin-master/src/views/theme/index.vue
  90. 77
      scheduler/vue-element-admin-master/src/views/zip/index.vue

0
scheduler/src/main/java/com/ccsens/scheduler/bean/dto/QuartzJob.java → scheduler/src/main/java/com/ccsens/scheduler/bean/dto/QuartzJobDto.java

4
scheduler/vue-element-admin-master/.env.development

@ -2,5 +2,7 @@
ENV = 'development'
# base api
VUE_APP_BASE_API = 'https://test.tall.wiki/gateway'
VUE_APP_BASE_API = 'https://test.tall.wiki'
VUE_APP_MOCK_API = '/dev-api'
VUE_APP_TALL_API = 'https://test.tall.wiki/gateway/tall/v1.0'
VUE_APP_SCHEDULER_API = 'https://test.tall.wiki/scheduler'

6
scheduler/vue-element-admin-master/src/api/remote-search.js

@ -1,8 +1,10 @@
import request from '@/utils/request'
const mock = process.env.VUE_APP_MOCK_API
export function searchUser(name) {
return request({
url: '/vue-element-admin/search/user',
url: `${mock}/vue-element-admin/search/user`,
method: 'get',
params: { name }
})
@ -10,7 +12,7 @@ export function searchUser(name) {
export function transactionList(query) {
return request({
url: '/vue-element-admin/transaction/list',
url: `${mock}/vue-element-admin/transaction/list`,
method: 'get',
params: query
})

65
scheduler/vue-element-admin-master/src/api/task.js

@ -1,9 +1,68 @@
import request from '@/utils/request'
const scheduler = process.env.VUE_APP_SCHEDULER_API
export function fetchList(query) {
return request({
url: '/vue-element-admin/article/list',
method: 'get',
params: query
url: `${scheduler}/job/list`,
method: 'post',
data: {
param: query
}
})
}
export function fetchPv(query) {
return request({
url: `${scheduler}/job/get`,
method: 'post',
data: {
param: query
}
})
}
export function createJob(query) {
return request({
url: `${scheduler}/job/add`,
method: 'post',
data: {
param: query
}
})
}
export function updateJob(query) {
return request({
url: `${scheduler}/job/modifyTime`,
method: 'post',
data: {
param: query
}
})
}
export function pauseJob(query) {
return request({
url: `${scheduler}/job/pause`,
method: 'post',
data: {
param: query
}
})
}
export function resumeJob(query) {
return request({
url: `${scheduler}/job/resume`,
method: 'post',
data: {
param: query
}
})
}
export function removeJob(query) {
return request({
url: `${scheduler}/job/remove`,
method: 'post',
data: {
param: query
}
})
}

2
scheduler/vue-element-admin-master/src/api/user.js

@ -1,5 +1,5 @@
import request from '@/utils/request'
const tall = `${process.env.VUE_APP_BASE_API}/tall3/v3.0`
const tall = process.env.VUE_APP_TALL_API
export function login(formData) {
return request({

2
scheduler/vue-element-admin-master/src/components/HeaderSearch/index.vue

@ -1,6 +1,6 @@
<template>
<div :class="{'show':show}" class="header-search">
<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
<!-- <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> -->
<el-select
ref="headerSearchSelect"
v-model="search"

2
scheduler/vue-element-admin-master/src/components/Screenfull/index.vue

@ -1,6 +1,6 @@
<template>
<div>
<svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" />
<!-- <svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" /> -->
</div>
</template>

2
scheduler/vue-element-admin-master/src/components/SizeSelect/index.vue

@ -1,7 +1,7 @@
<template>
<el-dropdown trigger="click" @command="handleSetSize">
<div>
<svg-icon class-name="size-icon" icon-class="size" />
<!-- <svg-icon class-name="size-icon" icon-class="size" /> -->
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value">

2
scheduler/vue-element-admin-master/src/main.js

@ -14,7 +14,7 @@ import App from './App'
import store from './store'
import router from './router'
import './icons' // icon
// import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error log

333
scheduler/vue-element-admin-master/src/router/index.js

@ -7,10 +7,10 @@ Vue.use(Router)
import Layout from '@/layout'
/* Router Modules */
import componentsRouter from './modules/components'
import chartsRouter from './modules/charts'
import tableRouter from './modules/table'
import nestedRouter from './modules/nested'
// import componentsRouter from './modules/components'
// import chartsRouter from './modules/charts'
// import tableRouter from './modules/table'
// import nestedRouter from './modules/nested'
/**
* Note: sub-menu only appear when route children.length >= 1
@ -39,17 +39,6 @@ import nestedRouter from './modules/nested'
* all roles can be accessed
*/
export const constantRoutes = [
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect/index')
}
]
},
{
path: '/login',
component: () => import('@/views/login/index'),
@ -73,52 +62,13 @@ export const constantRoutes = [
{
path: '/',
component: Layout,
redirect: '/task',
redirect: '/dashboard',
children: [
{
path: 'index',
component: () => import('@/views/task/index'),
name: 'task',
meta: { title: '调度任务', icon: 'el-icon-alarm-clock', noCache: true }
}
]
},
{
path: '/documentation',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/documentation/index'),
name: 'Documentation',
meta: { title: 'Documentation', icon: 'documentation', affix: true }
}
]
},
{
path: '/guide',
component: Layout,
redirect: '/guide/index',
children: [
{
path: 'index',
component: () => import('@/views/guide/index'),
name: 'Guide',
meta: { title: 'Guide', icon: 'guide', noCache: true }
}
]
},
{
path: '/profile',
component: Layout,
redirect: '/profile/index',
hidden: true,
children: [
{
path: 'index',
component: () => import('@/views/profile/index'),
name: 'Profile',
meta: { title: 'Profile', icon: 'user', noCache: true }
path: 'dashboard',
component: () => import('@/views/dashboard/index'),
name: 'Dashboard',
meta: { title: 'Dashboard', icon: 'el-icon-s-home', affix: true }
}
]
}
@ -130,278 +80,29 @@ export const constantRoutes = [
*/
export const asyncRoutes = [
{
path: '/task',
path: '/project',
component: Layout,
alwaysShow: true, // will always show the root menu
name: '任务',
meta: {
title: 'Permission',
icon: 'lock',
roles: ['admin', 'editor'] // you can set roles in root nav
},
children: [
{
path: 'index',
component: () => import('@/views/task/index'),
name: 'task',
meta: { title: '调度任务', icon: 'el-icon-alarm-clock', noCache: true }
component: () => import('@/views/project/index'),
name: 'Project',
meta: { title: '项目管理', icon: 'el-icon-s-platform', noCache: true }
}
]
},
{
path: '/permission',
component: Layout,
redirect: '/permission/page',
alwaysShow: true, // will always show the root menu
name: 'Permission',
meta: {
title: 'Permission',
icon: 'lock',
roles: ['admin', 'editor'] // you can set roles in root nav
},
children: [
{
path: 'page',
component: () => import('@/views/permission/page'),
name: 'PagePermission',
meta: {
title: 'Page Permission',
roles: ['admin'] // or you can only set roles in sub nav
}
},
{
path: 'directive',
component: () => import('@/views/permission/directive'),
name: 'DirectivePermission',
meta: {
title: 'Directive Permission'
// if do not set roles, means: this page does not require permission
}
},
{
path: 'role',
component: () => import('@/views/permission/role'),
name: 'RolePermission',
meta: {
title: 'Role Permission',
roles: ['admin']
}
}
]
},
{
path: '/icon',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/icons/index'),
name: 'Icons',
meta: { title: 'Icons', icon: 'icon', noCache: true }
}
]
},
/** when your routing map is too long, you can split it into small modules **/
componentsRouter,
chartsRouter,
nestedRouter,
tableRouter,
{
path: '/example',
component: Layout,
redirect: '/example/list',
name: 'Example',
meta: {
title: 'Example',
icon: 'el-icon-s-help'
},
children: [
{
path: 'create',
component: () => import('@/views/example/create'),
name: 'CreateArticle',
meta: { title: 'Create Article', icon: 'edit' }
},
{
path: 'edit/:id(\\d+)',
component: () => import('@/views/example/edit'),
name: 'EditArticle',
meta: { title: 'Edit Article', noCache: true, activeMenu: '/example/list' },
hidden: true
},
{
path: 'list',
component: () => import('@/views/example/list'),
name: 'ArticleList',
meta: { title: 'Article List', icon: 'list' }
}
]
},
{
path: '/tab',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/tab/index'),
name: 'Tab',
meta: { title: 'Tab', icon: 'tab' }
}
]
},
{
path: '/error',
component: Layout,
redirect: 'noRedirect',
name: 'ErrorPages',
meta: {
title: 'Error Pages',
icon: '404'
},
children: [
{
path: '401',
component: () => import('@/views/error-page/401'),
name: 'Page401',
meta: { title: '401', noCache: true }
},
{
path: '404',
component: () => import('@/views/error-page/404'),
name: 'Page404',
meta: { title: '404', noCache: true }
}
]
},
{
path: '/error-log',
component: Layout,
children: [
{
path: 'log',
component: () => import('@/views/error-log/index'),
name: 'ErrorLog',
meta: { title: 'Error Log', icon: 'bug' }
}
]
},
{
path: '/excel',
component: Layout,
redirect: '/excel/export-excel',
name: 'Excel',
meta: {
title: 'Excel',
icon: 'excel'
},
children: [
{
path: 'export-excel',
component: () => import('@/views/excel/export-excel'),
name: 'ExportExcel',
meta: { title: 'Export Excel' }
},
{
path: 'export-selected-excel',
component: () => import('@/views/excel/select-excel'),
name: 'SelectExcel',
meta: { title: 'Export Selected' }
},
{
path: 'export-merge-header',
component: () => import('@/views/excel/merge-header'),
name: 'MergeHeader',
meta: { title: 'Merge Header' }
},
{
path: 'upload-excel',
component: () => import('@/views/excel/upload-excel'),
name: 'UploadExcel',
meta: { title: 'Upload Excel' }
}
]
},
{
path: '/zip',
component: Layout,
redirect: '/zip/download',
alwaysShow: true,
name: 'Zip',
meta: { title: 'Zip', icon: 'zip' },
children: [
{
path: 'download',
component: () => import('@/views/zip/index'),
name: 'ExportZip',
meta: { title: 'Export Zip' }
}
]
},
{
path: '/pdf',
component: Layout,
redirect: '/pdf/index',
children: [
{
path: 'index',
component: () => import('@/views/pdf/index'),
name: 'PDF',
meta: { title: 'PDF', icon: 'pdf' }
}
]
},
{
path: '/pdf/download',
component: () => import('@/views/pdf/download'),
hidden: true
},
{
path: '/theme',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/theme/index'),
name: 'Theme',
meta: { title: 'Theme', icon: 'theme' }
}
]
},
{
path: '/clipboard',
path: '/task',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/clipboard/index'),
name: 'ClipboardDemo',
meta: { title: 'Clipboard', icon: 'clipboard' }
}
]
},
{
path: 'external-link',
component: Layout,
children: [
{
path: 'https://github.com/PanJiaChen/vue-element-admin',
meta: { title: 'External Link', icon: 'link' }
component: () => import('@/views/task/index'),
name: 'Task',
meta: { title: '调度任务', icon: 'el-icon-alarm-clock', noCache: true }
}
]
},
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]

36
scheduler/vue-element-admin-master/src/router/modules/charts.js

@ -1,36 +0,0 @@
/** When your routing table is too long, you can split it into small modules**/
import Layout from '@/layout'
const chartsRouter = {
path: '/charts',
component: Layout,
redirect: 'noRedirect',
name: 'Charts',
meta: {
title: 'Charts',
icon: 'chart'
},
children: [
{
path: 'keyboard',
component: () => import('@/views/charts/keyboard'),
name: 'KeyboardChart',
meta: { title: 'Keyboard Chart', noCache: true }
},
{
path: 'line',
component: () => import('@/views/charts/line'),
name: 'LineChart',
meta: { title: 'Line Chart', noCache: true }
},
{
path: 'mix-chart',
component: () => import('@/views/charts/mix-chart'),
name: 'MixChart',
meta: { title: 'Mix Chart', noCache: true }
}
]
}
export default chartsRouter

102
scheduler/vue-element-admin-master/src/router/modules/components.js

@ -1,102 +0,0 @@
/** When your routing table is too long, you can split it into small modules **/
import Layout from '@/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/json-editor'),
name: 'JsonEditorDemo',
meta: { title: 'JSON Editor' }
},
{
path: 'split-pane',
component: () => import('@/views/components-demo/split-pane'),
name: 'SplitpaneDemo',
meta: { title: 'SplitPane' }
},
{
path: 'avatar-upload',
component: () => import('@/views/components-demo/avatar-upload'),
name: 'AvatarUploadDemo',
meta: { title: 'Upload' }
},
{
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/count-to'),
name: 'CountToDemo',
meta: { title: 'Count To' }
},
{
path: 'mixin',
component: () => import('@/views/components-demo/mixin'),
name: 'ComponentMixinDemo',
meta: { title: 'Component Mixin' }
},
{
path: 'back-to-top',
component: () => import('@/views/components-demo/back-to-top'),
name: 'BackToTopDemo',
meta: { title: 'Back To Top' }
},
{
path: 'drag-dialog',
component: () => import('@/views/components-demo/drag-dialog'),
name: 'DragDialogDemo',
meta: { title: 'Drag Dialog' }
},
{
path: 'drag-select',
component: () => import('@/views/components-demo/drag-select'),
name: 'DragSelectDemo',
meta: { title: 'Drag Select' }
},
{
path: 'dnd-list',
component: () => import('@/views/components-demo/dnd-list'),
name: 'DndListDemo',
meta: { title: 'Dnd List' }
},
{
path: 'drag-kanban',
component: () => import('@/views/components-demo/drag-kanban'),
name: 'DragKanbanDemo',
meta: { title: 'Drag Kanban' }
}
]
}
export default componentsRouter

66
scheduler/vue-element-admin-master/src/router/modules/nested.js

@ -1,66 +0,0 @@
/** When your routing table is too long, you can split it into small modules **/
import Layout from '@/layout'
const nestedRouter = {
path: '/nested',
component: Layout,
redirect: '/nested/menu1/menu1-1',
name: 'Nested',
meta: {
title: 'Nested Routes',
icon: 'nested'
},
children: [
{
path: 'menu1',
component: () => import('@/views/nested/menu1/index'), // Parent router-view
name: 'Menu1',
meta: { title: 'Menu 1' },
redirect: '/nested/menu1/menu1-1',
children: [
{
path: 'menu1-1',
component: () => import('@/views/nested/menu1/menu1-1'),
name: 'Menu1-1',
meta: { title: 'Menu 1-1' }
},
{
path: 'menu1-2',
component: () => import('@/views/nested/menu1/menu1-2'),
name: 'Menu1-2',
redirect: '/nested/menu1/menu1-2/menu1-2-1',
meta: { title: 'Menu 1-2' },
children: [
{
path: 'menu1-2-1',
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
name: 'Menu1-2-1',
meta: { title: 'Menu 1-2-1' }
},
{
path: 'menu1-2-2',
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
name: 'Menu1-2-2',
meta: { title: 'Menu 1-2-2' }
}
]
},
{
path: 'menu1-3',
component: () => import('@/views/nested/menu1/menu1-3'),
name: 'Menu1-3',
meta: { title: 'Menu 1-3' }
}
]
},
{
path: 'menu2',
name: 'Menu2',
component: () => import('@/views/nested/menu2/index'),
meta: { title: 'Menu 2' }
}
]
}
export default nestedRouter

41
scheduler/vue-element-admin-master/src/router/modules/table.js

@ -1,41 +0,0 @@
/** When your routing table is too long, you can split it into small modules **/
import Layout from '@/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/dynamic-table/index'),
name: 'DynamicTable',
meta: { title: 'Dynamic Table' }
},
{
path: 'drag-table',
component: () => import('@/views/table/drag-table'),
name: 'DragTable',
meta: { title: 'Drag Table' }
},
{
path: 'inline-edit-table',
component: () => import('@/views/table/inline-edit-table'),
name: 'InlineEditTable',
meta: { title: 'Inline Edit' }
},
{
path: 'complex-table',
component: () => import('@/views/table/complex-table'),
name: 'ComplexTable',
meta: { title: 'Complex Table' }
}
]
}
export default tableRouter

1
scheduler/vue-element-admin-master/src/store/modules/permission.js

@ -54,7 +54,6 @@ const actions = {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
console.info('routes:', accessedRoutes)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)

2
scheduler/vue-element-admin-master/src/utils/request.js

@ -19,8 +19,6 @@ service.interceptors.request.use(
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
config.headers['Authorization'] = `Bearer ${getToken()}`
console.info('token:{}', `Bearer ${getToken()}`)
console.info('token2:{}', getToken())
}
config.headers['content-type'] = 'application/json;charset=utf-8'
return config

23
scheduler/vue-element-admin-master/src/views/charts/keyboard.vue

@ -1,23 +0,0 @@
<template>
<div class="chart-container">
<chart height="100%" width="100%" />
</div>
</template>
<script>
import Chart from '@/components/Charts/Keyboard'
export default {
name: 'KeyboardChart',
components: { Chart }
}
</script>
<style scoped>
.chart-container{
position: relative;
width: 100%;
height: calc(100vh - 84px);
}
</style>

23
scheduler/vue-element-admin-master/src/views/charts/line.vue

@ -1,23 +0,0 @@
<template>
<div class="chart-container">
<chart height="100%" width="100%" />
</div>
</template>
<script>
import Chart from '@/components/Charts/LineMarker'
export default {
name: 'LineChart',
components: { Chart }
}
</script>
<style scoped>
.chart-container{
position: relative;
width: 100%;
height: calc(100vh - 84px);
}
</style>

23
scheduler/vue-element-admin-master/src/views/charts/mix-chart.vue

@ -1,23 +0,0 @@
<template>
<div class="chart-container">
<chart height="100%" width="100%" />
</div>
</template>
<script>
import Chart from '@/components/Charts/MixChart'
export default {
name: 'MixChart',
components: { Chart }
}
</script>
<style scoped>
.chart-container{
position: relative;
width: 100%;
height: calc(100vh - 84px);
}
</style>

49
scheduler/vue-element-admin-master/src/views/clipboard/index.vue

@ -1,49 +0,0 @@
<template>
<div class="app-container">
<el-tabs v-model="activeName">
<el-tab-pane label="use clipboard directly" name="directly">
<el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" />
<el-button type="primary" icon="el-icon-document" @click="handleCopy(inputData,$event)">
copy
</el-button>
</el-tab-pane>
<el-tab-pane label="use clipboard by v-directive" name="v-directive">
<el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;" />
<el-button v-clipboard:copy="inputData" v-clipboard:success="clipboardSuccess" type="primary" icon="el-icon-document">
copy
</el-button>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import clip from '@/utils/clipboard' // use clipboard directly
import clipboard from '@/directive/clipboard/index.js' // use clipboard by v-directive
export default {
name: 'ClipboardDemo',
directives: {
clipboard
},
data() {
return {
activeName: 'directly',
inputData: 'https://github.com/PanJiaChen/vue-element-admin'
}
},
methods: {
handleCopy(text, event) {
clip(text, event)
},
clipboardSuccess() {
this.$message({
message: 'Copy successfully',
type: 'success',
duration: 1500
})
}
}
}
</script>

61
scheduler/vue-element-admin-master/src/views/components-demo/avatar-upload.vue

@ -1,61 +0,0 @@
<template>
<div class="components-container">
<aside>This is based on
<a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>.
Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.
</aside>
<pan-thumb :image="image" />
<el-button type="primary" icon="el-icon-upload" style="position: absolute;bottom: 15px;margin-left: 40px;" @click="imagecropperShow=true">
Change Avatar
</el-button>
<image-cropper
v-show="imagecropperShow"
:key="imagecropperKey"
:width="300"
:height="300"
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() {
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>

154
scheduler/vue-element-admin-master/src/views/components-demo/back-to-top.vue

@ -1,154 +0,0 @@
<template>
<div class="components-container">
<aside>
When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner
</aside>
<aside>
You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally
</aside>
<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>
<!-- you can add element-ui's 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() {
return {
// customizable button style, show/hide critical point, return position
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>

218
scheduler/vue-element-admin-master/src/views/components-demo/count-to.vue

@ -1,218 +0,0 @@
<template>
<div class="components-container">
<aside>
<a href="https://github.com/PanJiaChen/vue-countTo" target="_blank">countTo-component</a>
</aside>
<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">
Start
</div>
<div class="pause-resume-btn example-btn" @click="pauseResume">
pause/resume
</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>
<aside>&lt;count-to :start-val=&#x27;{{ _startVal }}&#x27; :end-val=&#x27;{{ _endVal }}&#x27; :duration=&#x27;{{ _duration }}&#x27;
:decimals=&#x27;{{ _decimals }}&#x27; :separator=&#x27;{{ _separator }}&#x27; :prefix=&#x27;{{ _prefix }}&#x27; :suffix=&#x27;{{ _suffix }}&#x27;
:autoplay=false&gt;</aside>
</div>
</template>
<script>
import countTo from 'vue-count-to'
export default {
name: 'CountToDemo',
components: { countTo },
data() {
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>

39
scheduler/vue-element-admin-master/src/views/components-demo/dnd-list.vue

@ -1,39 +0,0 @@
<template>
<div class="components-container">
<aside>drag-list base on
<a href="https://github.com/SortableJS/Vue.Draggable" target="_blank">Vue.Draggable</a>
</aside>
<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() {
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>

61
scheduler/vue-element-admin-master/src/views/components-demo/drag-dialog.vue

@ -1,61 +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-drag-dialog' // base on element-ui
export default {
name: 'DragDialogDemo',
directives: { elDragDialog },
data() {
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>

66
scheduler/vue-element-admin-master/src/views/components-demo/drag-kanban.vue

@ -1,66 +0,0 @@
<template>
<div class="components-container board">
<Kanban :key="1" :list="list1" :group="group" class="kanban todo" header-text="Todo" />
<Kanban :key="2" :list="list2" :group="group" class="kanban working" header-text="Working" />
<Kanban :key="3" :list="list3" :group="group" class="kanban done" header-text="Done" />
</div>
</template>
<script>
import Kanban from '@/components/Kanban'
export default {
name: 'DragKanbanDemo',
components: {
Kanban
},
data() {
return {
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>

43
scheduler/vue-element-admin-master/src/views/components-demo/drag-select.vue

@ -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" :key="item.value" :label="item.label" :value="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() {
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>

31
scheduler/vue-element-admin-master/src/views/components-demo/dropzone.vue

@ -1,31 +0,0 @@
<template>
<div class="components-container">
<aside>
Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>.
Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.
</aside>
<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>

36
scheduler/vue-element-admin-master/src/views/components-demo/json-editor.vue

@ -1,36 +0,0 @@
<template>
<div class="components-container">
<aside>Json-Editor is base on <a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirrorr</a>. Lint
base on <a
href="https://github.com/codemirror/CodeMirror/blob/master/addon/lint/json-lint.js"
target="_blank"
>json-lint</a>.</aside>
<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() {
return {
value: JSON.parse(jsonData)
}
}
}
</script>
<style scoped>
.editor-container{
position: relative;
height: 100%;
}
</style>

101
scheduler/vue-element-admin-master/src/views/components-demo/markdown.vue

@ -1,101 +0,0 @@
<template>
<div class="components-container">
<aside>Markdown is based on
<a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> simply wrapped with Vue.
<a
target="_blank"
href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html"
>
Documentation </a>
</aside>
<div class="editor-container">
<el-tag class="tag-title">
Basic:
</el-tag>
<markdown-editor v-model="content1" height="300px" />
</div>
<div class="editor-container">
<el-tag class="tag-title">
Markdown Mode:
</el-tag>
<markdown-editor ref="markdownEditor" v-model="content2" :options="{hideModeSwitch:true,previewStyle:'tab'}" height="200px" />
</div>
<div class="editor-container">
<el-tag class="tag-title">
Customize Toolbar:
</el-tag>
<markdown-editor v-model="content3" :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 ref="markdownEditor" v-model="content4" :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() {
return {
content1: content,
content2: content,
content3: content,
content4: content,
html: '',
languageTypeList: {
'en': 'en_US',
'zh': 'zh_CN',
'es': 'es_ES'
}
}
},
computed: {
language() {
return this.languageTypeList['en']
}
},
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>

169
scheduler/vue-element-admin-master/src/views/components-demo/mixin.vue

@ -1,169 +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="el-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() {
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: 'v4.0 篇', href: 'https://juejin.im/post/5c92ff94f265da6128275a85' },
{ 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>

67
scheduler/vue-element-admin-master/src/views/components-demo/split-pane.vue

@ -1,67 +0,0 @@
<template>
<div class="components-container">
<aside><strong>SplitPane</strong> If you've used
<a href="https://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>
</aside>
<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>

135
scheduler/vue-element-admin-master/src/views/components-demo/sticky.vue

@ -1,135 +0,0 @@
<template>
<div>
<sticky :z-index="10" 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" :key="item.key" :label="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" 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">
<aside>
Sticky header, When the page is scrolled to the preset position will be sticky on the top.
</aside>
<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>
<sticky :sticky-top="200">
<el-button type="primary"> placeholder</el-button>
</sticky>
<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() {
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>

36
scheduler/vue-element-admin-master/src/views/components-demo/tinymce.vue

@ -1,36 +0,0 @@
<template>
<div class="components-container">
<aside>
Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction.
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html">Documentation</a>
</aside>
<div>
<tinymce v-model="content" :height="300" />
</div>
<div class="editor-content" v-html="content" />
</div>
</template>
<script>
import Tinymce from '@/components/Tinymce'
export default {
name: 'TinymceDemo',
components: { Tinymce },
data() {
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>

57
scheduler/vue-element-admin-master/src/views/documentation/index.vue

@ -1,57 +0,0 @@
<template>
<div class="app-container documentation-container">
<a class="document-btn" target="_blank" href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=demo_English_button">Java backend integration</a>
<a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/">Documentation</a>
<a class="document-btn" target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">Github Repository</a>
<a class="document-btn" target="_blank" href="https://panjiachen.gitee.io/vue-element-admin-site/zh/">国内文档</a>
<dropdown-menu class="document-btn" :items="articleList" title="系列文章" />
<a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/">内推招聘</a>
</div>
</template>
<script>
import DropdownMenu from '@/components/Share/DropdownMenu'
export default {
name: 'Documentation',
components: { DropdownMenu },
data() {
return {
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: 'v4.0 篇', href: 'https://juejin.im/post/5c92ff94f265da6128275a85' },
{ title: '自行封装 component', href: 'https://segmentfault.com/a/1190000009090836' },
{ title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' },
{ title: 'webpack4(上)', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' },
{ title: 'webpack4(下)', href: 'https://juejin.im/post/5b5d6d6f6fb9a04fea58aabc' }
]
}
}
}
</script>
<style lang="scss" scoped>
.documentation-container {
margin: 50px;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.document-btn {
flex-shrink: 0;
display: block;
cursor: pointer;
background: black;
color: white;
height: 60px;
padding: 0 16px;
margin: 16px;
line-height: 60px;
font-size: 20px;
text-align: center;
}
}
</style>

289
scheduler/vue-element-admin-master/src/views/example/components/ArticleDetail.vue

@ -1,289 +0,0 @@
<template>
<div class="createPost-container">
<el-form ref="postForm" :model="postForm" :rules="rules" class="form-container">
<sticky :z-index="10" :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">
Publish
</el-button>
<el-button v-loading="loading" type="warning" @click="draftForm">
Draft
</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>
Title
</MDinput>
</el-form-item>
<div class="postInfo-container">
<el-row>
<el-col :span="8">
<el-form-item label-width="60px" label="Author:" class="postInfo-container-item">
<el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable default-first-option remote placeholder="Search user">
<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="120px" label="Publish Time:" class="postInfo-container-item">
<el-date-picker v-model="displayTime" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Select date and time" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="90px" label="Importance:" class="postInfo-container-item">
<el-rate
v-model="postForm.importance"
:max="3"
:colors="['#99A9BF', '#F7BA2A', '#FF9900']"
:low-threshold="1"
:high-threshold="3"
style="display:inline-block"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
<el-form-item style="margin-bottom: 40px;" label-width="70px" label="Summary:">
<el-input v-model="postForm.content_short" :rows="1" type="textarea" class="article-textarea" autosize placeholder="Please enter the content" />
<span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}words</span>
</el-form-item>
<el-form-item prop="content" style="margin-bottom: 30px;">
<Tinymce ref="editor" v-model="postForm.content" :height="400" />
</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 { validURL } from '@/utils/validate'
import { fetchArticle } from '@/api/article'
import { searchUser } from '@/api/remote-search'
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() {
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 (validURL(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
},
displayTime: {
// set and get is useful when the data
// returned by the back end api is different from the front end
// back end return => "2013-06-25 06:59:25"
// front end need timestamp => 1372114765000
get() {
return (+new Date(this.postForm.display_time))
},
set(val) {
this.postForm.display_time = new Date(val)
}
}
},
created() {
if (this.isEdit) {
const id = this.$route.params && this.$route.params.id
this.fetchData(id)
}
// 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()
// set page title
this.setPageTitle()
}).catch(err => {
console.log(err)
})
},
setTagsViewTitle() {
const title = 'Edit Article'
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
this.$store.dispatch('tagsView/updateVisitedView', route)
},
setPageTitle() {
const title = 'Edit Article'
document.title = `${title} - ${this.postForm.id}`
},
submitForm() {
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) {
searchUser(query).then(response => {
if (!response.data.items) return
this.userListOptions = response.data.items.map(v => v.name)
})
}
}
}
</script>
<style 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;
}
}
.article-textarea ::v-deep {
textarea {
padding-right: 40px;
resize: none;
border: none;
border-radius: 0px;
border-bottom: 1px solid #bfcbd9;
}
}
</style>

41
scheduler/vue-element-admin-master/src/views/example/components/Dropdown/Comment.vue

@ -1,41 +0,0 @@
<template>
<el-dropdown :show-timeout="100" trigger="click">
<el-button plain>
{{ !comment_disabled?'Comment: opened':'Comment: closed' }}
<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">
Close comment
</el-radio>
<el-radio :label="false">
Open comment
</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>

46
scheduler/vue-element-admin-master/src/views/example/components/Dropdown/Platform.vue

@ -1,46 +0,0 @@
<template>
<el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click">
<el-button plain>
Platfroms({{ 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" :key="item.key" :label="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() {
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>

38
scheduler/vue-element-admin-master/src/views/example/components/Dropdown/SourceUrl.vue

@ -1,38 +0,0 @@
<template>
<el-dropdown :show-timeout="100" 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:400px">
<el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri">
<el-input v-model="source_uri" placeholder="Please enter the content">
<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>

3
scheduler/vue-element-admin-master/src/views/example/components/Dropdown/index.js

@ -1,3 +0,0 @@
export { default as CommentDropdown } from './Comment'
export { default as PlatformDropdown } from './Platform'
export { default as SourceUrlDropdown } from './SourceUrl'

13
scheduler/vue-element-admin-master/src/views/example/components/Warning.vue

@ -1,13 +0,0 @@
<template>
<aside>
Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support
caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching
effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all
pages directly. See details
<a
href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html"
target="_blank"
>Document</a>
</aside>
</template>

13
scheduler/vue-element-admin-master/src/views/example/create.vue

@ -1,13 +0,0 @@
<template>
<article-detail :is-edit="false" />
</template>
<script>
import ArticleDetail from './components/ArticleDetail'
export default {
name: 'CreateArticle',
components: { ArticleDetail }
}
</script>

13
scheduler/vue-element-admin-master/src/views/example/edit.vue

@ -1,13 +0,0 @@
<template>
<article-detail :is-edit="true" />
</template>
<script>
import ArticleDetail from './components/ArticleDetail'
export default {
name: 'EditForm',
components: { ArticleDetail }
}
</script>

112
scheduler/vue-element-admin-master/src/views/example/list.vue

@ -1,112 +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="{row}">
<el-tag :type="row.status | statusFilter">
{{ row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column min-width="300px" label="Title">
<template slot-scope="{row}">
<router-link :to="'/example/edit/'+row.id" class="link-type">
<span>{{ 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() {
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
})
}
}
}
</script>
<style scoped>
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

34
scheduler/vue-element-admin-master/src/views/excel/components/AutoWidthOption.vue

@ -1,34 +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>

39
scheduler/vue-element-admin-master/src/views/excel/components/BookTypeOption.vue

@ -1,39 +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() {
return {
options: ['xlsx', 'csv', 'txt']
}
},
computed: {
bookType: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
}
}
</script>

27
scheduler/vue-element-admin-master/src/views/excel/components/FilenameOption.vue

@ -1,27 +0,0 @@
<template>
<div style="display:inline-block;">
<label class="radio-label" style="padding-left:0;">Filename: </label>
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:345px;" 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>

116
scheduler/vue-element-admin-master/src/views/excel/export-excel.vue

@ -1,116 +0,0 @@
<template>
<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="el-icon-document" @click="handleDownload">
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="Loading..." 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() {
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>

101
scheduler/vue-element-admin-master/src/views/excel/merge-header.vue

@ -1,101 +0,0 @@
<template>
<div class="app-container">
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload">Export</el-button>
<el-table
ref="multipleTable"
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
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="Main Information" align="center">
<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>
<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'
export default {
name: 'MergeHeader',
data() {
return {
list: null,
listLoading: true,
downloadLoading: false
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
fetchList(this.listQuery).then(response => {
this.list = response.data.items
this.listLoading = false
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const multiHeader = [['Id', 'Main Information', '', '', 'Date']]
const header = ['', 'Title', 'Author', 'Readings', '']
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
const list = this.list
const data = this.formatJson(filterVal, list)
const merges = ['A1:A2', 'B1:D1', 'E1:E2']
excel.export_json_to_excel({
multiHeader,
header,
merges,
data
})
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>

107
scheduler/vue-element-admin-master/src/views/excel/select-excel.vue

@ -1,107 +0,0 @@
<template>
<div class="app-container">
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:350px;" prefix-icon="el-icon-document" />
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="el-icon-document" @click="handleDownload">
Export Selected Items
</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
ref="multipleTable"
v-loading="listLoading"
: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() {
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>

42
scheduler/vue-element-admin-master/src/views/excel/upload-excel.vue

@ -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" :key="item" :prop="item" :label="item" />
</el-table>
</div>
</template>
<script>
import UploadExcelComponent from '@/components/UploadExcel/index.vue'
export default {
name: 'UploadExcel',
components: { UploadExcelComponent },
data() {
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>

36
scheduler/vue-element-admin-master/src/views/guide/index.vue

@ -1,36 +0,0 @@
<template>
<div class="app-container">
<aside>
The guide page is useful for some people who entered the project for the first time. You can briefly introduce the
features of the project. Demo is based on
<a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.</a>
</aside>
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
Show Guide
</el-button>
</div>
</template>
<script>
import Driver from 'driver.js' // import driver.js
import 'driver.js/dist/driver.min.css' // import driver.js css
import steps from './steps'
export default {
name: 'Guide',
data() {
return {
driver: null
}
},
mounted() {
this.driver = new Driver()
},
methods: {
guide() {
this.driver.defineSteps(steps)
this.driver.start()
}
}
}
</script>

53
scheduler/vue-element-admin-master/src/views/guide/steps.js

@ -1,53 +0,0 @@
const steps = [
{
element: '#hamburger-container',
popover: {
title: 'Hamburger',
description: 'Open && Close sidebar',
position: 'bottom'
}
},
{
element: '#breadcrumb-container',
popover: {
title: 'Breadcrumb',
description: 'Indicate the current page location',
position: 'bottom'
}
},
{
element: '#header-search',
popover: {
title: 'Page Search',
description: 'Page search, quick navigation',
position: 'left'
}
},
{
element: '#screenfull',
popover: {
title: 'Screenfull',
description: 'Set the page into fullscreen',
position: 'left'
}
},
{
element: '#size-select',
popover: {
title: 'Switch Size',
description: 'Switch the system size',
position: 'left'
}
},
{
element: '#tags-view-container',
popover: {
title: 'Tags view',
description: 'The history of the page you visited',
position: 'bottom'
},
padding: 0
}
]
export default steps

3
scheduler/vue-element-admin-master/src/views/icons/element-icons.js

@ -1,3 +0,0 @@
const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
export default elementIcons

101
scheduler/vue-element-admin-master/src/views/icons/index.vue

@ -1,101 +0,0 @@
<template>
<div class="icons-container">
<aside>
<a href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/icon.html" target="_blank">Add and use
</a>
</aside>
<el-tabs type="border-card">
<el-tab-pane label="Icons">
<div class="grid">
<div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
<el-tooltip placement="top">
<div slot="content">
{{ generateIconCode(item) }}
</div>
<div class="icon-item">
<svg-icon :icon-class="item" class-name="disabled" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="Element-UI Icons">
<div class="grid">
<div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)">
<el-tooltip placement="top">
<div slot="content">
{{ generateElementIconCode(item) }}
</div>
<div class="icon-item">
<i :class="'el-icon-' + item" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import clipboard from '@/utils/clipboard'
import svgIcons from './svg-icons'
import elementIcons from './element-icons'
export default {
name: 'Icons',
data() {
return {
svgIcons,
elementIcons
}
},
methods: {
generateIconCode(symbol) {
return `<svg-icon icon-class="${symbol}" />`
},
generateElementIconCode(symbol) {
return `<i class="el-icon-${symbol}" />`
},
handleClipboard(text, event) {
clipboard(text, event)
}
}
}
</script>
<style lang="scss" scoped>
.icons-container {
margin: 10px 20px 0;
overflow: hidden;
.grid {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.icon-item {
margin: 20px;
height: 85px;
text-align: center;
width: 100px;
float: left;
font-size: 30px;
color: #24292e;
cursor: pointer;
}
span {
display: block;
font-size: 16px;
margin-top: 10px;
}
.disabled {
pointer-events: none;
}
}
</style>

10
scheduler/vue-element-admin-master/src/views/icons/svg-icons.js

@ -1,10 +0,0 @@
const req = require.context('../../icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()
const re = /\.\/(.*)\.svg/
const svgIcons = requireAll(req).map(i => {
return i.match(re)[1]
})
export default svgIcons

52
scheduler/vue-element-admin-master/src/views/login/index.vue

@ -1,7 +1,6 @@
<template>
<div class="login-container">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" autocomplete="on" class="login-form" label-position="left">
<div class="title-container">
<h3 class="title">Login Form</h3>
</div>
@ -13,15 +12,15 @@
<el-input
ref="username"
v-model="loginForm.identifier"
placeholder="Username"
autocomplete="on"
name="username"
type="text"
placeholder="Username"
tabindex="1"
autocomplete="on"
type="text"
/>
</el-form-item>
<el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
<el-tooltip v-model="capsTooltip" content="Caps lock is On" manual placement="right">
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password" />
@ -29,15 +28,15 @@
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.credential"
:type="passwordType"
placeholder="Password"
autocomplete="on"
name="password"
v-model="loginForm.credential"
placeholder="Password"
tabindex="2"
autocomplete="on"
@keyup.native="checkCapslock"
@blur="capsTooltip = false"
@keyup.enter.native="handleLogin"
@keyup.native="checkCapslock"
/>
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
@ -45,7 +44,7 @@
</el-form-item>
</el-tooltip>
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
<el-button :loading="loading" style="width:100%;margin-bottom:30px;" type="primary" @click.native.prevent="handleLogin">Login</el-button>
</el-form>
</div>
</template>
@ -79,8 +78,12 @@ export default {
credential: '1234567'
},
loginRules: {
identifier: [{ required: true, trigger: 'blur', validator: validateUsername }],
credential: [{ required: true, trigger: 'blur', validator: validatePassword }]
identifier: [
{ required: true, trigger: 'blur', validator: validateUsername }
],
credential: [
{ required: true, trigger: 'blur', validator: validatePassword }
]
},
passwordType: 'password',
capsTooltip: false,
@ -118,7 +121,7 @@ export default {
methods: {
checkCapslock(e) {
const { key } = e
this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
this.capsTooltip = key && key.length === 1 && key >= 'A' && key <= 'Z'
},
showPwd() {
if (this.passwordType === 'password') {
@ -134,13 +137,16 @@ export default {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm)
this.$store
.dispatch('user/login', this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
this.$router.push({
path: this.redirect || '/',
query: this.otherQuery
})
this.loading = false
})
.catch((e) => {
console.info(e)
.catch(e => {
this.loading = false
})
} else {
@ -182,8 +188,8 @@ export default {
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg:#283443;
$light_gray:#fff;
$bg: #283443;
$light_gray: #fff;
$cursor: #fff;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
@ -226,9 +232,9 @@ $cursor: #fff;
</style>
<style lang="scss" scoped>
$bg:#2d3a4b;
$dark_gray:#889aa4;
$light_gray:#eee;
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
min-height: 100%;

7
scheduler/vue-element-admin-master/src/views/nested/menu1/index.vue

@ -1,7 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1">
<router-view />
</el-alert>
</div>
</template>

7
scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-1/index.vue

@ -1,7 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-1" type="success">
<router-view />
</el-alert>
</div>
</template>

7
scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-2/index.vue

@ -1,7 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2" type="success">
<router-view />
</el-alert>
</div>
</template>

5
scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-2/menu1-2-1/index.vue

@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-1" type="warning" />
</div>
</template>

5
scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-2/menu1-2-2/index.vue

@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-2" type="warning" />
</div>
</template>

5
scheduler/vue-element-admin-master/src/views/nested/menu1/menu1-3/index.vue

@ -1,5 +0,0 @@
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-3" type="success" />
</div>
</template>

5
scheduler/vue-element-admin-master/src/views/nested/menu2/index.vue

@ -1,5 +0,0 @@
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 2" />
</div>
</template>

58
scheduler/vue-element-admin-master/src/views/pdf/content.js

@ -1,58 +0,0 @@
const title = 'Plans for the Next Iteration of Vue.js'
const content = `<p>Last week at<a href="https://vuejs.london/summary" rel="nofollow">Vue.js London</a>I gave a brief sneak peek of what’s coming in the next major version of Vue. This post provides an in-depth overview of the plan.</p>
<p><img class=" wscnph" src="https://wpimg.wallstcn.com/b8a1d7be-0b73-41b8-be8c-7c01c93cab66.png" data-wscntype="image" data-wscnh="742" data-wscnw="692" /></p>
<h3>Why a new majorversion?</h3>
<p>Vue 2.0 was released<a href="https://medium.com/the-vue-point/vue-2-0-is-here-ef1f26acf4b8" rel="nofollow">exactly two years ago</a>(how time flies!). During this period, the core has remained backwards compatible with five minor releases. Weve accumulated a number of ideas that would bring improvements, but they were held off because they would result in breaking changes. At the same time, the JavaScript ecosystem and the language itself has been evolving rapidly. There are greatly improved tools that could enhance our workflow, and many new language features that could unlock simpler, more complete, and more efficient solutions to the problems Vue is trying to solve. Whats more exciting is that we are seeing ES2015 support becoming a baseline for all major evergreen browsers. Vue 3.0 aims to leverage these new language features to make Vue core smaller, faster, and more powerful.</p>
<p>Vue 3.0 is currently in prototyping phase, and we have already implemented a runtime close to feature-parity with 2.x.<strong>Many of the items listed below are either already implemented, or confirmed to be feasible. Ones that are not yet implemented or still in exploration phase are marked with a *.</strong></p>
<h3>The Details</h3>
<h4>High-Level APIChanges</h4>
<blockquote>TL;DR: Everything except render function API and scoped-slots syntax will either remain the same or can be made 2.x compatible via a compatibility build.</blockquote>
<p>Since its a new major, there is going to be some breaking changes. However, we take backwards compatibility seriously, so we want to start communicating these changes as soon as possible. Heres the currently planned public API changes:</p>
<ul><li>Template syntax will remain 99% the same. There may be small tweaks in scoped slots syntax, but other than that we have no plans to change anything else for templates.</li><li>3.0 will support class-based components natively, with the aim to provide an API that is pleasant to use in native ES2015 without requiring any transpilation or stage-x features. Most current options will have a reasonable mapping in the class-based API. Stage-x features such as class fields and decorators can still be used optionally to enhance the authoring experience. In addition, the API is designed with TypeScript type inference in mind. The 3.x codebase will itself be written in TypeScript, and providing improved TypeScript support. (That said, usage of TypeScript in an application is still entirely optional.)</li><li>The 2.x object-based component format will still be supported by internally transforming the object to a corresponding class.</li><li>Mixins will still be supported.*</li><li>Top level APIs will likely receive an overhaul to avoid globally mutating the Vue runtime when installing plugins. Instead, plugins will be applied and scoped to a component tree. This will make it easier to test components that rely on specific plugins, and also make it possible to mount multiple Vue applications on the same page with different plugins, but using the same Vue runtime.*</li><li>Functional components can finally be plain functions however, async components will now need to be explicitly created via a helper function.</li><li>The part that will receive the most changes is the Virtual DOM format used in render functions. We are currently collecting feedback from major library authors and will be sharing more details as we are more confident of the changes, but as long as you dont heavily rely on hand-written (non-JSX) render functions in your app, upgrading should be a reasonably straightforward process.</li></ul>
<h4>Source Code Architecture</h4>
<blockquote>TL;DR: better decoupled internal modules, TypeScript, and a codebase that is easier to contribute to.</blockquote>
<p>We are re-writing 3.0 from the ground up for a cleaner and more maintainable architecture, in particular trying to make it easier to contribute to. We are breaking some internal functionalities into individual packages in order to isolate the scope of complexity. For example, the observer module will become its own package, with its own public API and tests. Note this does not affect framework-level API you will not have to manually import individual bits from multiple packages in order to use Vue. Instead, the final Vue package is assembled using these internal packages.</p>
<p>The codebase is also now written in TypeScript. Although this will make proficiency in TypeScript a pre-requisite for contributing to the new codebase, we believe the type information and IDE support will actually make it easier for a new contributor to make meaningful contributions.</p>
<p>Decoupling the observer and scheduler into separate packages also allows us to easily experiment with alternative implementations of these parts. For example, we can implement an IE11 compatible observer implementation with the same API, or an alternative scheduler that leverages<code>requestIdleCallback</code>to yield to the browser during long updates.*</p>
<p><img class=" wscnph" src="https://wpimg.wallstcn.com/4d0b5fb2-d7f9-48fd-8f1b-03362b534dd9.png" data-wscntype="image" data-wscnh="716" data-wscnw="460" /></p>
<h4>Observation Mechanism</h4>
<blockquote>TL;DR: more complete, precise, efficient and debuggable reactivity tracking &amp; API for creating observables.</blockquote>
<p>3.0 will ship with a Proxy-based observer implementation that provides reactivity tracking with full language coverage. This eliminates a number of limitations of Vue 2s current implementation based on<code>Object.defineProperty</code>:</p>
<p>The new observer also features the following:</p>
<p>Easily understand why a component is re-rendering</p>
<p><img class=" wscnph" src="https://wpimg.wallstcn.com/a0c9d811-1ef9-4628-8976-f7c1aaa66da0.png" data-wscntype="image" data-wscnh="540" data-wscnw="789" /></p>
<h4>Other Runtime Improvements</h4>
<blockquote>TL;DR: smaller, faster, tree-shakable features, fragments &amp; portals, custom renderer API.</blockquote>
<h4>Compiler Improvements*</h4>
<blockquote>TL;DR: tree-shaking friendly output, more AOT optimizations, parser with better error info and source map support.</blockquote>
<h4>IE11 Support*</h4>
<blockquote>TL;DR: it will be supported, but in a separate build with the same reactivity limitations of Vue 2.x.</blockquote>
<p>The new codebase currently targets evergreen browsers only and assumes baseline native ES2015 support. But alas, we know a lot of our users still need to support IE11 for the foreseeable future. Most of the ES2015 features used can be transpiled / polyfilled for IE11, with the exception for Proxies. Our plan is to implement an alternative observer with the same API, but using the good old ES5<code>Object.defineProperty</code>API. A separate build of Vue 3.x will be distributed using this observer implementation. However, this build will be subject to the same change detection caveats of Vue 2.x and thus not fully compatible with the modern build of 3.x. We are aware that this imposes some inconvenience for library authors as they will need to be aware of compatibility for two different builds, but we will make sure to provide clear guidelines on this when we reach that stage.</p>
<h3>How Do We GetThere</h3>
<p>First of all, although we are announcing it today, we do not have a definitive timeline yet. What we do know at the moment is the steps we will be taking to get there:</p>
<h4>1. Internal Feedback for the Runtime Prototype</h4>
<p>This is the phase we are in right now. Currently, we already have a working runtime prototype that includes the new observer, Virtual DOM and component implementation. We have invited a group of authors of influential community projects to provide feedback for the internal changes, and would like to make sure they are comfortable with the changes before moving forward. We want to ensure that important libraries in the ecosystem will be ready at the same time when we release 3.0, so that users relying on those projects can upgrade easily.</p>
<h4>2. Public Feedback viaRFCs</h4>
<p>Once we gain a certain level of confidence in the new design, for each breaking change we will be opening a dedicated RFC issue which includes:</p>
<p>We will anticipate public feedback from the wider community to help us consolidate these ideas.</p>
<h4>3. Introduce Compatible Features in 2.x &amp;2.x-next</h4>
<p>We are not forgetting about 2.x! In fact, we plan to use 2.x to progressively accustom users to the new changes. We will be gradually introducing confirmed API changes into 2.x via opt-in adaptors, and 2.x-next will allow users to try out the new Proxy-based observer.</p>
<p>The last minor release in 2.x will become LTS and continue to receive bug and security fixes for 18 months when 3.0 is released.</p>
<h4>4. AlphaPhase</h4>
<p>Next, we will finish up the compiler and server-side rendering parts of 3.0 and start making alpha releases. These will mostly be for stability testing purposes in small greenfield apps.</p>
<h4>5. BetaPhase</h4>
<p>During beta phase, our main goal is updating support libraries and tools like Vue Router, Vuex, Vue CLI, Vue DevTools and make sure they work smoothly with the new core. We will also be working with major library authors from the community to help them get ready for 3.0.</p>
<h4>6. RCPhase</h4>
<p>Once we consider the API and codebase stable, we will enter RC phase with API freeze. During this phase we will also work on a compat build: a build of 3.0 that includes compatibility layers for 2.x API. This build will also ship with a flag you can turn on to emit deprecation warnings for 2.x API usage in your app. The compat build can be used as a guide to upgrade your app to 3.0.</p>
<h4>7. IE11build</h4>
<p>The last task before the final release will be the IE11 compatibility build as mentioned above.</p>
<h4>8. FinalRelease</h4>
<p>In all honesty, we dont know when this will happen yet, but likely in 2019. Again, we care more about shipping something that is solid and stable rather than hitting specific dates. There is a lot of work to be done, but we are excited for whats coming next!</p>`
const data = {
title,
content
}
export default data

201
scheduler/vue-element-admin-master/src/views/pdf/download.vue

@ -1,201 +0,0 @@
<template>
<div v-loading.fullscreen.lock="fullscreenLoading" class="main-article" element-loading-text="Efforts to generate PDF">
<div class="article__heading">
<div class="article__heading__title">
{{ article.title }}
</div>
</div>
<div style="color: #ccc;">
This article is from Evan You on <a target="_blank" href="https://medium.com/the-vue-point/plans-for-the-next-iteration-of-vue-js-777ffea6fabf">medium</a>
</div>
<div ref="content" class="node-article-content" v-html="article.content" />
</div>
</template>
<script>
export default {
data() {
return {
article: '',
fullscreenLoading: true
}
},
mounted() {
this.fetchData()
},
methods: {
fetchData() {
import('./content.js').then(data => {
const { title } = data.default
document.title = title
this.article = data.default
setTimeout(() => {
this.fullscreenLoading = false
this.$nextTick(() => {
window.print()
})
}, 3000)
})
}
}
}
</script>
<style lang="scss">
@mixin clearfix {
&:before {
display: table;
content: '';
clear: both;
}
&:after {
display: table;
content: '';
clear: both;
}
}
.main-article {
padding: 20px;
margin: 0 auto;
display: block;
width: 740px;
background: #fff;
}
.article__heading {
position: relative;
padding: 0 0 20px;
overflow: hidden;
}
.article__heading__title {
display: block;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
word-wrap: break-word;
overflow-wrap: break-word;
font-size: 32px;
line-height: 48px;
font-weight: 600;
color: #333;
overflow: hidden;
}
.node-article-content {
margin: 20px 0 0;
@include clearfix;
font-size: 16px;
color: #333;
letter-spacing: 0.5px;
line-height: 28px;
margin-bottom: 30px;
font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif;
&> :last-child {
margin-bottom: 0;
}
b,
strong {
font-weight: inherit;
font-weight: bolder;
}
img {
max-width: 100%;
display: block;
margin: 0 auto;
}
p {
font-weight: 400;
font-style: normal;
font-size: 21px;
line-height: 1.58;
letter-spacing: -.003em;
}
ul {
margin-bottom: 30px;
}
li {
--x-height-multiplier: 0.375;
--baseline-multiplier: 0.17;
letter-spacing: .01rem;
font-weight: 400;
font-style: normal;
font-size: 21px;
line-height: 1.58;
letter-spacing: -.003em;
margin-left: 30px;
margin-bottom: 14px;
}
a {
text-decoration: none;
background-repeat: repeat-x;
background-image: linear-gradient(to right, rgba(0, 0, 0, .84) 100%, rgba(0, 0, 0, 0) 0);
background-size: 1px 1px;
background-position: 0 calc(1em + 1px);
padding: 0 6px;
}
code {
background: rgba(0, 0, 0, .05);
padding: 3px 4px;
margin: 0 2px;
font-size: 16px;
display: inline-block;
}
img {
border: 0;
}
/* 解决 IE6-7 图片缩放锯齿问题 */
img {
-ms-interpolation-mode: bicubic;
}
blockquote {
--x-height-multiplier: 0.375;
--baseline-multiplier: 0.17;
font-family: medium-content-serif-font, Georgia, Cambria, "Times New Roman", Times, serif;
letter-spacing: .01rem;
font-weight: 400;
font-style: italic;
font-size: 21px;
line-height: 1.58;
letter-spacing: -.003em;
border-left: 3px solid rgba(0, 0, 0, .84);
padding-left: 20px;
margin-left: -23px;
padding-bottom: 2px;
}
a {
text-decoration: none;
}
h2,
h3,
h4 {
font-size: 34px;
line-height: 1.15;
letter-spacing: -.015em;
margin: 53px 0 0;
}
h4 {
font-size: 26px;
}
}
</style>

13
scheduler/vue-element-admin-master/src/views/pdf/index.vue

@ -1,13 +0,0 @@
<template>
<div class="app-container">
<aside style="margin-top:15px;">
Here we use window.print() to implement the feature of downloading PDF.
</aside>
<router-link target="_blank" to="/pdf/download">
<el-button type="primary">
Click to download PDF
</el-button>
</router-link>
</div>
</template>

32
scheduler/vue-element-admin-master/src/views/permission/components/SwitchRoles.vue

@ -1,32 +0,0 @@
<template>
<div>
<div style="margin-bottom:15px;">
Your roles: {{ roles }}
</div>
Switch roles:
<el-radio-group v-model="switchRoles">
<el-radio-button label="editor" />
<el-radio-button label="admin" />
</el-radio-group>
</div>
</template>
<script>
export default {
computed: {
roles() {
return this.$store.getters.roles
},
switchRoles: {
get() {
return this.roles[0]
},
set(val) {
this.$store.dispatch('user/changeRoles', val).then(() => {
this.$emit('change')
})
}
}
}
}
</script>

111
scheduler/vue-element-admin-master/src/views/permission/directive.vue

@ -1,111 +0,0 @@
<template>
<div class="app-container">
<switch-roles @change="handleRolesChange" />
<div :key="key" style="margin-top:30px;">
<div>
<span v-permission="['admin']" class="permission-alert">
Only
<el-tag class="permission-tag" size="small">admin</el-tag> can see this
</span>
<el-tag v-permission="['admin']" class="permission-sourceCode" type="info">
v-permission="['admin']"
</el-tag>
</div>
<div>
<span v-permission="['editor']" class="permission-alert">
Only
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
</span>
<el-tag v-permission="['editor']" class="permission-sourceCode" type="info">
v-permission="['editor']"
</el-tag>
</div>
<div>
<span v-permission="['admin','editor']" class="permission-alert">
Both
<el-tag class="permission-tag" size="small">admin</el-tag> and
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
</span>
<el-tag v-permission="['admin','editor']" class="permission-sourceCode" type="info">
v-permission="['admin','editor']"
</el-tag>
</div>
</div>
<div :key="'checkPermission'+key" style="margin-top:60px;">
<aside>
In some cases, using v-permission will have no effect. For example: Element-UI's Tab component or el-table-column and other scenes that dynamically render dom. You can only do this with v-if.
<br> e.g.
</aside>
<el-tabs type="border-card" style="width:550px;">
<el-tab-pane v-if="checkPermission(['admin'])" label="Admin">
Admin can see this
<el-tag class="permission-sourceCode" type="info">
v-if="checkPermission(['admin'])"
</el-tag>
</el-tab-pane>
<el-tab-pane v-if="checkPermission(['editor'])" label="Editor">
Editor can see this
<el-tag class="permission-sourceCode" type="info">
v-if="checkPermission(['editor'])"
</el-tag>
</el-tab-pane>
<el-tab-pane v-if="checkPermission(['admin','editor'])" label="Admin-OR-Editor">
Both admin or editor can see this
<el-tag class="permission-sourceCode" type="info">
v-if="checkPermission(['admin','editor'])"
</el-tag>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import permission from '@/directive/permission/index.js' //
import checkPermission from '@/utils/permission' //
import SwitchRoles from './components/SwitchRoles'
export default {
name: 'DirectivePermission',
components: { SwitchRoles },
directives: { permission },
data() {
return {
key: 1 //
}
},
methods: {
checkPermission,
handleRolesChange() {
this.key++
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
::v-deep .permission-alert {
width: 320px;
margin-top: 15px;
background-color: #f0f9eb;
color: #67c23a;
padding: 8px 16px;
border-radius: 4px;
display: inline-block;
}
::v-deep .permission-sourceCode {
margin-left: 15px;
}
::v-deep .permission-tag {
background-color: #ecf5ff;
}
}
</style>

19
scheduler/vue-element-admin-master/src/views/permission/page.vue

@ -1,19 +0,0 @@
<template>
<div class="app-container">
<switch-roles @change="handleRolesChange" />
</div>
</template>
<script>
import SwitchRoles from './components/SwitchRoles'
export default {
name: 'PagePermission',
components: { SwitchRoles },
methods: {
handleRolesChange() {
this.$router.push({ path: '/permission/index?' + +new Date() })
}
}
}
</script>

271
scheduler/vue-element-admin-master/src/views/permission/role.vue

@ -1,271 +0,0 @@
<template>
<div class="app-container">
<el-button type="primary" @click="handleAddRole">New Role</el-button>
<el-table :data="rolesList" style="width: 100%;margin-top:30px;" border>
<el-table-column align="center" label="Role Key" width="220">
<template slot-scope="scope">
{{ scope.row.key }}
</template>
</el-table-column>
<el-table-column align="center" label="Role Name" width="220">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column align="header-center" label="Description">
<template slot-scope="scope">
{{ scope.row.description }}
</template>
</el-table-column>
<el-table-column align="center" label="Operations">
<template slot-scope="scope">
<el-button type="primary" size="small" @click="handleEdit(scope)">Edit</el-button>
<el-button type="danger" size="small" @click="handleDelete(scope)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'Edit Role':'New Role'">
<el-form :model="role" label-width="80px" label-position="left">
<el-form-item label="Name">
<el-input v-model="role.name" placeholder="Role Name" />
</el-form-item>
<el-form-item label="Desc">
<el-input
v-model="role.description"
:autosize="{ minRows: 2, maxRows: 4}"
type="textarea"
placeholder="Role Description"
/>
</el-form-item>
<el-form-item label="Menus">
<el-tree
ref="tree"
:check-strictly="checkStrictly"
:data="routesData"
:props="defaultProps"
show-checkbox
node-key="path"
class="permission-tree"
/>
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">Cancel</el-button>
<el-button type="primary" @click="confirmRole">Confirm</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import path from 'path'
import { deepClone } from '@/utils'
import { getRoutes, getRoles, addRole, deleteRole, updateRole } from '@/api/role'
const defaultRole = {
key: '',
name: '',
description: '',
routes: []
}
export default {
data() {
return {
role: Object.assign({}, defaultRole),
routes: [],
rolesList: [],
dialogVisible: false,
dialogType: 'new',
checkStrictly: false,
defaultProps: {
children: 'children',
label: 'title'
}
}
},
computed: {
routesData() {
return this.routes
}
},
created() {
// Mock: get all routes and roles list from server
debugger
this.getRoutes()
this.getRoles()
},
methods: {
async getRoutes() {
const res = await getRoutes()
this.serviceRoutes = res.data
this.routes = this.generateRoutes(res.data)
},
async getRoles() {
const res = await getRoles()
this.rolesList = res.data
},
// Reshape the routes structure so that it looks the same as the sidebar
generateRoutes(routes, basePath = '/') {
const res = []
for (let route of routes) {
// skip some route
if (route.hidden) { continue }
const onlyOneShowingChild = this.onlyOneShowingChild(route.children, route)
if (route.children && onlyOneShowingChild && !route.alwaysShow) {
route = onlyOneShowingChild
}
const data = {
path: path.resolve(basePath, route.path),
title: route.meta && route.meta.title
}
// recursive child routes
if (route.children) {
data.children = this.generateRoutes(route.children, data.path)
}
res.push(data)
}
return res
},
generateArr(routes) {
let data = []
routes.forEach(route => {
data.push(route)
if (route.children) {
const temp = this.generateArr(route.children)
if (temp.length > 0) {
data = [...data, ...temp]
}
}
})
return data
},
handleAddRole() {
this.role = Object.assign({}, defaultRole)
if (this.$refs.tree) {
this.$refs.tree.setCheckedNodes([])
}
this.dialogType = 'new'
this.dialogVisible = true
},
handleEdit(scope) {
this.dialogType = 'edit'
this.dialogVisible = true
this.checkStrictly = true
this.role = deepClone(scope.row)
this.$nextTick(() => {
const routes = this.generateRoutes(this.role.routes)
this.$refs.tree.setCheckedNodes(this.generateArr(routes))
// set checked state of a node not affects its father and child nodes
this.checkStrictly = false
})
},
handleDelete({ $index, row }) {
this.$confirm('Confirm to remove the role?', 'Warning', {
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
type: 'warning'
})
.then(async() => {
await deleteRole(row.key)
this.rolesList.splice($index, 1)
this.$message({
type: 'success',
message: 'Delete succed!'
})
})
.catch(err => { console.error(err) })
},
generateTree(routes, basePath = '/', checkedKeys) {
const res = []
for (const route of routes) {
const routePath = path.resolve(basePath, route.path)
// recursive child routes
if (route.children) {
route.children = this.generateTree(route.children, routePath, checkedKeys)
}
if (checkedKeys.includes(routePath) || (route.children && route.children.length >= 1)) {
res.push(route)
}
}
return res
},
async confirmRole() {
const isEdit = this.dialogType === 'edit'
const checkedKeys = this.$refs.tree.getCheckedKeys()
this.role.routes = this.generateTree(deepClone(this.serviceRoutes), '/', checkedKeys)
if (isEdit) {
await updateRole(this.role.key, this.role)
for (let index = 0; index < this.rolesList.length; index++) {
if (this.rolesList[index].key === this.role.key) {
this.rolesList.splice(index, 1, Object.assign({}, this.role))
break
}
}
} else {
const { data } = await addRole(this.role)
this.role.key = data.key
this.rolesList.push(this.role)
}
const { description, key, name } = this.role
this.dialogVisible = false
this.$notify({
title: 'Success',
dangerouslyUseHTMLString: true,
message: `
<div>Role Key: ${key}</div>
<div>Role Name: ${name}</div>
<div>Description: ${description}</div>
`,
type: 'success'
})
},
// reference: src/view/layout/components/Sidebar/SidebarItem.vue
onlyOneShowingChild(children = [], parent) {
let onlyOneChild = null
const showingChildren = children.filter(item => !item.hidden)
// When there is only one child route, the child route is displayed by default
if (showingChildren.length === 1) {
onlyOneChild = showingChildren[0]
onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path)
return onlyOneChild
}
// Show parent if there are no child route to display
if (showingChildren.length === 0) {
onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return onlyOneChild
}
return false
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
.roles-table {
margin-top: 30px;
}
.permission-tree {
margin-bottom: 30px;
}
}
</style>

38
scheduler/vue-element-admin-master/src/views/profile/components/Account.vue

@ -1,38 +0,0 @@
<template>
<el-form>
<el-form-item label="Name">
<el-input v-model.trim="user.name" />
</el-form-item>
<el-form-item label="Email">
<el-input v-model.trim="user.email" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">Update</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
user: {
type: Object,
default: () => {
return {
name: '',
email: ''
}
}
}
},
methods: {
submit() {
this.$message({
message: 'User information has been updated successfully',
type: 'success',
duration: 5 * 1000
})
}
}
}
</script>

185
scheduler/vue-element-admin-master/src/views/profile/components/Activity.vue

@ -1,185 +0,0 @@
<template>
<div class="user-activity">
<div class="post">
<div class="user-block">
<img class="img-circle" :src="'https://wpimg.wallstcn.com/57ed425a-c71e-4201-9428-68760c0537c4.jpg'+avatarPrefix">
<span class="username text-muted">Iron Man</span>
<span class="description">Shared publicly - 7:30 PM today</span>
</div>
<p>
Lorem ipsum represents a long-held tradition for designers,
typographers and the like. Some people hate it and argue for
its demise, but others ignore the hate as they create awesome
tools to help create filler text for everyone from bacon lovers
to Charlie Sheen fans.
</p>
<ul class="list-inline">
<li>
<span class="link-black text-sm">
<i class="el-icon-share" />
Share
</span>
</li>
<li>
<span class="link-black text-sm">
<svg-icon icon-class="like" />
Like
</span>
</li>
</ul>
</div>
<div class="post">
<div class="user-block">
<img class="img-circle" :src="'https://wpimg.wallstcn.com/9e2a5d0a-bd5b-457f-ac8e-86554616c87b.jpg'+avatarPrefix">
<span class="username text-muted">Captain American</span>
<span class="description">Sent you a message - yesterday</span>
</div>
<p>
Lorem ipsum represents a long-held tradition for designers,
typographers and the like. Some people hate it and argue for
its demise, but others ignore the hate as they create awesome
tools to help create filler text for everyone from bacon lovers
to Charlie Sheen fans.
</p>
<ul class="list-inline">
<li>
<span class="link-black text-sm">
<i class="el-icon-share" />
Share
</span>
</li>
<li>
<span class="link-black text-sm">
<svg-icon icon-class="like" />
Like
</span>
</li>
</ul>
</div>
<div class="post">
<div class="user-block">
<img class="img-circle" :src="'https://wpimg.wallstcn.com/fb57f689-e1ab-443c-af12-8d4066e202e2.jpg'+avatarPrefix">
<span class="username">Spider Man</span>
<span class="description">Posted 4 photos - 2 days ago</span>
</div>
<div class="user-images">
<el-carousel :interval="6000" type="card" height="220px">
<el-carousel-item v-for="item in carouselImages" :key="item">
<img :src="item+carouselPrefix" class="image">
</el-carousel-item>
</el-carousel>
</div>
<ul class="list-inline">
<li><span class="link-black text-sm"><i class="el-icon-share" /> Share</span></li>
<li>
<span class="link-black text-sm">
<svg-icon icon-class="like" /> Like</span>
</li>
</ul>
</div>
</div>
</template>
<script>
const avatarPrefix = '?imageView2/1/w/80/h/80'
const carouselPrefix = '?imageView2/2/h/440'
export default {
data() {
return {
carouselImages: [
'https://wpimg.wallstcn.com/9679ffb0-9e0b-4451-9916-e21992218054.jpg',
'https://wpimg.wallstcn.com/bcce3734-0837-4b9f-9261-351ef384f75a.jpg',
'https://wpimg.wallstcn.com/d1d7b033-d75e-4cd6-ae39-fcd5f1c0a7c5.jpg',
'https://wpimg.wallstcn.com/50530061-851b-4ca5-9dc5-2fead928a939.jpg'
],
avatarPrefix,
carouselPrefix
}
}
}
</script>
<style lang="scss" scoped>
.user-activity {
.user-block {
.username,
.description {
display: block;
margin-left: 50px;
padding: 2px 0;
}
.username{
font-size: 16px;
color: #000;
}
:after {
clear: both;
}
.img-circle {
border-radius: 50%;
width: 40px;
height: 40px;
float: left;
}
span {
font-weight: 500;
font-size: 12px;
}
}
.post {
font-size: 14px;
border-bottom: 1px solid #d2d6de;
margin-bottom: 15px;
padding-bottom: 15px;
color: #666;
.image {
width: 100%;
height: 100%;
}
.user-images {
padding-top: 20px;
}
}
.list-inline {
padding-left: 0;
margin-left: -5px;
list-style: none;
li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
font-size: 13px;
}
.link-black {
&:hover,
&:focus {
color: #999;
}
}
}
}
.box-center {
margin: 0 auto;
display: table;
}
.text-muted {
color: #777;
}
</style>

43
scheduler/vue-element-admin-master/src/views/profile/components/Timeline.vue

@ -1,43 +0,0 @@
<template>
<div class="block">
<el-timeline>
<el-timeline-item v-for="(item,index) of timeline" :key="index" :timestamp="item.timestamp" placement="top">
<el-card>
<h4>{{ item.title }}</h4>
<p>{{ item.content }}</p>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</template>
<script>
export default {
data() {
return {
timeline: [
{
timestamp: '2019/4/20',
title: 'Update Github template',
content: 'PanJiaChen committed 2019/4/20 20:46'
},
{
timestamp: '2019/4/21',
title: 'Update Github template',
content: 'PanJiaChen committed 2019/4/21 20:46'
},
{
timestamp: '2019/4/22',
title: 'Build Template',
content: 'PanJiaChen committed 2019/4/22 20:46'
},
{
timestamp: '2019/4/23',
title: 'Release New Version',
content: 'PanJiaChen committed 2019/4/23 20:46'
}
]
}
}
}
</script>

134
scheduler/vue-element-admin-master/src/views/profile/components/UserCard.vue

@ -1,134 +0,0 @@
<template>
<el-card style="margin-bottom:20px;">
<div slot="header" class="clearfix">
<span>About me</span>
</div>
<div class="user-profile">
<div class="box-center">
<pan-thumb :image="user.avatar" :height="'100px'" :width="'100px'" :hoverable="false">
<div>Hello</div>
{{ user.role }}
</pan-thumb>
</div>
<div class="box-center">
<div class="user-name text-center">{{ user.name }}</div>
<div class="user-role text-center text-muted">{{ user.role | uppercaseFirst }}</div>
</div>
</div>
<div class="user-bio">
<div class="user-education user-bio-section">
<div class="user-bio-section-header"><svg-icon icon-class="education" /><span>Education</span></div>
<div class="user-bio-section-body">
<div class="text-muted">
JS in Computer Science from the University of Technology
</div>
</div>
</div>
<div class="user-skills user-bio-section">
<div class="user-bio-section-header"><svg-icon icon-class="skill" /><span>Skills</span></div>
<div class="user-bio-section-body">
<div class="progress-item">
<span>Vue</span>
<el-progress :percentage="70" />
</div>
<div class="progress-item">
<span>JavaScript</span>
<el-progress :percentage="18" />
</div>
<div class="progress-item">
<span>Css</span>
<el-progress :percentage="12" />
</div>
<div class="progress-item">
<span>ESLint</span>
<el-progress :percentage="100" status="success" />
</div>
</div>
</div>
</div>
</el-card>
</template>
<script>
import PanThumb from '@/components/PanThumb'
export default {
components: { PanThumb },
props: {
user: {
type: Object,
default: () => {
return {
name: '',
email: '',
avatar: '',
role: ''
}
}
}
}
}
</script>
<style lang="scss" scoped>
.box-center {
margin: 0 auto;
display: table;
}
.text-muted {
color: #777;
}
.user-profile {
.user-name {
font-weight: bold;
}
.box-center {
padding-top: 10px;
}
.user-role {
padding-top: 10px;
font-weight: 400;
font-size: 14px;
}
.box-social {
padding-top: 30px;
.el-table {
border-top: 1px solid #dfe6ec;
}
}
.user-follow {
padding-top: 20px;
}
}
.user-bio {
margin-top: 20px;
color: #606266;
span {
padding-left: 4px;
}
.user-bio-section {
font-size: 14px;
padding: 15px 0;
.user-bio-section-header {
border-bottom: 1px solid #dfe6ec;
padding-bottom: 10px;
margin-bottom: 10px;
font-weight: bold;
}
}
}
</style>

68
scheduler/vue-element-admin-master/src/views/profile/index.vue

@ -1,68 +0,0 @@
<template>
<div class="app-container">
<div v-if="user">
<el-row :gutter="20">
<el-col :span="6" :xs="24">
<user-card :user="user" />
</el-col>
<el-col :span="18" :xs="24">
<el-card>
<el-tabs v-model="activeTab">
<el-tab-pane label="Activity" name="activity">
<activity />
</el-tab-pane>
<el-tab-pane label="Timeline" name="timeline">
<timeline />
</el-tab-pane>
<el-tab-pane label="Account" name="account">
<account :user="user" />
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import UserCard from './components/UserCard'
import Activity from './components/Activity'
import Timeline from './components/Timeline'
import Account from './components/Account'
export default {
name: 'Profile',
components: { UserCard, Activity, Timeline, Account },
data() {
return {
user: {},
activeTab: 'activity'
}
},
computed: {
...mapGetters([
'name',
'avatar',
'roles'
])
},
created() {
this.getUser()
},
methods: {
getUser() {
this.user = {
name: this.name,
role: this.roles.join(' | '),
email: 'admin@test.com',
avatar: this.avatar
}
}
}
}
</script>

5
scheduler/vue-element-admin-master/src/views/project/index.vue

@ -0,0 +1,5 @@
<template>
<div class="app-container">
hello world
</div>
</template>

41
scheduler/vue-element-admin-master/src/views/qiniu/upload.vue

@ -1,41 +0,0 @@
<template>
<el-upload :data="dataObj" :multiple="true" :before-upload="beforeUpload" action="https://upload.qbox.me" drag>
<i class="el-icon-upload" />
<div class="el-upload__text">
将文件拖到此处<em>点击上传</em>
</div>
</el-upload>
</template>
<script>
import { getToken } from '@/api/qiniu'
// token Access Key,Secret Key,buckettoken
// sdk https://developer.qiniu.com/sdk#official-sdk
export default {
data() {
return {
dataObj: { token: '', key: '' },
image_uri: [],
fileList: []
}
},
methods: {
beforeUpload() {
const _self = this
return new Promise((resolve, reject) => {
getToken().then(response => {
const key = response.data.qiniu_key
const token = response.data.qiniu_token
_self._data.dataObj.token = token
_self._data.dataObj.key = key
resolve(true)
}).catch(err => {
console.log(err)
reject(false)
})
})
}
}
}
</script>

12
scheduler/vue-element-admin-master/src/views/redirect/index.vue

@ -1,12 +0,0 @@
<script>
export default {
created() {
const { params, query } = this.$route
const { path } = params
this.$router.replace({ path: '/' + path, query })
},
render: function(h) {
return h() // avoid warning message
}
}
</script>

103
scheduler/vue-element-admin-master/src/views/tab/components/TabPane.vue

@ -1,103 +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="{row}">
<span>{{ row.title }}</span>
<el-tag>{{ 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="{row}">
<el-tag :type="row.status | statusFilter">
{{ 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() {
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>

57
scheduler/vue-element-admin-master/src/views/tab/index.vue

@ -1,57 +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" :key="item.key" :label="item.label" :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() {
return {
tabMapOptions: [
{ label: 'China', key: 'CN' },
{ label: 'USA', key: 'US' },
{ label: 'Japan', key: 'JP' },
{ label: 'Eurozone', key: 'EU' }
],
activeName: 'CN',
createdTimes: 0
}
},
watch: {
activeName(val) {
this.$router.push(`${this.$route.path}?tab=${val}`)
}
},
created() {
// init the default selected tab
const tab = this.$route.query.tab
if (tab) {
this.activeName = tab
}
},
methods: {
showCreatedTimes() {
this.createdTimes = this.createdTimes + 1
}
}
}
</script>
<style scoped>
.tab-container {
margin: 30px;
}
</style>

379
scheduler/vue-element-admin-master/src/views/table/complex-table.vue

@ -1,379 +0,0 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-input v-model="listQuery.title" placeholder="Title" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.importance" placeholder="Imp" 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="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">
Search
</el-button>
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
Add
</el-button>
<el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">
Export
</el-button>
<el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
reviewer
</el-checkbox>
</div>
<el-table
:key="tableKey"
v-loading="listLoading"
:data="list"
border
fit
highlight-current-row
style="width: 100%;"
@sort-change="sortChange"
>
<el-table-column label="ID" prop="id" sortable="custom" align="center" width="80" :class-name="getSortClass('id')">
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column label="Date" width="150px" align="center">
<template slot-scope="{row}">
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="Title" min-width="150px">
<template slot-scope="{row}">
<span class="link-type" @click="handleUpdate(row)">{{ row.title }}</span>
<el-tag>{{ row.type | typeFilter }}</el-tag>
</template>
</el-table-column>
<el-table-column label="Author" width="110px" align="center">
<template slot-scope="{row}">
<span>{{ row.author }}</span>
</template>
</el-table-column>
<el-table-column v-if="showReviewer" label="Reviewer" width="110px" align="center">
<template slot-scope="{row}">
<span style="color:red;">{{ row.reviewer }}</span>
</template>
</el-table-column>
<el-table-column label="Imp" width="80px">
<template slot-scope="{row}">
<svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" />
</template>
</el-table-column>
<el-table-column label="Readings" align="center" width="95">
<template slot-scope="{row}">
<span v-if="row.pageviews" class="link-type" @click="handleFetchPv(row.pageviews)">{{ row.pageviews }}</span>
<span v-else>0</span>
</template>
</el-table-column>
<el-table-column label="Status" class-name="status-col" width="100">
<template slot-scope="{row}">
<el-tag :type="row.status | statusFilter">
{{ row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="Actions" align="center" width="230" class-name="small-padding fixed-width">
<template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="handleUpdate(row)">
Edit
</el-button>
<el-button v-if="row.status!='published'" size="mini" type="success" @click="handleModifyStatus(row,'published')">
Publish
</el-button>
<el-button v-if="row.status!='draft'" size="mini" @click="handleModifyStatus(row,'draft')">
Draft
</el-button>
<el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleDelete(row,$index)">
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="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="Date" prop="timestamp">
<el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date" />
</el-form-item>
<el-form-item label="Title" prop="title">
<el-input v-model="temp.title" />
</el-form-item>
<el-form-item label="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="Imp">
<el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;" />
</el-form-item>
<el-form-item label="Remark">
<el-input v-model="temp.remark" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="Please input" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">
Cancel
</el-button>
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
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">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() {
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: '操作Success',
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: 'Success',
message: 'Created Successfully',
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(() => {
const index = this.list.findIndex(v => v.id === this.temp.id)
this.list.splice(index, 1, this.temp)
this.dialogFormVisible = false
this.$notify({
title: 'Success',
message: 'Update Successfully',
type: 'success',
duration: 2000
})
})
}
})
},
handleDelete(row, index) {
this.$notify({
title: 'Success',
message: 'Delete Successfully',
type: 'success',
duration: 2000
})
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)
excel.export_json_to_excel({
header: tHeader,
data,
filename: 'table-list'
})
this.downloadLoading = false
})
},
formatJson(filterVal) {
return this.list.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
return v[j]
}
}))
},
getSortClass: function(key) {
const sort = this.listQuery.sort
return sort === `+${key}` ? 'ascending' : 'descending'
}
}
}
</script>

153
scheduler/vue-element-admin-master/src/views/table/drag-table.vue

@ -1,153 +0,0 @@
<template>
<div class="app-container">
<!-- Note that row-key is necessary to get a correct row order. -->
<el-table ref="dragTable" 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="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="Date">
<template slot-scope="{row}">
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column min-width="300px" label="Title">
<template slot-scope="{row}">
<span>{{ row.title }}</span>
</template>
</el-table-column>
<el-table-column width="110px" align="center" label="Author">
<template slot-scope="{row}">
<span>{{ row.author }}</span>
</template>
</el-table-column>
<el-table-column width="100px" label="Importance">
<template slot-scope="{row}">
<svg-icon v-for="n in + 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="{row}">
<span>{{ row.pageviews }}</span>
</template>
</el-table-column>
<el-table-column class-name="status-col" label="Status" width="110">
<template slot-scope="{row}">
<el-tag :type="row.status | statusFilter">
{{ 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>
<div class="show-d">
<el-tag>The default order :</el-tag> {{ oldList }}
</div>
<div class="show-d">
<el-tag>The after dragging order :</el-tag> {{ 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() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
page: 1,
limit: 10
},
sortable: null,
oldList: [],
newList: []
}
},
created() {
this.getList()
},
methods: {
async getList() {
this.listLoading = true
const { data } = await fetchList(this.listQuery)
this.list = data.items
this.total = 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 = this.$refs.dragTable.$el.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) {
// to avoid Firefox bug
// Detail see : https://github.com/RubaXa/Sortable/issues/1012
dataTransfer.setData('Text', '')
},
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>

62
scheduler/vue-element-admin-master/src/views/table/dynamic-table/components/FixedThead.vue

@ -1,62 +0,0 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-checkbox-group v-model="checkboxVal">
<el-checkbox label="apple">
apple
</el-checkbox>
<el-checkbox label="banana">
banana
</el-checkbox>
<el-checkbox label="orange">
orange
</el-checkbox>
</el-checkbox-group>
</div>
<el-table :key="key" :data="tableData" border fit highlight-current-row style="width: 100%">
<el-table-column prop="name" label="fruitName" width="180" />
<el-table-column v-for="fruit in formThead" :key="fruit" :label="fruit">
<template slot-scope="scope">
{{ scope.row[fruit] }}
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
const defaultFormThead = ['apple', 'banana']
export default {
data() {
return {
tableData: [
{
name: 'fruit-1',
apple: 'apple-10',
banana: 'banana-10',
orange: 'orange-10'
},
{
name: 'fruit-2',
apple: 'apple-20',
banana: 'banana-20',
orange: 'orange-20'
}
],
key: 1, // table key
formTheadOptions: ['apple', 'banana', 'orange'],
checkboxVal: defaultFormThead, // checkboxVal
formThead: defaultFormThead // Default header
}
},
watch: {
checkboxVal(valArr) {
this.formThead = this.formTheadOptions.filter(i => valArr.indexOf(i) >= 0)
this.key = this.key + 1// table In order to ensure the table will be re-rendered each time
}
}
}
</script>

50
scheduler/vue-element-admin-master/src/views/table/dynamic-table/components/UnfixedThead.vue

@ -1,50 +0,0 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-checkbox-group v-model="formThead">
<el-checkbox label="apple">
apple
</el-checkbox>
<el-checkbox label="banana">
banana
</el-checkbox>
<el-checkbox label="orange">
orange
</el-checkbox>
</el-checkbox-group>
</div>
<el-table :data="tableData" border fit highlight-current-row style="width: 100%">
<el-table-column prop="name" label="fruitName" width="180" />
<el-table-column v-for="fruit in formThead" :key="fruit" :label="fruit">
<template slot-scope="scope">
{{ scope.row[fruit] }}
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [
{
name: 'fruit-1',
apple: 'apple-10',
banana: 'banana-10',
orange: 'orange-10'
},
{
name: 'fruit-2',
apple: 'apple-20',
banana: 'banana-20',
orange: 'orange-20'
}
],
formThead: ['apple', 'banana']
}
}
}
</script>

24
scheduler/vue-element-admin-master/src/views/table/dynamic-table/index.vue

@ -1,24 +0,0 @@
<template>
<div class="app-container">
<div style="margin:0 0 5px 20px">
Fixed header, sorted by header order,
</div>
<fixed-thead />
<div style="margin:30px 0 5px 20px">
Not fixed header, sorted by click order
</div>
<unfixed-thead />
</div>
</template>
<script>
import FixedThead from './components/FixedThead'
import UnfixedThead from './components/UnfixedThead'
export default {
name: 'DynamicTable',
components: { FixedThead, UnfixedThead }
}
</script>

149
scheduler/vue-element-admin-master/src/views/table/inline-edit-table.vue

@ -1,149 +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="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="Date">
<template slot-scope="{row}">
<span>{{ 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="{row}">
<span>{{ row.author }}</span>
</template>
</el-table-column>
<el-table-column width="100px" label="Importance">
<template slot-scope="{row}">
<svg-icon v-for="n in + 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="{row}">
<el-tag :type="row.status | statusFilter">
{{ row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column min-width="300px" label="Title">
<template slot-scope="{row}">
<template v-if="row.edit">
<el-input v-model="row.title" class="edit-input" size="small" />
<el-button
class="cancel-btn"
size="small"
icon="el-icon-refresh"
type="warning"
@click="cancelEdit(row)"
>
cancel
</el-button>
</template>
<span v-else>{{ row.title }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="Actions" width="120">
<template slot-scope="{row}">
<el-button
v-if="row.edit"
type="success"
size="small"
icon="el-icon-circle-check-outline"
@click="confirmEdit(row)"
>
Ok
</el-button>
<el-button
v-else
type="primary"
size="small"
icon="el-icon-edit"
@click="row.edit=!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() {
return {
list: null,
listLoading: true,
listQuery: {
page: 1,
limit: 10
}
}
},
created() {
this.getList()
},
methods: {
async getList() {
this.listLoading = true
const { data } = await fetchList(this.listQuery)
const items = 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>

600
scheduler/vue-element-admin-master/src/views/task/index.vue

@ -1,87 +1,235 @@
<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">
<!--搜索条件-->
<div class="filter-container">
<el-input v-model="listQuery.jobName" placeholder="任务名称" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.jobGroupName" placeholder="任务组名称" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.triggerName" placeholder="触发器名称" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.triggerGroupName" placeholder="触发器组名" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
<el-date-picker v-model="listQuery.startTime" type="datetime" placeholder="开始时间" @change="changeTime($event, 0)" />
<el-date-picker v-model="listQuery.endTime" type="datetime" placeholder="结束时间" @change="changeTime($event, 1)" />
<el-select v-model="listQuery.misfirePolicy" placeholder="失火策略" clearable style="width: 130px" class="filter-item">
<el-option v-for="item in misfirePolicyArr" :key="item" :label="item.value" :value="item.key" />
</el-select>
<el-select v-model="listQuery.job" placeholder="执行任务" clearable class="filter-item" style="width: 130px">
<el-option v-for="item in jobArr" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
<el-select v-model="listQuery.notifyWay" placeholder="通知方式" clearable style="width: 140px" class="filter-item" @change="handleFilter">
<el-option v-for="item in notifyWayArr" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
<el-select v-model="listQuery.appId" placeholder="appId" style="width: 140px" class="filter-item" @change="handleFilter">
<el-option v-for="item in appIdArr" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
Search
</el-button>
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
Add
</el-button>
</div>
<!--表格-->
<el-table
:key="index"
v-loading="listLoading"
:data="list"
border
fit
highlight-current-row
style="width: 100%;"
@sort-change="sortChange"
>
<el-table-column fixed label="任务名" align="center" width="150px">
<template slot-scope="{row}">
<span>{{ row.id }}</span>
<span>{{ row.jobName }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="Date">
<el-table-column fixed label="状态" width="100px" align="center">
<template slot-scope="{row}">
<span>{{ row.triggerState }}</span>
</template>
</el-table-column>
<el-table-column fixed label="上一次执行时间" width="150px" align="center">
<template slot-scope="{row}">
<span>{{ row.prevFireTime | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column fixed label="下一次执行时间" width="150px" align="center">
<template slot-scope="{row}">
<span>{{ row.nextFireTime | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="任务组" width="150px" align="center">
<template slot-scope="{row}">
<span>{{ row.jobGroupName }}</span>
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column width="120px" align="center" label="Author">
<el-table-column label="触发器名称" align="center" width="150px">
<template slot-scope="{row}">
<span>{{ row.author }}</span>
<span>{{ row.triggerName }}</span>
</template>
</el-table-column>
<el-table-column width="100px" label="Importance">
<el-table-column label="触发器组名" width="150px" align="center">
<template slot-scope="{row}">
<svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" />
<span>{{ row.triggerGroupName }}</span>
</template>
</el-table-column>
<el-table-column class-name="status-col" label="Status" width="110">
<el-table-column label="cron" width="150px" align="center">
<template slot-scope="{row}">
<el-tag :type="row.status | statusFilter">
{{ row.status }}
</el-tag>
<span>{{ row.cron }}</span>
</template>
</el-table-column>
<el-table-column min-width="300px" label="Title">
<el-table-column label="开始时间" width="150px" align="center">
<template slot-scope="{row}">
<template v-if="row.edit">
<el-input v-model="row.title" class="edit-input" size="small" />
<el-button
class="cancel-btn"
size="small"
icon="el-icon-refresh"
type="warning"
@click="cancelEdit(row)"
>
cancel
</el-button>
</template>
<span v-else>{{ row.title }}</span>
<span>{{ row.startTime | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="Actions" width="120">
<el-table-column label="结束时间" width="150px" align="center">
<template slot-scope="{row}">
<el-button
v-if="row.edit"
type="success"
size="small"
icon="el-icon-circle-check-outline"
@click="confirmEdit(row)"
>
Ok
</el-button>
<el-button
v-else
type="primary"
size="small"
icon="el-icon-edit"
@click="row.edit=!row.edit"
>
<span>{{ row.endTime | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="执行任务" min-width="80">
<template slot-scope="{row}">
<span>{{ getJob(row.job) }}</span>
</template>
</el-table-column>
<el-table-column label="失火策略" min-width="80">
<template slot-scope="{row}">
<span>{{ row.misfirePolicy }}</span>
</template>
</el-table-column>
<el-table-column label="通知方式" align="center">
<template slot-scope="{row}">
<span>{{ getNotifyWay(row.notifyWay) }}</span>
</template>
</el-table-column>
<el-table-column label="通知路径" align="center">
<template slot-scope="{row}">
<span>{{ row.notifyUrl }}</span>
</template>
</el-table-column>
<el-table-column label="通知内容" align="center">
<template slot-scope="{row}">
<span>{{ row.notifyParam }}</span>
</template>
</el-table-column>
<el-table-column fixed="right" label="Actions" align="center" width="230" class-name="small-padding fixed-width">
<template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="handleUpdate(row)">
Edit
</el-button>
<el-popconfirm v-if="row.recStatus === 1" title="确定重启任务吗?" @onConfirm="handleResume(row,$index)">
<el-button slot="reference" size="mini" type="success">resume</el-button>
</el-popconfirm>
<el-popconfirm v-else title="确定停止任务吗?" @onConfirm="handlePause(row,$index)">
<el-button slot="reference" size="mini" type="warning">pause</el-button>
</el-popconfirm>
<el-popconfirm title="删除后任务不可恢复,确定删除吗?" @onConfirm="handleDelete(row,$index)">
<el-button slot="reference" size="mini" type="danger">Delete</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.pageNum" :limit.sync="listQuery.pageSize" @pagination="getList" />
<!--添加/编辑界面-->
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="90px" style="width: 90%; margin-left:30px;">
<el-form-item label="cron" prop="cron">
<el-input v-model="temp.cron" />
</el-form-item>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker v-model="date.start" type="datetime" placeholder="开始时间" style="width: 100%;" @change="changeTime($event, 2)" />
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker v-model="date.end" type="datetime" placeholder="结束时间" style="width: 100%;" @change="changeTime($event, 3)" />
</el-form-item>
<el-form-item label="通知方式" prop="notifyWay">
<el-select v-model="temp.notifyWay" placeholder="通知方式" style="width: 100%;">
<el-option v-for="item in notifyWayArr" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-form-item>
<el-form-item label="通知路径" prop="notifyUrl">
<el-input v-model="temp.notifyUrl" />
</el-form-item>
<el-form-item label="通知内容" prop="content">
<el-input v-model="temp.notifyParam" />
</el-form-item>
<el-form-item label="执行任务" prop="job">
<el-select v-model="temp.job" placeholder="执行任务" style="width: 100%;">
<el-option v-for="item in jobArr" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-form-item>
<el-form-item label="失火策略" prop="misfirePolicy">
<el-select v-model="temp.misfirePolicy" placeholder="失火策略" style="width: 100%;">
<el-option v-for="item in misfirePolicyArr" :key="item" :label="item.value" :value="item.key" />
</el-select>
</el-form-item>
<el-form-item label="appId" prop="appId">
<el-select v-model="temp.appId" placeholder="appId" style="width: 100%;" :disabled="dialogStatus !== 'create'">
<el-option v-for="item in appIdArr" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-form-item>
<el-form-item label="任务名" prop="jobName">
<el-input v-model="temp.jobName" :disabled="dialogStatus !== 'create'" />
</el-form-item>
<el-form-item label="任务组" prop="jobGroupName">
<el-input v-model="temp.jobGroupName" :disabled="dialogStatus !== 'create'" />
</el-form-item>
<el-form-item label="触发器名称" prop="triggerName">
<el-input v-model="temp.triggerName" :disabled="dialogStatus !== 'create'" />
</el-form-item>
<el-form-item label="触发器组名" prop="triggerGroupName">
<el-input v-model="temp.triggerGroupName" :disabled="dialogStatus !== 'create'" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">
Cancel
</el-button>
<el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
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">Confirm</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { fetchList } from '@/api/article'
import { fetchList, fetchPv, createJob, updateJob, pauseJob, resumeJob, removeJob } from '@/api/task'
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: 'InlineEditTable',
name: 'ComplexTable',
components: { Pagination },
directives: { waves },
filters: {
statusFilter(status) {
const statusMap = {
@ -94,56 +242,340 @@ export default {
},
data() {
return {
tableKey: 0,
list: null,
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 10
}
pageNum: 1,
pageSize: 20,
jobName: undefined,
jobGroupName: undefined,
triggerName: undefined,
triggerGroupName: undefined,
startTime: undefined,
endTime: undefined,
content: undefined,
misfirePolicy: undefined,
job: undefined,
autoMove: undefined,
notifyWay: undefined
},
misfirePolicyArr: [
{
key: 'withMisfireHandlingInstructionIgnoreMisfires',
value: 'withMisfireHandlingInstructionIgnoreMisfires'
},
{
key: 'withMisfireHandlingInstructionFireAndProceed',
value: 'withMisfireHandlingInstructionFireAndProceed'
},
{
key: 'withMisfireHandlingInstructionDoNothing',
value: 'withMisfireHandlingInstructionDoNothing'
}
],
jobArr: [
{ key: 0, value: '任务通知' }
],
notifyWayArr: [
{ key: 0, value: 'http' },
{ key: 1, value: 'mq' },
{ key: 2, value: '邮件' },
{ key: 3, value: '短信' }
],
appIdArr: [
{ key: '0', value: '0' }
],
statusOptions: ['published', 'draft', 'deleted'],
showReviewer: false,
temp: {
jobName: undefined,
jobGroupName: undefined,
triggerName: undefined,
triggerGroupName: undefined,
cron: undefined,
startTime: undefined,
endTime: undefined,
misfirePolicy: 'withMisfireHandlingInstructionDoNothing',
job: 0,
autoMove: 1,
notifyWay: 0,
notifyUrl: undefined,
notifyParam: undefined
},
date: {
start: undefined,
end: undefined
},
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: 'Edit',
create: 'Create'
},
dialogPvVisible: false,
pvData: [],
rules: {
cron: [{ required: true, message: 'cron是必填的', trigger: 'blur' }],
// timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
notifyUrl: [{ required: true, message: '通知路径是必填的', trigger: 'blur' }]
},
downloadLoading: false
}
},
created() {
this.getList()
},
methods: {
async getList() {
getJob(key) {
for (const ele of this.jobArr) {
if (ele.key === key) {
return ele.value
}
}
return ''
},
getNotifyWay(key) {
for (const ele of this.notifyWayArr) {
if (ele.key === key) {
return ele.value
}
}
return ''
},
getAppId(key) {
for (const ele in this.appIdArr) {
if (ele.key === key) {
return ele.value
}
}
return ''
},
changeTime(e, num) {
const time = e.getTime()
switch (num) {
case 0:
this.listQuery.startTime = time
break
case 1:
this.listQuery.endTime = time
break
case 2:
this.temp.startTime = time
break
case 3:
this.temp.endTime = time
break
}
},
getList() {
this.listLoading = true
const { data } = await fetchList(this.listQuery)
const items = 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
fetchList(this.listQuery).then(response => {
this.list = response.data.list
this.total = +response.data.total
this.listLoading = false
})
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'
})
handleFilter() {
this.listQuery.pageNum = 1
this.getList()
},
confirmEdit(row) {
row.edit = false
row.originalTitle = row.title
handleModifyStatus(row, status) {
this.$message({
message: 'The title has been edited',
message: '操作Success',
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 = {
jobName: undefined,
jobGroupName: undefined,
triggerName: undefined,
triggerGroupName: undefined,
cron: undefined,
startTime: undefined,
endTime: undefined,
misfirePolicy: 'withMisfireHandlingInstructionDoNothing',
job: 0,
autoMove: 1,
notifyWay: 0,
notifyUrl: undefined,
notifyParam: undefined
}
},
handleCreate() {
this.resetTemp()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
createData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
createJob(this.temp).then(() => {
// this.list.unshift(this.temp)
this.handleFilter()
this.dialogFormVisible = false
this.$notify({
title: 'Success',
message: 'Created Successfully',
type: 'success',
duration: 2000
})
})
}
})
},
handleUpdate(row) {
const { jobName, jobGroupName } = row
fetchPv({ jobName, jobGroupName }).then(response => {
this.temp = Object.assign({}, response.data)
if (this.temp.startTime) {
const start = new Date()
start.setTime(this.temp.startTime)
this.date.start = start
}
if (this.temp.endTime) {
const end = new Date()
end.setTime(this.temp.endTime)
this.date.end = end
}
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
updateJob(tempData).then(() => {
this.dialogFormVisible = false
this.handleFilter()
this.$notify({
title: 'Success',
message: 'Update Successfully',
type: 'success',
duration: 2000
})
})
}
})
},
handleDelete(row, index) {
const { jobName, jobGroupName, triggerName, triggerGroupName } = row
this.listLoading = true
removeJob({ jobName, jobGroupName, triggerName, triggerGroupName }).then(response => {
this.listLoading = false
this.handleFilter()
this.$notify({
title: 'Success',
message: 'Delete Successfully',
type: 'success',
duration: 2000
})
}).catch(e => {
this.listLoading = false
this.$notify({
title: 'Fail',
message: 'Delete FAIL',
type: 'error',
duration: 2000
})
})
},
handleResume(row, index) {
const { jobName, jobGroupName } = row
this.listLoading = true
resumeJob({ jobName, jobGroupName }).then(response => {
this.listLoading = false
this.handleFilter()
this.$notify({
title: 'Success',
message: 'Resume Successfully',
type: 'success',
duration: 2000
})
}).catch(e => {
this.listLoading = false
this.$notify({
title: 'Fail',
message: 'Resume FAIL',
type: 'error',
duration: 2000
})
})
},
handlePause(row, index) {
const { jobName, jobGroupName } = row
this.listLoading = true
pauseJob({ jobName, jobGroupName }).then(response => {
this.listLoading = false
this.handleFilter()
this.$notify({
title: 'Success',
message: 'Pause Successfully',
type: 'success',
duration: 2000
})
}).catch(e => {
this.listLoading = false
this.$notify({
title: 'Fail',
message: 'Pause FAIL',
type: 'error',
duration: 2000
})
})
},
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)
excel.export_json_to_excel({
header: tHeader,
data,
filename: 'table-list'
})
this.downloadLoading = false
})
},
formatJson(filterVal) {
return this.list.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
return v[j]
}
}))
},
getSortClass: function(key) {
const sort = this.listQuery.sort
return sort === `+${key}` ? 'ascending' : 'descending'
}
}
}
</script>
<style scoped>
.edit-input {
padding-right: 100px;
}
.cancel-btn {
position: absolute;
right: 15px;
top: 10px;
}
</style>

120
scheduler/vue-element-admin-master/src/views/theme/index.vue

@ -1,120 +0,0 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header">
<a class="link-type link-title" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/theme.html">
Theme documentation
</a>
</div>
<div class="box-item">
<span class="field-label">Change Theme : </span>
<el-switch v-model="theme" />
<aside style="margin-top:15px;">
Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.
</aside>
</div>
</el-card>
<div class="block">
<el-button type="primary">
Primary
</el-button>
<el-button type="success">
Success
</el-button>
<el-button type="info">
Info
</el-button>
<el-button type="warning">
Warning
</el-button>
<el-button type="danger">
Danger
</el-button>
</div>
<div class="block">
<el-button type="primary" icon="el-icon-edit" />
<el-button type="primary" icon="el-icon-share" />
<el-button type="primary" icon="el-icon-delete" />
<el-button type="primary" icon="el-icon-search">
Search
</el-button>
<el-button type="primary">
Upload
<i class="el-icon-upload el-icon-right" />
</el-button>
</div>
<div class="block">
<el-tag v-for="tag in tags" :key="tag.type" :type="tag.type" class="tag-item">
{{ tag.name }}
</el-tag>
</div>
<div class="block">
<el-radio-group v-model="radio">
<el-radio :label="3">
Option A
</el-radio>
<el-radio :label="6">
Option B
</el-radio>
<el-radio :label="9">
Option C
</el-radio>
</el-radio-group>
</div>
<div class="block">
<el-slider v-model="slideValue" />
</div>
</div>
</template>
<script>
import { toggleClass } from '@/utils'
import '@/assets/custom-theme/index.css' // the theme changed version element-ui css
export default {
name: 'Theme',
data() {
return {
theme: false,
tags: [
{ name: 'Tag One', type: '' },
{ name: 'Tag Two', type: 'info' },
{ name: 'Tag Three', type: 'success' },
{ name: 'Tag Four', type: 'warning' },
{ name: 'Tag Five', type: 'danger' }
],
slideValue: 50,
radio: 3
}
},
watch: {
theme() {
toggleClass(document.body, 'custom-theme')
}
}
}
</script>
<style scoped>
.field-label{
vertical-align: middle;
}
.box-card {
width: 400px;
max-width: 100%;
margin: 20px auto;
}
.block {
padding: 30px 24px;
}
.tag-item {
margin-right: 15px;
}
</style>

77
scheduler/vue-element-admin-master/src/views/zip/index.vue

@ -1,77 +0,0 @@
<template>
<div class="app-container">
<el-input v-model="filename" placeholder="Please enter the file name (default file)" style="width:300px;" prefix-icon="el-icon-document" />
<el-button :loading="downloadLoading" style="margin-bottom:20px;" type="primary" icon="el-icon-document" @click="handleDownload">
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() {
return {
list: null,
listLoading: true,
downloadLoading: false,
filename: ''
}
},
created() {
this.fetchData()
},
methods: {
async fetchData() {
this.listLoading = true
const { data } = await fetchList()
this.list = 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…
Cancel
Save