@lavida/vue-element-admin-template 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +15 -0
- package/template/.editorconfig +14 -0
- package/template/.env.development +5 -0
- package/template/.env.production +6 -0
- package/template/.env.staging +8 -0
- package/template/.eslintignore +4 -0
- package/template/.eslintrc.js +198 -0
- package/template/.travis.yml +5 -0
- package/template/LICENSE +21 -0
- package/template/README.es.md +222 -0
- package/template/README.ja.md +218 -0
- package/template/README.md +222 -0
- package/template/README.zh-CN.md +245 -0
- package/template/babel.config.js +14 -0
- package/template/build/index.js +35 -0
- package/template/jest.config.js +24 -0
- package/template/jsconfig.json +9 -0
- package/template/mock/article.js +116 -0
- package/template/mock/index.js +60 -0
- package/template/mock/mock-server.js +81 -0
- package/template/mock/remote-search.js +51 -0
- package/template/mock/role/index.js +98 -0
- package/template/mock/role/routes.js +530 -0
- package/template/mock/user.js +84 -0
- package/template/mock/utils.js +48 -0
- package/template/package.json +111 -0
- package/template/plop-templates/component/index.hbs +26 -0
- package/template/plop-templates/component/prompt.js +55 -0
- package/template/plop-templates/store/index.hbs +16 -0
- package/template/plop-templates/store/prompt.js +62 -0
- package/template/plop-templates/utils.js +2 -0
- package/template/plop-templates/view/index.hbs +26 -0
- package/template/plop-templates/view/prompt.js +55 -0
- package/template/plopfile.js +9 -0
- package/template/postcss.config.js +5 -0
- package/template/public/favicon.ico +0 -0
- package/template/public/index.html +15 -0
- package/template/src/App.vue +11 -0
- package/template/src/api/article.js +41 -0
- package/template/src/api/qiniu.js +8 -0
- package/template/src/api/remote-search.js +17 -0
- package/template/src/api/role.js +38 -0
- package/template/src/api/user.js +24 -0
- package/template/src/assets/401_images/401.gif +0 -0
- package/template/src/assets/404_images/404.png +0 -0
- package/template/src/assets/404_images/404_cloud.png +0 -0
- package/template/src/assets/custom-theme/fonts/element-icons.ttf +0 -0
- package/template/src/assets/custom-theme/fonts/element-icons.woff +0 -0
- package/template/src/assets/custom-theme/index.css +1 -0
- package/template/src/components/BackToTop/index.vue +111 -0
- package/template/src/components/Breadcrumb/index.vue +82 -0
- package/template/src/components/Charts/Keyboard.vue +155 -0
- package/template/src/components/Charts/LineMarker.vue +227 -0
- package/template/src/components/Charts/MixChart.vue +271 -0
- package/template/src/components/Charts/mixins/resize.js +56 -0
- package/template/src/components/DndList/index.vue +166 -0
- package/template/src/components/DragSelect/index.vue +65 -0
- package/template/src/components/Dropzone/index.vue +297 -0
- package/template/src/components/ErrorLog/index.vue +78 -0
- package/template/src/components/GithubCorner/index.vue +54 -0
- package/template/src/components/Hamburger/index.vue +44 -0
- package/template/src/components/HeaderSearch/index.vue +180 -0
- package/template/src/components/ImageCropper/index.vue +1779 -0
- package/template/src/components/ImageCropper/utils/data2blob.js +19 -0
- package/template/src/components/ImageCropper/utils/effectRipple.js +39 -0
- package/template/src/components/ImageCropper/utils/language.js +232 -0
- package/template/src/components/ImageCropper/utils/mimes.js +7 -0
- package/template/src/components/JsonEditor/index.vue +77 -0
- package/template/src/components/Kanban/index.vue +99 -0
- package/template/src/components/MDinput/index.vue +360 -0
- package/template/src/components/MarkdownEditor/default-options.js +31 -0
- package/template/src/components/MarkdownEditor/index.vue +118 -0
- package/template/src/components/Pagination/index.vue +101 -0
- package/template/src/components/PanThumb/index.vue +142 -0
- package/template/src/components/RightPanel/index.vue +145 -0
- package/template/src/components/Screenfull/index.vue +60 -0
- package/template/src/components/Share/DropdownMenu.vue +103 -0
- package/template/src/components/SizeSelect/index.vue +57 -0
- package/template/src/components/Sticky/index.vue +91 -0
- package/template/src/components/SvgIcon/index.vue +62 -0
- package/template/src/components/TextHoverEffect/Mallki.vue +113 -0
- package/template/src/components/ThemePicker/index.vue +175 -0
- package/template/src/components/Tinymce/components/EditorImage.vue +111 -0
- package/template/src/components/Tinymce/dynamicLoadScript.js +59 -0
- package/template/src/components/Tinymce/index.vue +250 -0
- package/template/src/components/Tinymce/plugins.js +7 -0
- package/template/src/components/Tinymce/toolbar.js +6 -0
- package/template/src/components/Upload/SingleImage.vue +134 -0
- package/template/src/components/Upload/SingleImage2.vue +130 -0
- package/template/src/components/Upload/SingleImage3.vue +157 -0
- package/template/src/components/UploadExcel/index.vue +138 -0
- package/template/src/directive/clipboard/clipboard.js +49 -0
- package/template/src/directive/clipboard/index.js +13 -0
- package/template/src/directive/el-drag-dialog/drag.js +77 -0
- package/template/src/directive/el-drag-dialog/index.js +13 -0
- package/template/src/directive/el-table/adaptive.js +41 -0
- package/template/src/directive/el-table/index.js +13 -0
- package/template/src/directive/permission/index.js +13 -0
- package/template/src/directive/permission/permission.js +31 -0
- package/template/src/directive/sticky.js +91 -0
- package/template/src/directive/waves/index.js +13 -0
- package/template/src/directive/waves/waves.css +26 -0
- package/template/src/directive/waves/waves.js +72 -0
- package/template/src/filters/index.js +68 -0
- package/template/src/icons/index.js +9 -0
- package/template/src/icons/svg/404.svg +1 -0
- package/template/src/icons/svg/bug.svg +1 -0
- package/template/src/icons/svg/chart.svg +1 -0
- package/template/src/icons/svg/clipboard.svg +1 -0
- package/template/src/icons/svg/component.svg +1 -0
- package/template/src/icons/svg/dashboard.svg +1 -0
- package/template/src/icons/svg/documentation.svg +1 -0
- package/template/src/icons/svg/drag.svg +1 -0
- package/template/src/icons/svg/edit.svg +1 -0
- package/template/src/icons/svg/education.svg +1 -0
- package/template/src/icons/svg/email.svg +1 -0
- package/template/src/icons/svg/example.svg +1 -0
- package/template/src/icons/svg/excel.svg +1 -0
- package/template/src/icons/svg/exit-fullscreen.svg +1 -0
- package/template/src/icons/svg/eye-open.svg +1 -0
- package/template/src/icons/svg/eye.svg +1 -0
- package/template/src/icons/svg/form.svg +1 -0
- package/template/src/icons/svg/fullscreen.svg +1 -0
- package/template/src/icons/svg/guide.svg +1 -0
- package/template/src/icons/svg/icon.svg +1 -0
- package/template/src/icons/svg/international.svg +1 -0
- package/template/src/icons/svg/language.svg +1 -0
- package/template/src/icons/svg/link.svg +1 -0
- package/template/src/icons/svg/list.svg +1 -0
- package/template/src/icons/svg/lock.svg +1 -0
- package/template/src/icons/svg/message.svg +1 -0
- package/template/src/icons/svg/money.svg +1 -0
- package/template/src/icons/svg/nested.svg +1 -0
- package/template/src/icons/svg/password.svg +1 -0
- package/template/src/icons/svg/pdf.svg +1 -0
- package/template/src/icons/svg/people.svg +1 -0
- package/template/src/icons/svg/peoples.svg +1 -0
- package/template/src/icons/svg/qq.svg +1 -0
- package/template/src/icons/svg/search.svg +1 -0
- package/template/src/icons/svg/shopping.svg +1 -0
- package/template/src/icons/svg/size.svg +1 -0
- package/template/src/icons/svg/skill.svg +1 -0
- package/template/src/icons/svg/star.svg +1 -0
- package/template/src/icons/svg/tab.svg +1 -0
- package/template/src/icons/svg/table.svg +1 -0
- package/template/src/icons/svg/theme.svg +1 -0
- package/template/src/icons/svg/tree-table.svg +1 -0
- package/template/src/icons/svg/tree.svg +1 -0
- package/template/src/icons/svg/user.svg +1 -0
- package/template/src/icons/svg/wechat.svg +1 -0
- package/template/src/icons/svg/zip.svg +1 -0
- package/template/src/icons/svgo.yml +22 -0
- package/template/src/layout/components/AppMain.vue +57 -0
- package/template/src/layout/components/Navbar.vue +167 -0
- package/template/src/layout/components/Settings/index.vue +108 -0
- package/template/src/layout/components/Sidebar/FixiOSBug.js +26 -0
- package/template/src/layout/components/Sidebar/Item.vue +41 -0
- package/template/src/layout/components/Sidebar/Link.vue +43 -0
- package/template/src/layout/components/Sidebar/Logo.vue +82 -0
- package/template/src/layout/components/Sidebar/SidebarItem.vue +95 -0
- package/template/src/layout/components/Sidebar/index.vue +54 -0
- package/template/src/layout/components/TagsView/ScrollPane.vue +94 -0
- package/template/src/layout/components/TagsView/index.vue +292 -0
- package/template/src/layout/components/index.js +5 -0
- package/template/src/layout/index.vue +102 -0
- package/template/src/layout/mixin/ResizeHandler.js +45 -0
- package/template/src/main.js +53 -0
- package/template/src/permission.js +74 -0
- package/template/src/router/index.js +404 -0
- package/template/src/router/modules/charts.js +36 -0
- package/template/src/router/modules/components.js +102 -0
- package/template/src/router/modules/nested.js +66 -0
- package/template/src/router/modules/table.js +41 -0
- package/template/src/settings.js +35 -0
- package/template/src/store/getters.js +15 -0
- package/template/src/store/index.js +25 -0
- package/template/src/store/modules/app.js +56 -0
- package/template/src/store/modules/errorLog.js +28 -0
- package/template/src/store/modules/permission.js +69 -0
- package/template/src/store/modules/settings.js +35 -0
- package/template/src/store/modules/tagsView.js +160 -0
- package/template/src/store/modules/user.js +131 -0
- package/template/src/styles/btn.scss +99 -0
- package/template/src/styles/element-ui.scss +84 -0
- package/template/src/styles/element-variables.scss +31 -0
- package/template/src/styles/index.scss +191 -0
- package/template/src/styles/mixin.scss +66 -0
- package/template/src/styles/sidebar.scss +226 -0
- package/template/src/styles/transition.scss +48 -0
- package/template/src/styles/variables.scss +35 -0
- package/template/src/utils/auth.js +15 -0
- package/template/src/utils/clipboard.js +32 -0
- package/template/src/utils/error-log.js +35 -0
- package/template/src/utils/get-page-title.js +10 -0
- package/template/src/utils/index.js +357 -0
- package/template/src/utils/open-window.js +25 -0
- package/template/src/utils/permission.js +25 -0
- package/template/src/utils/request.js +85 -0
- package/template/src/utils/scroll-to.js +58 -0
- package/template/src/utils/validate.js +87 -0
- package/template/src/vendor/Export2Excel.js +220 -0
- package/template/src/vendor/Export2Zip.js +24 -0
- package/template/src/views/charts/keyboard.vue +23 -0
- package/template/src/views/charts/line.vue +23 -0
- package/template/src/views/charts/mix-chart.vue +23 -0
- package/template/src/views/clipboard/index.vue +49 -0
- package/template/src/views/components-demo/avatar-upload.vue +61 -0
- package/template/src/views/components-demo/back-to-top.vue +154 -0
- package/template/src/views/components-demo/count-to.vue +218 -0
- package/template/src/views/components-demo/dnd-list.vue +39 -0
- package/template/src/views/components-demo/drag-dialog.vue +61 -0
- package/template/src/views/components-demo/drag-kanban.vue +66 -0
- package/template/src/views/components-demo/drag-select.vue +43 -0
- package/template/src/views/components-demo/dropzone.vue +31 -0
- package/template/src/views/components-demo/json-editor.vue +36 -0
- package/template/src/views/components-demo/markdown.vue +101 -0
- package/template/src/views/components-demo/mixin.vue +169 -0
- package/template/src/views/components-demo/split-pane.vue +67 -0
- package/template/src/views/components-demo/sticky.vue +135 -0
- package/template/src/views/components-demo/tinymce.vue +36 -0
- package/template/src/views/dashboard/admin/components/BarChart.vue +102 -0
- package/template/src/views/dashboard/admin/components/BoxCard.vue +118 -0
- package/template/src/views/dashboard/admin/components/LineChart.vue +135 -0
- package/template/src/views/dashboard/admin/components/PanelGroup.vue +181 -0
- package/template/src/views/dashboard/admin/components/PieChart.vue +79 -0
- package/template/src/views/dashboard/admin/components/RaddarChart.vue +116 -0
- package/template/src/views/dashboard/admin/components/TodoList/Todo.vue +81 -0
- package/template/src/views/dashboard/admin/components/TodoList/index.scss +320 -0
- package/template/src/views/dashboard/admin/components/TodoList/index.vue +127 -0
- package/template/src/views/dashboard/admin/components/TransactionTable.vue +55 -0
- package/template/src/views/dashboard/admin/components/mixins/resize.js +55 -0
- package/template/src/views/dashboard/admin/index.vue +124 -0
- package/template/src/views/dashboard/editor/index.vue +74 -0
- package/template/src/views/dashboard/index.vue +31 -0
- package/template/src/views/documentation/index.vue +56 -0
- package/template/src/views/error-log/components/ErrorTestA.vue +13 -0
- package/template/src/views/error-log/components/ErrorTestB.vue +11 -0
- package/template/src/views/error-log/index.vue +32 -0
- package/template/src/views/error-page/401.vue +99 -0
- package/template/src/views/error-page/404.vue +228 -0
- package/template/src/views/example/components/ArticleDetail.vue +289 -0
- package/template/src/views/example/components/Dropdown/Comment.vue +41 -0
- package/template/src/views/example/components/Dropdown/Platform.vue +46 -0
- package/template/src/views/example/components/Dropdown/SourceUrl.vue +38 -0
- package/template/src/views/example/components/Dropdown/index.js +3 -0
- package/template/src/views/example/components/Warning.vue +13 -0
- package/template/src/views/example/create.vue +13 -0
- package/template/src/views/example/edit.vue +13 -0
- package/template/src/views/example/list.vue +112 -0
- package/template/src/views/excel/components/AutoWidthOption.vue +34 -0
- package/template/src/views/excel/components/BookTypeOption.vue +39 -0
- package/template/src/views/excel/components/FilenameOption.vue +27 -0
- package/template/src/views/excel/export-excel.vue +116 -0
- package/template/src/views/excel/merge-header.vue +101 -0
- package/template/src/views/excel/select-excel.vue +107 -0
- package/template/src/views/excel/upload-excel.vue +42 -0
- package/template/src/views/guide/index.vue +36 -0
- package/template/src/views/guide/steps.js +53 -0
- package/template/src/views/icons/element-icons.js +3 -0
- package/template/src/views/icons/index.vue +101 -0
- package/template/src/views/icons/svg-icons.js +10 -0
- package/template/src/views/login/auth-redirect.vue +15 -0
- package/template/src/views/login/components/SocialSignin.vue +72 -0
- package/template/src/views/login/index.vue +324 -0
- package/template/src/views/nested/menu1/index.vue +7 -0
- package/template/src/views/nested/menu1/menu1-1/index.vue +7 -0
- package/template/src/views/nested/menu1/menu1-2/index.vue +7 -0
- package/template/src/views/nested/menu1/menu1-2/menu1-2-1/index.vue +5 -0
- package/template/src/views/nested/menu1/menu1-2/menu1-2-2/index.vue +5 -0
- package/template/src/views/nested/menu1/menu1-3/index.vue +5 -0
- package/template/src/views/nested/menu2/index.vue +5 -0
- package/template/src/views/pdf/content.js +58 -0
- package/template/src/views/pdf/download.vue +201 -0
- package/template/src/views/pdf/index.vue +13 -0
- package/template/src/views/permission/components/SwitchRoles.vue +32 -0
- package/template/src/views/permission/directive.vue +111 -0
- package/template/src/views/permission/page.vue +19 -0
- package/template/src/views/permission/role.vue +270 -0
- package/template/src/views/profile/components/Account.vue +38 -0
- package/template/src/views/profile/components/Activity.vue +185 -0
- package/template/src/views/profile/components/Timeline.vue +43 -0
- package/template/src/views/profile/components/UserCard.vue +134 -0
- package/template/src/views/profile/index.vue +68 -0
- package/template/src/views/qiniu/upload.vue +41 -0
- package/template/src/views/redirect/index.vue +12 -0
- package/template/src/views/tab/components/TabPane.vue +103 -0
- package/template/src/views/tab/index.vue +57 -0
- package/template/src/views/table/complex-table.vue +379 -0
- package/template/src/views/table/drag-table.vue +153 -0
- package/template/src/views/table/dynamic-table/components/FixedThead.vue +62 -0
- package/template/src/views/table/dynamic-table/components/UnfixedThead.vue +50 -0
- package/template/src/views/table/dynamic-table/index.vue +24 -0
- package/template/src/views/table/inline-edit-table.vue +149 -0
- package/template/src/views/theme/index.vue +120 -0
- package/template/src/views/zip/index.vue +77 -0
- package/template/tests/unit/.eslintrc.js +5 -0
- package/template/tests/unit/components/Hamburger.spec.js +18 -0
- package/template/tests/unit/components/SvgIcon.spec.js +22 -0
- package/template/tests/unit/utils/formatTime.spec.js +29 -0
- package/template/tests/unit/utils/param2Obj.spec.js +14 -0
- package/template/tests/unit/utils/parseTime.spec.js +37 -0
- package/template/tests/unit/utils/validate.spec.js +28 -0
- package/template/vue.config.js +125 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="app-container">
|
|
3
|
+
<switch-roles @change="handleRolesChange" />
|
|
4
|
+
<div :key="key" style="margin-top:30px;">
|
|
5
|
+
<div>
|
|
6
|
+
<span v-permission="['admin']" class="permission-alert">
|
|
7
|
+
Only
|
|
8
|
+
<el-tag class="permission-tag" size="small">admin</el-tag> can see this
|
|
9
|
+
</span>
|
|
10
|
+
<el-tag v-permission="['admin']" class="permission-sourceCode" type="info">
|
|
11
|
+
v-permission="['admin']"
|
|
12
|
+
</el-tag>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div>
|
|
16
|
+
<span v-permission="['editor']" class="permission-alert">
|
|
17
|
+
Only
|
|
18
|
+
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
|
|
19
|
+
</span>
|
|
20
|
+
<el-tag v-permission="['editor']" class="permission-sourceCode" type="info">
|
|
21
|
+
v-permission="['editor']"
|
|
22
|
+
</el-tag>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div>
|
|
26
|
+
<span v-permission="['admin','editor']" class="permission-alert">
|
|
27
|
+
Both
|
|
28
|
+
<el-tag class="permission-tag" size="small">admin</el-tag> and
|
|
29
|
+
<el-tag class="permission-tag" size="small">editor</el-tag> can see this
|
|
30
|
+
</span>
|
|
31
|
+
<el-tag v-permission="['admin','editor']" class="permission-sourceCode" type="info">
|
|
32
|
+
v-permission="['admin','editor']"
|
|
33
|
+
</el-tag>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div :key="'checkPermission'+key" style="margin-top:60px;">
|
|
38
|
+
<aside>
|
|
39
|
+
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.
|
|
40
|
+
<br> e.g.
|
|
41
|
+
</aside>
|
|
42
|
+
|
|
43
|
+
<el-tabs type="border-card" style="width:550px;">
|
|
44
|
+
<el-tab-pane v-if="checkPermission(['admin'])" label="Admin">
|
|
45
|
+
Admin can see this
|
|
46
|
+
<el-tag class="permission-sourceCode" type="info">
|
|
47
|
+
v-if="checkPermission(['admin'])"
|
|
48
|
+
</el-tag>
|
|
49
|
+
</el-tab-pane>
|
|
50
|
+
|
|
51
|
+
<el-tab-pane v-if="checkPermission(['editor'])" label="Editor">
|
|
52
|
+
Editor can see this
|
|
53
|
+
<el-tag class="permission-sourceCode" type="info">
|
|
54
|
+
v-if="checkPermission(['editor'])"
|
|
55
|
+
</el-tag>
|
|
56
|
+
</el-tab-pane>
|
|
57
|
+
|
|
58
|
+
<el-tab-pane v-if="checkPermission(['admin','editor'])" label="Admin-OR-Editor">
|
|
59
|
+
Both admin or editor can see this
|
|
60
|
+
<el-tag class="permission-sourceCode" type="info">
|
|
61
|
+
v-if="checkPermission(['admin','editor'])"
|
|
62
|
+
</el-tag>
|
|
63
|
+
</el-tab-pane>
|
|
64
|
+
</el-tabs>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</template>
|
|
68
|
+
|
|
69
|
+
<script>
|
|
70
|
+
import permission from '@/directive/permission/index.js' // 权限判断指令
|
|
71
|
+
import checkPermission from '@/utils/permission' // 权限判断函数
|
|
72
|
+
import SwitchRoles from './components/SwitchRoles'
|
|
73
|
+
|
|
74
|
+
export default {
|
|
75
|
+
name: 'DirectivePermission',
|
|
76
|
+
components: { SwitchRoles },
|
|
77
|
+
directives: { permission },
|
|
78
|
+
data() {
|
|
79
|
+
return {
|
|
80
|
+
key: 1 // 为了能每次切换权限的时候重新初始化指令
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
methods: {
|
|
84
|
+
checkPermission,
|
|
85
|
+
handleRolesChange() {
|
|
86
|
+
this.key++
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<style lang="scss" scoped>
|
|
93
|
+
.app-container {
|
|
94
|
+
::v-deep .permission-alert {
|
|
95
|
+
width: 320px;
|
|
96
|
+
margin-top: 15px;
|
|
97
|
+
background-color: #f0f9eb;
|
|
98
|
+
color: #67c23a;
|
|
99
|
+
padding: 8px 16px;
|
|
100
|
+
border-radius: 4px;
|
|
101
|
+
display: inline-block;
|
|
102
|
+
}
|
|
103
|
+
::v-deep .permission-sourceCode {
|
|
104
|
+
margin-left: 15px;
|
|
105
|
+
}
|
|
106
|
+
::v-deep .permission-tag {
|
|
107
|
+
background-color: #ecf5ff;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
111
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="app-container">
|
|
3
|
+
<switch-roles @change="handleRolesChange" />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
import SwitchRoles from './components/SwitchRoles'
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
name: 'PagePermission',
|
|
12
|
+
components: { SwitchRoles },
|
|
13
|
+
methods: {
|
|
14
|
+
handleRolesChange() {
|
|
15
|
+
this.$router.push({ path: '/permission/index?' + +new Date() })
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="app-container">
|
|
3
|
+
<el-button type="primary" @click="handleAddRole">New Role</el-button>
|
|
4
|
+
|
|
5
|
+
<el-table :data="rolesList" style="width: 100%;margin-top:30px;" border>
|
|
6
|
+
<el-table-column align="center" label="Role Key" width="220">
|
|
7
|
+
<template slot-scope="scope">
|
|
8
|
+
{{ scope.row.key }}
|
|
9
|
+
</template>
|
|
10
|
+
</el-table-column>
|
|
11
|
+
<el-table-column align="center" label="Role Name" width="220">
|
|
12
|
+
<template slot-scope="scope">
|
|
13
|
+
{{ scope.row.name }}
|
|
14
|
+
</template>
|
|
15
|
+
</el-table-column>
|
|
16
|
+
<el-table-column align="header-center" label="Description">
|
|
17
|
+
<template slot-scope="scope">
|
|
18
|
+
{{ scope.row.description }}
|
|
19
|
+
</template>
|
|
20
|
+
</el-table-column>
|
|
21
|
+
<el-table-column align="center" label="Operations">
|
|
22
|
+
<template slot-scope="scope">
|
|
23
|
+
<el-button type="primary" size="small" @click="handleEdit(scope)">Edit</el-button>
|
|
24
|
+
<el-button type="danger" size="small" @click="handleDelete(scope)">Delete</el-button>
|
|
25
|
+
</template>
|
|
26
|
+
</el-table-column>
|
|
27
|
+
</el-table>
|
|
28
|
+
|
|
29
|
+
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'Edit Role':'New Role'">
|
|
30
|
+
<el-form :model="role" label-width="80px" label-position="left">
|
|
31
|
+
<el-form-item label="Name">
|
|
32
|
+
<el-input v-model="role.name" placeholder="Role Name" />
|
|
33
|
+
</el-form-item>
|
|
34
|
+
<el-form-item label="Desc">
|
|
35
|
+
<el-input
|
|
36
|
+
v-model="role.description"
|
|
37
|
+
:autosize="{ minRows: 2, maxRows: 4}"
|
|
38
|
+
type="textarea"
|
|
39
|
+
placeholder="Role Description"
|
|
40
|
+
/>
|
|
41
|
+
</el-form-item>
|
|
42
|
+
<el-form-item label="Menus">
|
|
43
|
+
<el-tree
|
|
44
|
+
ref="tree"
|
|
45
|
+
:check-strictly="checkStrictly"
|
|
46
|
+
:data="routesData"
|
|
47
|
+
:props="defaultProps"
|
|
48
|
+
show-checkbox
|
|
49
|
+
node-key="path"
|
|
50
|
+
class="permission-tree"
|
|
51
|
+
/>
|
|
52
|
+
</el-form-item>
|
|
53
|
+
</el-form>
|
|
54
|
+
<div style="text-align:right;">
|
|
55
|
+
<el-button type="danger" @click="dialogVisible=false">Cancel</el-button>
|
|
56
|
+
<el-button type="primary" @click="confirmRole">Confirm</el-button>
|
|
57
|
+
</div>
|
|
58
|
+
</el-dialog>
|
|
59
|
+
</div>
|
|
60
|
+
</template>
|
|
61
|
+
|
|
62
|
+
<script>
|
|
63
|
+
import path from 'path'
|
|
64
|
+
import { deepClone } from '@/utils'
|
|
65
|
+
import { getRoutes, getRoles, addRole, deleteRole, updateRole } from '@/api/role'
|
|
66
|
+
|
|
67
|
+
const defaultRole = {
|
|
68
|
+
key: '',
|
|
69
|
+
name: '',
|
|
70
|
+
description: '',
|
|
71
|
+
routes: []
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default {
|
|
75
|
+
data() {
|
|
76
|
+
return {
|
|
77
|
+
role: Object.assign({}, defaultRole),
|
|
78
|
+
routes: [],
|
|
79
|
+
rolesList: [],
|
|
80
|
+
dialogVisible: false,
|
|
81
|
+
dialogType: 'new',
|
|
82
|
+
checkStrictly: false,
|
|
83
|
+
defaultProps: {
|
|
84
|
+
children: 'children',
|
|
85
|
+
label: 'title'
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
computed: {
|
|
90
|
+
routesData() {
|
|
91
|
+
return this.routes
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
created() {
|
|
95
|
+
// Mock: get all routes and roles list from server
|
|
96
|
+
this.getRoutes()
|
|
97
|
+
this.getRoles()
|
|
98
|
+
},
|
|
99
|
+
methods: {
|
|
100
|
+
async getRoutes() {
|
|
101
|
+
const res = await getRoutes()
|
|
102
|
+
this.serviceRoutes = res.data
|
|
103
|
+
this.routes = this.generateRoutes(res.data)
|
|
104
|
+
},
|
|
105
|
+
async getRoles() {
|
|
106
|
+
const res = await getRoles()
|
|
107
|
+
this.rolesList = res.data
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
// Reshape the routes structure so that it looks the same as the sidebar
|
|
111
|
+
generateRoutes(routes, basePath = '/') {
|
|
112
|
+
const res = []
|
|
113
|
+
|
|
114
|
+
for (let route of routes) {
|
|
115
|
+
// skip some route
|
|
116
|
+
if (route.hidden) { continue }
|
|
117
|
+
|
|
118
|
+
const onlyOneShowingChild = this.onlyOneShowingChild(route.children, route)
|
|
119
|
+
|
|
120
|
+
if (route.children && onlyOneShowingChild && !route.alwaysShow) {
|
|
121
|
+
route = onlyOneShowingChild
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const data = {
|
|
125
|
+
path: path.resolve(basePath, route.path),
|
|
126
|
+
title: route.meta && route.meta.title
|
|
127
|
+
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// recursive child routes
|
|
131
|
+
if (route.children) {
|
|
132
|
+
data.children = this.generateRoutes(route.children, data.path)
|
|
133
|
+
}
|
|
134
|
+
res.push(data)
|
|
135
|
+
}
|
|
136
|
+
return res
|
|
137
|
+
},
|
|
138
|
+
generateArr(routes) {
|
|
139
|
+
let data = []
|
|
140
|
+
routes.forEach(route => {
|
|
141
|
+
data.push(route)
|
|
142
|
+
if (route.children) {
|
|
143
|
+
const temp = this.generateArr(route.children)
|
|
144
|
+
if (temp.length > 0) {
|
|
145
|
+
data = [...data, ...temp]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
return data
|
|
150
|
+
},
|
|
151
|
+
handleAddRole() {
|
|
152
|
+
this.role = Object.assign({}, defaultRole)
|
|
153
|
+
if (this.$refs.tree) {
|
|
154
|
+
this.$refs.tree.setCheckedNodes([])
|
|
155
|
+
}
|
|
156
|
+
this.dialogType = 'new'
|
|
157
|
+
this.dialogVisible = true
|
|
158
|
+
},
|
|
159
|
+
handleEdit(scope) {
|
|
160
|
+
this.dialogType = 'edit'
|
|
161
|
+
this.dialogVisible = true
|
|
162
|
+
this.checkStrictly = true
|
|
163
|
+
this.role = deepClone(scope.row)
|
|
164
|
+
this.$nextTick(() => {
|
|
165
|
+
const routes = this.generateRoutes(this.role.routes)
|
|
166
|
+
this.$refs.tree.setCheckedNodes(this.generateArr(routes))
|
|
167
|
+
// set checked state of a node not affects its father and child nodes
|
|
168
|
+
this.checkStrictly = false
|
|
169
|
+
})
|
|
170
|
+
},
|
|
171
|
+
handleDelete({ $index, row }) {
|
|
172
|
+
this.$confirm('Confirm to remove the role?', 'Warning', {
|
|
173
|
+
confirmButtonText: 'Confirm',
|
|
174
|
+
cancelButtonText: 'Cancel',
|
|
175
|
+
type: 'warning'
|
|
176
|
+
})
|
|
177
|
+
.then(async() => {
|
|
178
|
+
await deleteRole(row.key)
|
|
179
|
+
this.rolesList.splice($index, 1)
|
|
180
|
+
this.$message({
|
|
181
|
+
type: 'success',
|
|
182
|
+
message: 'Delete succed!'
|
|
183
|
+
})
|
|
184
|
+
})
|
|
185
|
+
.catch(err => { console.error(err) })
|
|
186
|
+
},
|
|
187
|
+
generateTree(routes, basePath = '/', checkedKeys) {
|
|
188
|
+
const res = []
|
|
189
|
+
|
|
190
|
+
for (const route of routes) {
|
|
191
|
+
const routePath = path.resolve(basePath, route.path)
|
|
192
|
+
|
|
193
|
+
// recursive child routes
|
|
194
|
+
if (route.children) {
|
|
195
|
+
route.children = this.generateTree(route.children, routePath, checkedKeys)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (checkedKeys.includes(routePath) || (route.children && route.children.length >= 1)) {
|
|
199
|
+
res.push(route)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return res
|
|
203
|
+
},
|
|
204
|
+
async confirmRole() {
|
|
205
|
+
const isEdit = this.dialogType === 'edit'
|
|
206
|
+
|
|
207
|
+
const checkedKeys = this.$refs.tree.getCheckedKeys()
|
|
208
|
+
this.role.routes = this.generateTree(deepClone(this.serviceRoutes), '/', checkedKeys)
|
|
209
|
+
|
|
210
|
+
if (isEdit) {
|
|
211
|
+
await updateRole(this.role.key, this.role)
|
|
212
|
+
for (let index = 0; index < this.rolesList.length; index++) {
|
|
213
|
+
if (this.rolesList[index].key === this.role.key) {
|
|
214
|
+
this.rolesList.splice(index, 1, Object.assign({}, this.role))
|
|
215
|
+
break
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
const { data } = await addRole(this.role)
|
|
220
|
+
this.role.key = data.key
|
|
221
|
+
this.rolesList.push(this.role)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const { description, key, name } = this.role
|
|
225
|
+
this.dialogVisible = false
|
|
226
|
+
this.$notify({
|
|
227
|
+
title: 'Success',
|
|
228
|
+
dangerouslyUseHTMLString: true,
|
|
229
|
+
message: `
|
|
230
|
+
<div>Role Key: ${key}</div>
|
|
231
|
+
<div>Role Name: ${name}</div>
|
|
232
|
+
<div>Description: ${description}</div>
|
|
233
|
+
`,
|
|
234
|
+
type: 'success'
|
|
235
|
+
})
|
|
236
|
+
},
|
|
237
|
+
// reference: src/view/layout/components/Sidebar/SidebarItem.vue
|
|
238
|
+
onlyOneShowingChild(children = [], parent) {
|
|
239
|
+
let onlyOneChild = null
|
|
240
|
+
const showingChildren = children.filter(item => !item.hidden)
|
|
241
|
+
|
|
242
|
+
// When there is only one child route, the child route is displayed by default
|
|
243
|
+
if (showingChildren.length === 1) {
|
|
244
|
+
onlyOneChild = showingChildren[0]
|
|
245
|
+
onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path)
|
|
246
|
+
return onlyOneChild
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Show parent if there are no child route to display
|
|
250
|
+
if (showingChildren.length === 0) {
|
|
251
|
+
onlyOneChild = { ... parent, path: '', noShowingChildren: true }
|
|
252
|
+
return onlyOneChild
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return false
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
</script>
|
|
260
|
+
|
|
261
|
+
<style lang="scss" scoped>
|
|
262
|
+
.app-container {
|
|
263
|
+
.roles-table {
|
|
264
|
+
margin-top: 30px;
|
|
265
|
+
}
|
|
266
|
+
.permission-tree {
|
|
267
|
+
margin-bottom: 30px;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
</style>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-form>
|
|
3
|
+
<el-form-item label="Name">
|
|
4
|
+
<el-input v-model.trim="user.name" />
|
|
5
|
+
</el-form-item>
|
|
6
|
+
<el-form-item label="Email">
|
|
7
|
+
<el-input v-model.trim="user.email" />
|
|
8
|
+
</el-form-item>
|
|
9
|
+
<el-form-item>
|
|
10
|
+
<el-button type="primary" @click="submit">Update</el-button>
|
|
11
|
+
</el-form-item>
|
|
12
|
+
</el-form>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
export default {
|
|
17
|
+
props: {
|
|
18
|
+
user: {
|
|
19
|
+
type: Object,
|
|
20
|
+
default: () => {
|
|
21
|
+
return {
|
|
22
|
+
name: '',
|
|
23
|
+
email: ''
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
methods: {
|
|
29
|
+
submit() {
|
|
30
|
+
this.$message({
|
|
31
|
+
message: 'User information has been updated successfully',
|
|
32
|
+
type: 'success',
|
|
33
|
+
duration: 5 * 1000
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="user-activity">
|
|
3
|
+
<div class="post">
|
|
4
|
+
<div class="user-block">
|
|
5
|
+
<img class="img-circle" :src="'https://wpimg.wallstcn.com/57ed425a-c71e-4201-9428-68760c0537c4.jpg'+avatarPrefix">
|
|
6
|
+
<span class="username text-muted">Iron Man</span>
|
|
7
|
+
<span class="description">Shared publicly - 7:30 PM today</span>
|
|
8
|
+
</div>
|
|
9
|
+
<p>
|
|
10
|
+
Lorem ipsum represents a long-held tradition for designers,
|
|
11
|
+
typographers and the like. Some people hate it and argue for
|
|
12
|
+
its demise, but others ignore the hate as they create awesome
|
|
13
|
+
tools to help create filler text for everyone from bacon lovers
|
|
14
|
+
to Charlie Sheen fans.
|
|
15
|
+
</p>
|
|
16
|
+
<ul class="list-inline">
|
|
17
|
+
<li>
|
|
18
|
+
<span class="link-black text-sm">
|
|
19
|
+
<i class="el-icon-share" />
|
|
20
|
+
Share
|
|
21
|
+
</span>
|
|
22
|
+
</li>
|
|
23
|
+
<li>
|
|
24
|
+
<span class="link-black text-sm">
|
|
25
|
+
<svg-icon icon-class="like" />
|
|
26
|
+
Like
|
|
27
|
+
</span>
|
|
28
|
+
</li>
|
|
29
|
+
</ul>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="post">
|
|
32
|
+
<div class="user-block">
|
|
33
|
+
<img class="img-circle" :src="'https://wpimg.wallstcn.com/9e2a5d0a-bd5b-457f-ac8e-86554616c87b.jpg'+avatarPrefix">
|
|
34
|
+
<span class="username text-muted">Captain American</span>
|
|
35
|
+
<span class="description">Sent you a message - yesterday</span>
|
|
36
|
+
</div>
|
|
37
|
+
<p>
|
|
38
|
+
Lorem ipsum represents a long-held tradition for designers,
|
|
39
|
+
typographers and the like. Some people hate it and argue for
|
|
40
|
+
its demise, but others ignore the hate as they create awesome
|
|
41
|
+
tools to help create filler text for everyone from bacon lovers
|
|
42
|
+
to Charlie Sheen fans.
|
|
43
|
+
</p>
|
|
44
|
+
<ul class="list-inline">
|
|
45
|
+
<li>
|
|
46
|
+
<span class="link-black text-sm">
|
|
47
|
+
<i class="el-icon-share" />
|
|
48
|
+
Share
|
|
49
|
+
</span>
|
|
50
|
+
</li>
|
|
51
|
+
<li>
|
|
52
|
+
<span class="link-black text-sm">
|
|
53
|
+
<svg-icon icon-class="like" />
|
|
54
|
+
Like
|
|
55
|
+
</span>
|
|
56
|
+
</li>
|
|
57
|
+
</ul>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="post">
|
|
60
|
+
<div class="user-block">
|
|
61
|
+
<img class="img-circle" :src="'https://wpimg.wallstcn.com/fb57f689-e1ab-443c-af12-8d4066e202e2.jpg'+avatarPrefix">
|
|
62
|
+
<span class="username">Spider Man</span>
|
|
63
|
+
<span class="description">Posted 4 photos - 2 days ago</span>
|
|
64
|
+
</div>
|
|
65
|
+
<div class="user-images">
|
|
66
|
+
<el-carousel :interval="6000" type="card" height="220px">
|
|
67
|
+
<el-carousel-item v-for="item in carouselImages" :key="item">
|
|
68
|
+
<img :src="item+carouselPrefix" class="image">
|
|
69
|
+
</el-carousel-item>
|
|
70
|
+
</el-carousel>
|
|
71
|
+
</div>
|
|
72
|
+
<ul class="list-inline">
|
|
73
|
+
<li><span class="link-black text-sm"><i class="el-icon-share" /> Share</span></li>
|
|
74
|
+
<li>
|
|
75
|
+
<span class="link-black text-sm">
|
|
76
|
+
<svg-icon icon-class="like" /> Like</span>
|
|
77
|
+
</li>
|
|
78
|
+
</ul>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</template>
|
|
82
|
+
|
|
83
|
+
<script>
|
|
84
|
+
const avatarPrefix = '?imageView2/1/w/80/h/80'
|
|
85
|
+
const carouselPrefix = '?imageView2/2/h/440'
|
|
86
|
+
|
|
87
|
+
export default {
|
|
88
|
+
data() {
|
|
89
|
+
return {
|
|
90
|
+
carouselImages: [
|
|
91
|
+
'https://wpimg.wallstcn.com/9679ffb0-9e0b-4451-9916-e21992218054.jpg',
|
|
92
|
+
'https://wpimg.wallstcn.com/bcce3734-0837-4b9f-9261-351ef384f75a.jpg',
|
|
93
|
+
'https://wpimg.wallstcn.com/d1d7b033-d75e-4cd6-ae39-fcd5f1c0a7c5.jpg',
|
|
94
|
+
'https://wpimg.wallstcn.com/50530061-851b-4ca5-9dc5-2fead928a939.jpg'
|
|
95
|
+
],
|
|
96
|
+
avatarPrefix,
|
|
97
|
+
carouselPrefix
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<style lang="scss" scoped>
|
|
104
|
+
.user-activity {
|
|
105
|
+
.user-block {
|
|
106
|
+
|
|
107
|
+
.username,
|
|
108
|
+
.description {
|
|
109
|
+
display: block;
|
|
110
|
+
margin-left: 50px;
|
|
111
|
+
padding: 2px 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.username{
|
|
115
|
+
font-size: 16px;
|
|
116
|
+
color: #000;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
:after {
|
|
120
|
+
clear: both;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.img-circle {
|
|
124
|
+
border-radius: 50%;
|
|
125
|
+
width: 40px;
|
|
126
|
+
height: 40px;
|
|
127
|
+
float: left;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
span {
|
|
131
|
+
font-weight: 500;
|
|
132
|
+
font-size: 12px;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.post {
|
|
137
|
+
font-size: 14px;
|
|
138
|
+
border-bottom: 1px solid #d2d6de;
|
|
139
|
+
margin-bottom: 15px;
|
|
140
|
+
padding-bottom: 15px;
|
|
141
|
+
color: #666;
|
|
142
|
+
|
|
143
|
+
.image {
|
|
144
|
+
width: 100%;
|
|
145
|
+
height: 100%;
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.user-images {
|
|
150
|
+
padding-top: 20px;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.list-inline {
|
|
155
|
+
padding-left: 0;
|
|
156
|
+
margin-left: -5px;
|
|
157
|
+
list-style: none;
|
|
158
|
+
|
|
159
|
+
li {
|
|
160
|
+
display: inline-block;
|
|
161
|
+
padding-right: 5px;
|
|
162
|
+
padding-left: 5px;
|
|
163
|
+
font-size: 13px;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.link-black {
|
|
167
|
+
|
|
168
|
+
&:hover,
|
|
169
|
+
&:focus {
|
|
170
|
+
color: #999;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.box-center {
|
|
178
|
+
margin: 0 auto;
|
|
179
|
+
display: table;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.text-muted {
|
|
183
|
+
color: #777;
|
|
184
|
+
}
|
|
185
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="block">
|
|
3
|
+
<el-timeline>
|
|
4
|
+
<el-timeline-item v-for="(item,index) of timeline" :key="index" :timestamp="item.timestamp" placement="top">
|
|
5
|
+
<el-card>
|
|
6
|
+
<h4>{{ item.title }}</h4>
|
|
7
|
+
<p>{{ item.content }}</p>
|
|
8
|
+
</el-card>
|
|
9
|
+
</el-timeline-item>
|
|
10
|
+
</el-timeline>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
export default {
|
|
16
|
+
data() {
|
|
17
|
+
return {
|
|
18
|
+
timeline: [
|
|
19
|
+
{
|
|
20
|
+
timestamp: '2019/4/20',
|
|
21
|
+
title: 'Update Github template',
|
|
22
|
+
content: 'PanJiaChen committed 2019/4/20 20:46'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
timestamp: '2019/4/21',
|
|
26
|
+
title: 'Update Github template',
|
|
27
|
+
content: 'PanJiaChen committed 2019/4/21 20:46'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
timestamp: '2019/4/22',
|
|
31
|
+
title: 'Build Template',
|
|
32
|
+
content: 'PanJiaChen committed 2019/4/22 20:46'
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
timestamp: '2019/4/23',
|
|
36
|
+
title: 'Release New Version',
|
|
37
|
+
content: 'PanJiaChen committed 2019/4/23 20:46'
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</script>
|