init: init for basic version

This commit is contained in:
chenghongxing 2020-07-23 10:39:01 +08:00
parent 272f740597
commit d279d2f976
106 changed files with 184 additions and 5037 deletions

View File

@ -1,42 +0,0 @@
<template>
<div class="alert" :style="`top: ${top}px`">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'Alert',
props: ['show'],
data() {
return {
top: 100
}
},
mounted() {
console.log(this)
// this.$page.alert = this.$page.alert ? this.$page.alert : {top: 100}
// this.$page.alert.top += 20
// this.top = this.$page.alert.top
setTimeout(() => {
this.$el.remove()
}, 1000)
}
}
</script>
<style scoped>
.alert{
position: absolute;
padding: 6px 8px;
background-color: #f0f2f5;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
border-radius: 4px;
margin: 0 auto;
z-index: 999;
top: 100px;
width: fit-content;
left: 0;
right: 0;
}
</style>

View File

@ -1,35 +0,0 @@
<template>
<div :data-clipboard-text="color" class="color" @click="onClick" :style="`background-color:${color}`" />
</template>
<script>
import Clipboard from 'clipboard'
export default {
name: 'Color',
props: ['color'],
data() {
return {
alert: false
}
},
methods: {
onClick() {
let clipboard = new Clipboard('.color')
clipboard.on('success', () => {
this.$alert(`颜色代码已复制:${this.color}`)
clipboard.destroy()
})
}
}
}
</script>
<style scoped>
.color{
border: 1px dashed #a0d911;
display: inline-block;
width: 20px;
height: 20px;
cursor: pointer;
}
</style>

View File

@ -1,18 +0,0 @@
<template>
<div>
<color class="color" :key="index" v-for="(color, index) in colors" :color="color" ></color>
</div>
</template>
<script>
export default {
name: 'ColorList',
props: ['colors']
}
</script>
<style scoped>
.color{
margin: 0 2px;
}
</style>

View File

@ -1,57 +0,0 @@
module.exports = {
title: 'Vue Antd Admin',
description: 'Vue Antd Admin',
base: '/vue-antd-admin/',
head: [
['link', { rel: 'icon', href: '/favicon.ico' }]
],
themeConfig: {
logo: '/logo.png',
repo: 'iczer/vue-antd-admin',
docsDir: 'docs',
editLinks: true,
editLinkText: '在 Github 上帮助我们编辑此页',
nav: [
{text: '指南', link: '/'},
{text: '配置', link: '/develop/layout'},
{text: '主题', link: '/advance/theme'},
],
lastUpdated: 'Last Updated',
sidebar: [
{
title: '开始',
collapsable: false,
children: [
'/start/use', '/start/faq'
]
},
{
title: '开发',
collapsable: false,
children: [
'/develop/layout', '/develop/router', '/develop/page', '/develop/theme', '/develop/service', '/develop/mock'
]
},
{
title: '进阶',
collapsable: false,
children: [
'/advance/i18n', '/advance/chart', '/advance/theme', '/advance/error', '/advance/authority'
]
},
{
title: '其它',
collapsable: false,
children: [
'/other/upgrade', '/other/community'
]
}
],
nextLinks: true,
prevLinks: true,
},
plugins: ['@vuepress/back-to-top', require('./plugins/alert')],
markdown: {
lineNumbers: true
}
}

View File

@ -1,46 +0,0 @@
<template>
<div class="alert" :style="`top: ${top}px`">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'Alert',
props: ['alert'],
data() {
return {
top: 0
}
},
beforeMount() {
this.top = this.alert.top
},
mounted() {
window.addEventListener('alert_remove', (e) => {
this.top -= e.detail.height
})
},
watch: {
'page.alert.top': function (value) {
}
}
}
</script>
<style scoped>
.alert{
position: fixed;
padding: 6px 8px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.25);
border-radius: 4px;
margin: 0 auto;
z-index: 999;
top: 100px;
width: fit-content;
left: 0;
right: 0;
transition: top 0.3s;
}
</style>

View File

@ -1,38 +0,0 @@
import Alert from './Alert'
const AlertMixin = {
install(Vue) {
Vue.mixin({
methods: {
$alert(message, duration = 2000) {
let Constructor= Vue.extend(Alert)
let alert = new Constructor()
alert.$slots.default = message
alert.$props.alert = this.$page.alert
alert.$mount()
document.body.appendChild(alert.$el)
const appendHeight = alert.$el.offsetHeight + 16
this.$page.alert.top += appendHeight
setTimeout(() => {
this.$page.alert.top -= appendHeight
this.triggerRemoveAlert(appendHeight)
setTimeout(() => {
alert.$destroy()
alert.$el.remove()
}, 100)
}, duration)
},
triggerRemoveAlert(height) {
const event = new CustomEvent('alert_remove', {
detail: {height}
})
window.dispatchEvent(event)
}
}
})
}
}
export default AlertMixin

View File

@ -1,5 +0,0 @@
export default {
updated() {
this.$page.alert.top = 100
}
}

View File

@ -1,5 +0,0 @@
import AlertMixin from './alertMixin'
export default ({Vue}) => {
Vue.use(AlertMixin)
}

View File

@ -1,13 +0,0 @@
const path = require('path')
module.exports = (options, ctx) => {
return {
clientRootMixin: path.resolve(__dirname, 'clientRootMixin.js'),
extendPageData($page) {
$page.alert = {
top: 100
}
},
enhanceAppFiles: path.resolve(__dirname, 'enhanceApp.js')
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,12 +0,0 @@
.custom-block.tip{
border-color: #1890ff
}
.theme-default-content code .token.inserted{
color: #60bd90;
}
//.custom-block.warning{
// border-color: #fa8c16
//}
//.custom-block.error{
// border-color: #f5222d
//}

View File

@ -1,2 +0,0 @@
$accentColor = #1890ff
$contentWidth = 940px

View File

@ -1,17 +0,0 @@
---
title: 首页
home: true
heroImage: /logo.png
heroText: Vue Antd Admin
tagline: 开箱即用的中台前端/设计解决方案
actionText: 快速上手 →
actionLink: /start/use
features:
- title: 简洁
details: 以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。
- title: 优雅
details: 享受 Vue + webpack 的开发体验,在 Markdown 中使用 Vue 组件,同时可以使用 Vue 来开发自定义主题。
- title: 自然
details: VuePress 为每个页面预渲染生成静态的 HTML同时在页面被加载的时候将作为 SPA 运行。
footer: MIT Licensed | Copyright © 2018-present iczer
---

View File

@ -1,5 +0,0 @@
---
title: 进阶
lang: zn-CN
---
# 进阶

View File

@ -1,7 +0,0 @@
---
title: 权限管理
lang: zn-CN
---
# 权限管理
### 作者还没来得及编辑该页面,如果你感兴趣,可以点击下方链接,帮助作者完善此页

View File

@ -1,7 +0,0 @@
---
title: 图表
lang: zn-CN
---
# 图表
### 作者还没来得及编辑该页面,如果你感兴趣,可以点击下方链接,帮助作者完善此页

View File

@ -1,7 +0,0 @@
---
title: 错误处理
lang: zn-CN
---
# 错误处理
### 作者还没来得及编辑该页面,如果你感兴趣,可以点击下方链接,帮助作者完善此页

View File

@ -1,7 +0,0 @@
---
title: 国际化
lang: zn-CN
---
# 国际化
### 作者还没来得及编辑该页面,如果你感兴趣,可以点击下方链接,帮助作者完善此页

View File

@ -1,7 +0,0 @@
---
title: 更换主题
lang: zn-CN
---
# 更换主题
### 作者还没来得及编辑该页面,如果你感兴趣,可以点击下方链接,帮助作者完善此页

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@ -1,5 +0,0 @@
---
title: 开发
lang: zh-CN
---
# 开发

View File

@ -1,79 +0,0 @@
---
title: 布局
lang: zh-CN
---
# 布局
页面整体布局是一个产品最外层的框架结构,往往会包含导航、页脚、侧边栏、通知栏以及内容等。在页面之中,也有很多区块的布局结构。在真实项目中,页面布局通常统领整个应用的界面,有非常重要的作用。
## Admin 的布局
在 Vue Antd Admin 中,我们抽离了使用过程中一些常用的布局,都放在 layouts 目录中,分别为:
* [AdminLayout](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/AdminLayout.vue) / **管理后台布局**,包含了头部导航,侧边导航、内容区和页脚,一般用于后台系统的整体布局
![admin-layout](../assets/admin-layout.png)
* [PageLayout](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageLayout.vue) / **页面布局**,包含了页头和内容区,常用于需要页头(包含面包屑、标题、额外操作等)的页面
![page-layout](../assets/page-layout.png)
* [CommonLayout](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/CommonLayout.vue) / **通用布局**,仅包含内容区和页脚的简单布局,项目中常用于注册、登录或展示页面
![common-layout](../assets/common-layout.png)
## Admin 的视图
在 Vue Antd Admin 中,除了基本布局外,通常有很多页面的结构是相似的。因此,我们把这部分结构抽离为视图组件。
一个视图组件通常包含一个基本布局组件、视图公共区块、路由视图内容区、页脚等,常常结合路由配置使用。它们也被放入了 layouts 目录中,分别为:
* [TabsView](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/TabsView.vue) / **多页签视图**,包含了 AdminLayout 布局、多页签头和路由视图内容区
![tabs-view](../assets/tabs-view.png)
* [PageView](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageView.vue) / **页面视图**,包含了 PageLayout 布局和路由视图内容区
![page-view](../assets/page-view.png)
* [BlankView](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/BlankView.vue) / **空白视图**,仅包含一个路由视图内容区
![blank-view](../assets/blank-view.png)
## 如何使用
通常我们会把视图组件和路由配置结合一起使用,我们把配置信息抽离在路由配置文件中 [router/index.js](https://github.com/iczer/vue-antd-admin/blob/master/src/router/index.js) 。如下:
```jsx {7,12}
{
path: 'form',
name: '表单页',
meta: {
icon: 'form',
},
component: PageView,
children: [
{
path: 'basic',
name: '基础表单',
component: () => import('@/pages/form/basic/BasicForm'),
}
]
}
```
当然,如果这满足不了你的需求,你也可以自定义一些视图组件,或者直接在页面组件中使用布局。参考
[workplace](https://github.com/iczer/vue-antd-admin/blob/master/src/pages/dashboard/workplace/WorkPlace.vue) 页面:
```vue {2,13}
<template>
<page-layout :avatar="currUser.avatar">
<div slot="headerContent">
<div class="title">{{$t('timeFix')}}{{currUser.name}}{{$t('welcome')}}</div>
<div>{{$t('position')}}</div>
</div>
<template slot="extra">
<head-info class="split-right" :title="$t('project')" content="56"/>
<head-info class="split-right" :title="$t('ranking')" content="8/24"/>
<head-info class="split-right" :title="$t('visit')" content="2,223"/>
</template>
<div>...</div>
</page-layout>
</template>
```
## 其它布局组件
除了 Admin 里的内建布局以外,在一些页面中需要进行布局,还可以使用 Ant Design Vue 提供的布局组件Grid 和 Layout。
### Grid 组件
栅格布局是网页中最常用的布局,其特点就是按照一定比例划分页面,能够随着屏幕的变化依旧保持比例,从而具有弹性布局的特点。
而 Ant Design Vue 的栅格组件提供的功能更为强大,能够设置间距、具有支持响应式的比例设置,以及支持 flex 模式,基本上涵盖了大部分的布局场景,详情查看:[Grid](https://www.antdv.com/components/grid-cn/)。
### Layout 组件
如果你需要辅助页面框架级别的布局设计,那么 Layout 则是你最佳的选择,它抽象了大部分框架布局结构,使得只需要填空就可以开发规范专业的页面整体布局,详情查看:[Layout](https://www.antdv.com/components/layout-cn/)。
### 根据不同场景区分抽离布局组件
在大部分场景下,我们需要基于上面两个组件封装一些适用于当下具体业务的组件,包含了通用的导航、侧边栏、顶部通知、页面标题等元素。例如 Vue Antd Admin 的 [AdminLayout](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/AdminLayout.vue)。
通常,我们会把抽象出来的布局组件,放到 layouts 文件夹中方便管理。需要注意的是,这些布局组件和我们平时使用的其它组件并没有什么不同,只不过功能性上是为了处理布局问题而单独归类。

View File

@ -1,7 +0,0 @@
---
title: Mock
lang: zh-CN
---
# Mock
### 作者还没来得及编辑该页面,如果你感兴趣,可以点击下方链接,帮助作者完善此页

View File

@ -1,218 +0,0 @@
---
title: 页面
lang: zh-CN
---
# 页面
这里的『页面』包含新建页面文件配置路由、样式文件及i18n国际化等。通常情况下你仅需简单的配置就可以添加一个新的页面。
## 新建页面文件
在 src/pages 下创建新的 .vue 文件。如果页面相关文件过多,您可以创建一个文件夹来放置这些文件。
```diff
├── public
├── src
│ ├── assets # 本地静态资源
: :
│ ├── pages # 页面组件和通用模板
+ │ │ └── newPage.vue # 新页面文件
or
+ │ │ └── newFolder # 为新页面创建一个文件夹
+ │ │ ├── newPage.vue # 新页面文件
+ │ │ ├── index.less # 页面样式文件
+ │ │ └── index.js # import 引导文件
: :
│ └── main.js # 应用入口js
├── package.json # package.json
├── README.md # README.md
└── vue.config.js # vue 配置文件
```
为了更好地演示,我们初始化 newPage.vue 文件如下:
```vue
<template>
<div class="new-page" :style="`min-height: ${layoutMinHeight}px`">
<h1>演示页面</h1>
</div>
</template>
<script>
export default {
name: 'NewPage',
inject: ['layoutMinHeight'],
data() {
return {
desc: '这是一个演示页面'
}
}
}
</script>
<style scoped lang="less">
@import "index.less";
</style>
```
index.less 文件:
```less
.new-page{
height: 100%;
background-color: @base-bg-color;
text-align: center;
padding: 200px 0 0 0;
margin-top: -24px;
h1{
font-size: 48px;
}
}
```
index.js 文件:
```js
import NewPage from '@/pages/newPage/NewPage'
export default NewPage
```
## 配置路由
路由配置在 src/router/index.js 文件中,我们把上面创建的页面文件加入路由配置中
```js {10-14}
const router = new Router({
routes: [
{name: '登录页'...},
{
path: '/',
name: '首页',
component: TabsView,
redirect: '/login',
children: [
{
path: 'newPage',
name: '新页面',
component: () => import('@/pages/newPage'),
},
{
path: 'dashboard',
name: 'Dashboard',
meta: {
icon: 'dashboard'
},
component: BlankView,
children: [...]
}
]
...
}
]
})
```
:::tip
我们建议使用英文设置路由的 path 属性,用中文设置路由的 name 属性。因为系统将自动提取路由的 path 和 name 属性作为国际化配置。这在后面的章节
[进阶>国际化](../advance/i18n.md)中将会讲到。
当然,如果你的项目不需要国际化,可以忽略。
:::
启动服务,你将看到新增页面如下:
![newPage](../assets/new-page.png)
如果你想把它配置为二级页面或更深层级的页面,只需为它配置一个父级路由,并为父级路由配置一个[视图组件](./layout.md#admin-的视图)
这里我们选择 [PageView](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageView.vue),如下:
```js {10-21}
const router = new Router({
routes: [
{name: '登录页'...},
{
path: '/',
name: '首页',
component: TabsView,
redirect: '/login',
children: [
{
path: 'parent',
name: '父级路由',
component: PageView,
children: [
{
path: 'newPage',
name: '新页面',
component: () => import('@/pages/newPage'),
}
]
},
{name: 'dashboard'...}
]
...
}
]
})
```
:::warning
页面所有父级路由的组件必须配置为[视图组件](../develop/layout.md#admin-的视图),否则页面的内容可能不会显示。
目前有 [PageView](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageView.vue)、
[TabsView](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/tabs/TabsView.vue) 和
[BlankView](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/BlankView.vue) 可选,
你也可以自己创建视图组件。([什么是视图组件?](../develop/layout.md#admin-的视图)
:::
页面如下:
![newPage2](../assets/new-page-2.png)
## i18n国际化配置
如果你想为页面增加i18n国际化配置只需在页面同级文件夹下创建 i18n.js 文件,然后在页面文件中引入并使用即可。
创建 i18n.js 文件:
```diff {6-10}
├── public
├── src
│ ├── assets # 本地静态资源
: :
│ ├── pages # 页面组件和通用模板
│ │ └── newFolder # 为新页面创建一个文件夹
│ │ ├── newPage.vue # 新页面文件
│ │ ├── index.less # 页面样式文件
+ │ │ ├── i18n.js # i18n 国际化配置文件
│ │ └── index.js # import 引导文件
: :
│ └── main.js # 应用入口js
├── package.json # package.json
├── README.md # README.md
└── vue.config.js # vue 配置文件
```
i18n.js 文件内容:
```js
module.exports = {
messages: {
CN: {
content: '演示页面',
description: '这是一个演示页面'
},
HK: {
content: '演示頁面',
description: '這是一個演示頁面'
},
US: {
content: 'Demo Page',
description: 'This is a demo page'
}
}
}
```
在 NewPage.vue 文件中引入 i18n.js并添加需要国际化的内容。如下修改
```vue {3,11-15}
<template>
<div class="new-page" :style="`min-height: ${layoutMinHeight}px`">
<h1>{{$t('content')}}</h1>
</div>
</template>
<script>
export default {
name: 'NewPage',
inject: ['layoutMinHeight'],
i18n: require('./i18n'),
computed: {
desc() {
return this.$t('description')
}
}
}
</script>
<style scoped lang="less">
@import "index";
</style>
```
然后页面右上角语言项选择 ``English``,你会发现,页面语言切换为英文了。如下:
![newPageUs](../assets/new-page-us.png)
一切就是这么的简单!
:::tip
如果你尝试切换为繁体语言,可能会发现``页面标题``和``面包屑``显示为英文。
这涉及到路由的国际化配置,在章节 [进阶 > 国际化](../advance/i18n.md) 中,我们会对此作详细讲解。
:::

View File

@ -1,144 +0,0 @@
---
title: 路由和菜单
lang: zh-CN
---
# 路由和菜单
路由和菜单起到组织一个应用的关键骨架的作用Vue Antd Admin 使用 [vue-router](https://router.vuejs.org/zh/) 来配置和管理我们的路由和菜单。
## 基本结构
得益于 vue-router 路由配置的可扩展性Vue Antd Admin 通过结合 router 配置文件、基本算法及 [menu.js](https://github.com/iczer/vue-antd-admin/blob/master/src/components/menu/menu.js) 菜单生成工具,搭建了路由和菜单的基本框架,主要涉及以下几个模块/功能:
|功能 |配置 |
|:----------|:-------------------------------|
|*路由管理* |通过 [vue-router](https://router.vuejs.org/zh/) 的路由规则进行管理和配置|
|*菜单生成* |根据路由配置自动生成菜单,菜单项名称、图标和层级等全部可以通过路由配置进行自定义|
|*面包屑* |布局组件 [PageLayout](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageLayout.vue) 提取当前页面路由,并根据当前路由层次关系自动生成面包屑,当然你也可以自定义面包屑|
|*页面标题* |同面包屑,布局组件 [PageLayout](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageLayout.vue) 根据提取到的当前页面的路由名称设置为页面标题,你也同样可以自定义标题|
## 路由
Vue Antd Admin 的路由配置完全遵循 vue-router 的 [routes 配置规则](https://router.vuejs.org/zh/api/#routes)。
另外我们还在 routes 的元数据属性 [meta](https://router.vuejs.org/zh/guide/advanced/meta.html#%E8%B7%AF%E7%94%B1%E5%85%83%E4%BF%A1%E6%81%AF) 中注入了三个属性 icon、invisible 和 page它们将在生成菜单和页头时发挥作用。配置示例如下
```js {8,14}
import Router from 'vue-router'
export default new Router({
routes: [{
path: '/',
name: '首页',
component: TabsView,
meta: {
invisible: true
},
children: [{
path: 'dashboard',
name: 'Dashboard',
meta: {
icon: 'dashboard'
},
component: BlankView,
children: [{
path: 'workplace',
name: '工作台',
component: () => import('@/pages/dashboard/workplace/WorkPlace'),
}, {
path: 'analysis',
name: '分析页',
component: () => import('@/pages/dashboard/analysis/Analysis'),
}]
}]
}]
})
```
完整配置示例,请查看 [router/index.js](https://github.com/iczer/vue-antd-admin/blob/master/src/router/index.js)
## 菜单
Admin 系统的菜单直接通过路由配置生成,路由属性和菜单功能对应关系如下
|路由属性|对应菜单功能|
|:-----------------|:-------|
|**name** |菜单名称 |
|**path** |点击菜单时的跳转链接|
|**meta.icon** |菜单图标,图标使用 ant-design-vue 图标库,对应 [Icon](https://www.antdv.com/components/icon-cn/#API) 组件 的 type 属性|
|**meta.invisible**|是否不将此路由项渲染为菜单项默认false如设置为 true则生成菜单时将忽略此路由|
假如使用上面 [路由](#路由) 文档中的 [配置示例](#路由),将会生成如下菜单:
![menu-demo](../assets/menu-demo.png)
实际项目中,我们是在 AdminLayout 组件创建之前,提取 router 配置中根路由 '/' 下所有子路由配置,
并将此配置传递给 menu.js 插件,从而生成菜单。如下:
```vue {4,12,13,14}
<template>
<a-layout :class="['admin-layout'...]">
...
<side-menu :menuData="menuData".../>
</a-layout>
</template>
<script>
import ...
export default {
name: 'AdminLayout',
...
beforeCreate () {
menuData = this.$router.options.routes.find((item) => item.path === '/').children
}
}
</script>
```
详细代码可查看 [layouts/AdminLayout#L83](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/AdminLayout.vue#L83)。
当然你也可以不使用 router 配置生成菜单,你只需按照配置规则给菜单传递你所定义配置即可。菜单组件配置规则如下:
```jsx {}
[{
name: '菜单标题',
path: '菜单路由',
meta: {
icon: '菜单图标',
invisible: 'boolean, 是否隐藏此菜单项, 默认 false',
},
children: [ //子菜单配置
{
name: '子菜单标题',
path: '子菜单路由',
meta: {
icon: '子菜单图标',
invisible: 'boolean, 是否隐藏此菜单项, 默认 false',
},
}
]
}]
```
更多细节可查看 [components/menu/menu.js](https://github.com/iczer/vue-antd-admin/blob/master/src/components/menu/menu.js)
## 面包屑
面包屑由 [PageHeader](https://github.com/iczer/vue-antd-admin/blob/master/src/components/page/PageHeader.vue) 实现PageLayout 组件会从当前页面路由提取面包屑配置(如未设置,则根据当前路由层次关系生成面包屑)。所以只要页面中使用了 PageLayout 布局或者它的父级组件使用了 PageLayout 布局,面包屑都将自动生成。
当然,如果你想在某个页面自定义面包屑,只需在对应的路由元数据 meta 中定义 page.breadcrumb 属性即可。Vue Antd Admin 将会优先使用路由元数据 meta 中定义的面包屑配置。
比如,想自定义工作台页面面包屑,可以在工作台的 route 配置中如下设置:
```jsx {5,6,7}
{
path: 'workplace',
name: '工作台',
meta: {
page: {
breadcrumb: ['首页', 'Dashboard', '自定义']
}
},
component: () => import('@/pages/dashboard/workplace/WorkPlace'),
}
```
更多细节可查看 [layouts/PageLayout.vue#L55](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageLayout.vue#L55)
## 页面标题
页面标题的实现方式与面包屑基本一致,也是由 PageLayout 组件从当前页面路由提取标题(如未设置,则提取当前路由名称作为标题)。
如果你想自定义页面标题,在页面对应的路由元数据 meta 中定义 page.title 属性即可,如下示例,定义了工作台页面的标题:
```jsx {5,6,7}
{
path: 'workplace',
name: '工作台',
meta: {
page: {
title: '自定义标题'
}
},
component: () => import('@/pages/dashboard/workplace/WorkPlace'),
}
```
更多细节可查看 [layouts/PageLayout.vue#L48](https://github.com/iczer/vue-antd-admin/blob/master/src/layouts/PageLayout.vue#L48)

View File

@ -1,7 +0,0 @@
---
title: 服务端交互
lang: zh-CN
---
# 服务端交互
### 作者还没来得及编辑该页面,如果你感兴趣,可以点击下方链接,帮助作者完善此页

View File

@ -1,502 +0,0 @@
---
title: 主题定制
lang: zh-CN
---
# 主题定制
## 主题颜色
### 主题色
我们内置了一个色盘供您选择
<color color="#fa541c"/>
<color color="#fadb14"/>
<color color="#3eaf7c"/>
<color color="#13c2c2"/>
<color color="#1890ff"/>
<color color="#722ed1"/>
<color color="#eb2f96"/>
如果这不能满足你的需求,你也可以使用任何你喜欢的颜色,只需要在 src/config/config.js 文件中配置你的主题色即可。如:
```js {3}
module.exports = {
theme: {
color: '#13c2c2', //换成任何你喜欢的颜色,支持 hex 色值
mode: 'night'
},
multiPage: true,
animate: {
name: 'roll',
direction: 'default'
}
}
```
当你设置好主题色后系统会根据这个主题色为你生成一系列配套的颜色并应用到vue组件中。
:::tip
你可以在你的样式文件中直接使用 less 变量 ``@theme-color``。
:::
:::warning
主题色目前只支持 ``hex`` 模式的色值。如果设置为 ``rgb`` 或其它模式的色值,可能会导致配套颜色无法生成。
:::
### 功能色
除了主题色,系统还有一些功能性颜色,分别为:成功色、警告色和错误色。默认色值分别为:
|名称|success |warning |error |
|:-:|:--------:|:-------:|:-----:|
|色值|``#52c41a``|``#faad14``|``#f5222d``|
|颜色|<color color="#52c41a"/>|<color color="#faad14"/>|<color color="#f5222d" />|
|less变量|@success-color|@warning-color|@error-color|
你也可以在 src/config/config.js 重新定义这些功能色
```js {5-7}
module.exports = {
theme: {
color: '#13c2c2',
mode: 'night',
success: '#52c41a', //定义成功色,支持 hex 色值
warning: '#faad14', //定义警告色,支持 hex 色值
error: '#f5222d' //定义错误色,支持 hex 色值
},
multiPage: true,
animate: {
name: 'roll',
direction: 'default'
}
}
```
:::tip
想在在你的样式文件中使用以上各功能色,引用各功能色对应的 less 变量即可。
:::
:::warning
功能色目前也只支持 ``hex`` 模式的色值。如果设置为 ``rgb`` 或其它模式的色值,可能会导致配套颜色无法生成。
:::
### 文本色
<table style="text-align: center" >
<tr>
<th>主题模式</th>
<th>标题色</th>
<th>文本色</th>
<th>次级文本色</th>
</tr>
<tr>
<td rowspan="2">light/dark</td>
<td><color color="rgba(0,0,0,0.85)"/></td>
<td><color color="rgba(0,0,0,0.65)"/></td>
<td><color color="rgba(0,0,0,0.45)"/></td>
</tr>
<tr>
<td><code>rgba(0,0,0,0.85)</code></td>
<td><code>rgba(0,0,0,0.65)</code></td>
<td><code>rgba(0,0,0,0.45)</code></td>
</tr>
<tr>
<td rowspan="2">night</td>
<td><color color="rgba(255,255,255,0.85)"/></td>
<td><color color="rgba(255,255,255,0.65)"/></td>
<td><color color="rgba(255,255,255,0.45)"/></td>
</tr>
<tr>
<td><code>rgba(255,255,255,0.85)</code></td>
<td><code>rgba(255,255,255,0.65)</code></td>
<td><code>rgba(255,255,255,0.45)</code></td>
</tr>
<tr>
<td>less变量</td>
<td>@title-color</td>
<td>@text-color</td>
<td>@text-color-second</td>
</tr>
</table>
:::tip
想在在你的样式文件中使用以上文本色,引用各文本色对应的 less 变量即可。
:::
:::warning
目前不支持自定义文本色,因为涉及到主题模式切换时文本色的置换问题。如强行修改,可能会导致主题模式切换时出现样式异常。
如果你的项目不需要主题模式切换,可自行替换以上文本色。
:::
### 背景色
<table style="text-align: center">
<tr>
<th>主题模式</th>
<th>布局背景色</th>
<th>基础背景色</th>
<th>hover背景色</th>
<th>边框颜色</th>
<th>阴影颜色</th>
</tr>
<tr>
<td rowspan="2">light/dark</td>
<td><color color="#f0f2f5"/></td>
<td><color color="#fff"/></td>
<td><color color="rgba(0,0,0,0.025)"/></td>
<td><color color="#f0f0f0"/></td>
<td><color color="rgba(0,0,0,0.15)"/></td>
</tr>
<tr>
<td><code>#f0f2f5</code></td>
<td><code>#fff</code></td>
<td><code>rgba(0,0,0,0.025)</code></td>
<td><code>#f0f0f0</code></td>
<td><code>rgba(0,0,0,0.15)</code></td>
</tr>
<tr>
<td rowspan="2">night</td>
<td><color color="#000"/></td>
<td><color color="#141414"/></td>
<td><color color="rgba(255,255,255,0.025)"/></td>
<td><color color="#303030"/></td>
<td><color color="rgba(255,255,255,0.15)"/></td>
</tr>
<tr>
<td><code>#000</code></td>
<td><code>#141414</code></td>
<td><code>rgba(255,255,255,0.025)</code></td>
<td><code>#303030</code></td>
<td><code>rgba(255,255,255,0.15)</code></td>
</tr>
<tr>
<td>less变量</td>
<td>@layout-bg-color</td>
<td>@base-bg-color</td>
<td>@hover-bg-color</td>
<td>@border-color</td>
<td>@shadow-color</td>
</tr>
</table>
:::tip
想在在你的样式文件中使用以上背景色,引用各背景色对应的 less 变量即可。
:::
:::warning
目前也不支持自定义背景色,因为涉及到主题模式切换时背景色的置换问题。如强行修改,可能会导致主题模式切换时出现样式异常。
如果你的项目不需要主题模式切换,可自行替换以上背景色。
:::
### antd 的色系
除了以上颜色,我们还引入了 ant-design 内置的色系。如下:
<table style="text-align: center">
<tr>
<th>色系</th>
<th>类型</th>
<th>颜色</th>
</tr>
<tr>
<td rowspan="2">blue/拂晓蓝</td>
<td>色盘</td>
<td >
<color-list
:colors="['#e6f7ff', '#bae7ff', '#91d5ff', '#69c0ff', '#40a9ff', '#1890ff', '#096dd9', '#0050b3', '#003a8c', '#002766']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@blue-1</code>
<code>@blue-2</code>
<code>...</code>
<code>@blue-10</code>
</td>
</tr>
<tr>
<td rowspan="2">purple/酱紫</td>
<td>色盘</td>
<td>
<color-list
:colors="['#f9f0ff', '#efdbff', '#d3adf7', '#b37feb', '#9254de', '#722ed1', '#531dab', '#391085', '#22075e', '#120338']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@purple-1</code>
<code>@purple-2</code>
<code>...</code>
<code>@purple-10</code>
</td>
</tr>
<tr>
<td rowspan="2">cyan/明青</td>
<td>色盘</td>
<td>
<color-list
:colors="['#e6fffb', '#b5f5ec', '#87e8de', '#5cdbd3', '#36cfc9', '#13c2c2', '#08979c', '#006d75', '#00474f', '#002329']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@cyan-1</code>
<code>@cyan-2</code>
<code>...</code>
<code>@cyan-10</code>
</td>
</tr>
<tr>
<td rowspan="2">green/极光绿</td>
<td>色盘</td>
<td>
<color-list
:colors="['#f6ffed', '#d9f7be', '#b7eb8f', '#95de64', '#73d13d', '#52c41a', '#389e0d', '#237804', '#135200', '#092b00']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@green-1</code>
<code>@green-2</code>
<code>...</code>
<code>@green-10</code>
</td>
</tr>
<tr>
<td rowspan="2">magenta/法式洋红</td>
<td>色盘</td>
<td>
<color-list
:colors="['#fff0f6', '#ffd6e7', '#ffadd2', '#ff85c0', '#f759ab', '#eb2f96', '#c41d7f', '#9e1068', '#780650', '#520339']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@magenta-1</code>
<code>@magenta-2</code>
<code>...</code>
<code>@magenta-10</code>
</td>
</tr>
<tr>
<td rowspan="2">red/薄暮</td>
<td>色盘</td>
<td>
<color-list
:colors="['#fff1f0', '#ffccc7', '#ffa39e', '#ff7875', '#ff4d4f', '#f5222d', '#cf1322', '#a8071a', '#820014', '#5c0011']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@red-1</code>
<code>@red-2</code>
<code>...</code>
<code>@red-10</code>
</td>
</tr>
<tr>
<td rowspan="2">orange/日暮</td>
<td>色盘</td>
<td>
<color-list
:colors="['#fff7e6', '#ffe7ba', '#ffd591', '#ffc069', '#ffa940', '#fa8c16', '#d46b08', '#ad4e00', '#873800', '#612500']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@orange-1</code>
<code>@orange-2</code>
<code>...</code>
<code>@orange-10</code>
</td>
</tr>
<tr>
<td rowspan="2">yellow/日出</td>
<td>色盘</td>
<td>
<color-list
:colors="['#feffe6', '#ffffb8', '#fffb8f', '#fff566', '#ffec3d', '#fadb14', '#d4b106', '#ad8b00', '#876800', '#614700']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@yellow-1</code>
<code>@yellow-2</code>
<code>...</code>
<code>@yellow-10</code>
</td>
</tr>
<tr>
<td rowspan="2">volcano/火山</td>
<td>色盘</td>
<td>
<color-list
:colors="['#fff2e8', '#ffd8bf', '#ffbb96', '#ff9c6e', '#ff7a45', '#fa541c', '#d4380d', '#ad2102', '#871400', '#610b00']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@volcano-1</code>
<code>@volcano-2</code>
<code>...</code>
<code>@volcano-10</code>
</td>
</tr>
<tr>
<td rowspan="2">geekblue/极客蓝</td>
<td>色盘</td>
<td>
<color-list
:colors="['#f0f5ff', '#d6e4ff', '#adc6ff', '#85a5ff', '#597ef7', '#2f54eb', '#1d39c4', '#10239e', '#061178', '#030852']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@geekblue-1</code>
<code>@geekblue-2</code>
<code>...</code>
<code>@geekblue-10</code>
</td>
</tr>
<tr>
<td rowspan="2">lime/青柠</td>
<td>色盘</td>
<td>
<color-list
:colors="['#fcffe6', '#f4ffb8', '#eaff8f', '#d3f261', '#bae637', '#a0d911', '#7cb305', '#5b8c00', '#3f6600', '#254000']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@lime-1</code>
<code>@lime-2</code>
<code>...</code>
<code>@lime-10</code>
</td>
</tr>
<tr>
<td rowspan="2">gold/金盏花</td>
<td>色盘</td>
<td>
<color-list
:colors="['#fffbe6', '#fff1b8', '#ffe58f', '#ffd666', '#ffc53d', '#faad14', '#d48806', '#ad6800', '#874d00', '#613400']"
/>
</td>
</tr>
<tr>
<td>less变量</td>
<td>
<code>@gold-1</code>
<code>@gold-2</code>
<code>...</code>
<code>@gold-10</code>
</td>
</tr>
</table>
以上色系对应的less变量均可以在你的样式代码中直接使用。
:::tip
我们建议在开发中使用 `less变量` 而不是直接使用 `颜色值` 来设置颜色。这样做对主题色和主题模式切换很有帮助。
:::
## 主题模式
Vue Antd Admin 有三种主题模式,分别为:`light/亮色菜单模式``dark/暗色菜单模式``night/黑夜模式`
light / 亮色菜单模式:
![light](../assets/mode-light.png)
dark / 暗色菜单模式:
![dark](../assets/mode-dark.png)
night / 黑夜模式:
![night](../assets/mode-night.png)
你可以在这三种模式之间随意切换,也可以在 src/config/config.js 中设置默认的主题模式。
```js {4}
module.exports = {
theme: {
color: '#13c2c2',
mode: 'night' //设置你的默认主题模式,可选 light、dark 和 night
},
multiPage: true,
animate: {
name: 'roll',
direction: 'default'
}
}
```
## 导航布局
Vue Antd Admin 有两种导航布局,`side/侧边导航``head/顶部导航`
默认为侧边导航,你可以在 src/config/config.js 中修改导航布局
```js {6}
module.exports = {
theme: {
color: '#13c2c2',
mode: 'night'
},
layout: 'side', //设置你的默认导航布局,有 side 和 head 可选
multiPage: true,
animate: {
name: 'roll',
direction: 'default'
}
}
```
## 动画
Vue Antd Admin 内置了 [animate.css](https://animate.style) 动画库,在页面切换时会应用动画效果。你可以在 src/config/config.js 中配置动画效果或者禁用动画。
```js {7-11}
module.exports = {
theme: {
color: '#13c2c2',
mode: 'night'
},
multiPage: true,
animate: {
disabled: false, //禁用动画true:禁用false:启用
name: 'roll', //动画效果,支持的动画效果可参考 src/config/default/animate.config.js
direction: 'default' //动画方向,切换页面时动画的方向,参考 src/config/default/animate.config.js
}
}
```
支持的动画特效种类,可以参考 src/config/default/animate.config.js 文件。
## 其它
### 色弱模式
对于有视觉障碍的群体,我们提供了色弱模式,你可以通过配置 src/config/config.js 启用色弱模式
```js {7}
module.exports = {
theme: {
color: '#13c2c2',
mode: 'night'
},
multiPage: true,
weekMode: false, //色弱模式true:开启false:不开启
animate: {
name: 'roll',
direction: 'default'
}
}
```
### 多页签
在 src/config/config.js 设置 multiPage 来启用或关闭多页签模式
```js {7}
module.exports = {
theme: {
color: '#13c2c2',
mode: 'night'
},
multiPage: true, //多页签模式true:开启false:不开启
animate: {
name: 'roll',
direction: 'default'
}
}
```
完整的系统设置参考 src/config/default/setting.config.js
:::tip
以上所有主题设置项,均已映射到 vuex/setting 模块的 state 中,你可以通过提交 setting/mutations 实时修改设置项。
如何使用 [mutations](https://vuex.vuejs.org/zh/guide/mutations.html)
:::

View File

@ -1,5 +0,0 @@
---
title: 其它
lang: zh-CN
---
# 其它

View File

@ -1,8 +0,0 @@
---
title: 社区
lang: zh-CN
---
# 社区
## 交流学习
### QQ群610090280

View File

@ -1,5 +0,0 @@
---
title: 更新日志
lang: zh-CN
---
# 更新日志

View File

@ -1,5 +0,0 @@
---
title: 开始
lang: zh-CN
---
## 开始

View File

@ -1,22 +0,0 @@
---
title: 常见问题
lang: zh-CN
---
# 常见问题
### 为什么不是 Ant Design Pro Vue
[Ant Design Pro Vue](https://github.com/vueComponent/ant-design-vue-pro) 是 [Ant Design Pro](https://github.com/ant-design/ant-design-pro) 的 Vue 版本,其中项目结构、组件、
布局和使用方法等基本与 Ant Design Pro 的 react 版本保持一致。如果你比较熟悉 react 版,或者你已经在使用它,这确实是一个不错的选择。
[Vue Antd Admin](https://github.com/iczer/vue-antd-admin) 同样实现了 Ant Design Pro 的所有功能。与此同时,我们还根据 Vue 的特性,对 Ant Design Pro 的一些组件和布局作出了相应的修改及优化,同时不影响保持与 Ant Design Pro 的一致。
另外,我们还在添加一些 Ant Design Pro 没有的功能,比如全局动画、多页签模式等。
如果你想使用 Ant Design Pro但又觉得它缺乏一些你想要的功能不妨看看 [Vue Antd Admin](https://github.com/iczer/vue-antd-admin),我们会认真考虑每个用户的需求。
因此,如果你有一些不错的想法和建议,欢迎随时和我们交流,很可能你的想法就在我们下一个版本中实现。
### 如何使用 Vue Antd Admin
请阅读文档 [开始使用](./use.md)。有任何疑问,欢迎在 github 上给我们提交 [issue](https://github.com/iczer/vue-antd-admin/issues/new)。
### 是否支持国际化
Vue Antd Admin 引入了 vue-i18n 支持。因此你可以使用 vue-i18n 的特性对项目做国际化修改,详细请查看 [国际化](../advance/i18n.md)

View File

@ -1,48 +0,0 @@
---
title: 使用
lang: zh-CN
---
# 使用
## 准备
你的本地环境需要安装 yarn、node 和 git。我们的技术栈基于 ES2015+、Vue、Antd提前学习这些知识会非常有帮助。
## 安装
克隆本项目到本地
```bash
$ git clone https://github.com/iczer/vue-antd-admin.git
```
安装依赖
```bash
$ yarn install
```
## 目录结构
我们已经为你生成了一个完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。
```bash
├── docs # 使用文档
├── public
│ └── favicon.png # favicon
│ └── index.html # 入口 HTML
├── src
│ ├── assets # 本地静态资源
│ ├── components # 业务通用组件
│ ├── config # 系统配置
│ ├── layouts # 通用布局
│ ├── mock # 本地 mock 数据
│ ├── pages # 页面组件和通用模板
│ ├── plugins # vue 插件
│ ├── router # 路由配置
│ ├── store # vuex 状态管理配置
│ ├── theme # 主题相关
│ ├── utils # js 工具
│ └── App.vue # 应用入口组件
│ └── main.js # 应用入口js
├── package.json # package.json
├── README.md # README.md
└── vue.config.js # vue 配置文件
```
## 本地开发
启动服务
```bash
$ yarn serve
```
启动成功后,会看到一个本地预览地址,通常是 http://localhost:8080 。接下来就可以修改代码,并实时预览修改结果啦!

View File

@ -9,9 +9,6 @@
"lint": "vue-cli-service lint",
"predeploy": "yarn build",
"deploy": "gh-pages -d dist -b pages -r https://gitee.com/iczer/vue-antd-admin.git",
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs",
"docs:deploy": "vuepress build docs && gh-pages -d docs/.vuepress/dist"
},
"dependencies": {
"@antv/data-set": "^0.11.4",

View File

@ -1,6 +1,6 @@
<template>
<div class="page-layout">
<page-header :breadcrumb="breadcrumb" :title="pageTitle" :logo="logo" :avatar="avatar">
<page-header :style="`margin-top: ${multiPage ? 0 : -24}px`" :breadcrumb="breadcrumb" :title="pageTitle" :logo="logo" :avatar="avatar">
<slot name="action" slot="action"></slot>
<slot slot="content" name="headerContent"></slot>
<div slot="content" v-if="!this.$slots.headerContent && desc">
@ -40,7 +40,7 @@ export default {
this.page = this.$route.meta.page
},
computed: {
...mapState('setting', ['layout']),
...mapState('setting', ['layout', 'multiPage']),
pageTitle() {
let pageTitle = this.page && this.page.title
return this.title || this.$t(pageTitle) || this.routeName
@ -79,7 +79,7 @@ export default {
<style lang="less">
.page-header{
margin: -24px -24px 0;
margin: 0 -24px 0;
}
.link{
/*margin-top: 16px;*/

View File

@ -15,7 +15,7 @@
<span slot="tab" :pagekey="page.fullPath">{{pageName(page.path)}}</span>
</a-tab-pane>
</a-tabs>
<div class="tabs-view-content">
<div class="tabs-view-content" :style="`margin-top: ${multiPage ? -24 : 0}px`">
<page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction">
<keep-alive :exclude="dustbins" v-if="multiPage">
<router-view />

View File

@ -1,32 +0,0 @@
import {users, groups} from './index'
const events = [
{
type: 0,
event: '八月迭代'
},
{
type: 1,
event: '留言'
},
{
type: 2,
event: '项目进展'
}
]
const activities = users.map((user, index) => {
return {
user: Object.assign({}, user, {group: groups[user.groupId]}),
activity: events[index % events.length],
template: ''
}
})
const templates = [
(user, activity) => { return `${user.name} 在 <a >${user.group}</a> 新建项目 <a>${activity.event}</a>` },
(user, activity) => { return `${user.name} 在 <a >${user.group}</a> 发布了 <a>${activity.event}</a>` },
(user, activity) => { return `${user.name} 将 <a >${activity.event}</a> 更新至已发布状态` }
]
export {activities, templates}

View File

@ -27,63 +27,6 @@ const positions = [
}
]
const sayings = [
'那是一种内在的东西,他们到达不了,也无法触及的',
'希望是一个好东西,也许是最好的,好东西是不会消亡的',
'城镇中有那么多的酒馆,她却偏偏走进了我的酒馆',
'那时候我只会想自己想要什么,从不想自己拥有什么'
]
const logos = [
'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png',
'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png',
'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png',
'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png',
'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png'
]
const admins = ['ICZER', 'JACK', 'LUIS', 'DAVID']
const groups = ['高逼格设计天团', '中二少女团', '科学搬砖组', '骗你学计算机', '程序员日常']
const users = [
{
name: '曲丽丽',
avatar: avatars[0],
groupId: 0
},
{
name: '付晓晓',
avatar: avatars[1],
groupId: 0
},
{
name: '林东东',
avatar: avatars[2],
groupId: 1
},
{
name: '周星星',
avatar: avatars[3],
groupId: 2
},
{
name: '朱偏右',
avatar: avatars[4],
groupId: 3
},
{
name: '勒个',
avatar: avatars[5],
groupId: 4
}
]
const teams = groups.map((item, index) => {
return {
name: item,
avatar: avatars[index]
}
})
export {logos, sayings, positions, avatars, admins, groups, users, teams}
export {positions, avatars, admins}

View File

@ -1,118 +0,0 @@
const operation1 = [
{
key: 'op1',
type: '订购关系生效',
name: '曲丽丽',
status: 'agree',
updatedAt: '2017-10-03 19:23:12',
memo: '-'
},
{
key: 'op2',
type: '财务复审',
name: '付小小',
status: 'reject',
updatedAt: '2017-10-03 19:23:12',
memo: '不通过原因'
},
{
key: 'op3',
type: '部门初审',
name: '周毛毛',
status: 'agree',
updatedAt: '2017-10-03 19:23:12',
memo: '-'
},
{
key: 'op4',
type: '提交订单',
name: '林东东',
status: 'agree',
updatedAt: '2017-10-03 19:23:12',
memo: '很棒'
},
{
key: 'op5',
type: '创建订单',
name: '汗牙牙',
status: 'agree',
updatedAt: '2017-10-03 19:23:12',
memo: '-'
}
]
const operation2 = [
{
key: 'op2',
type: '财务复审',
name: '付小小',
status: 'reject',
updatedAt: '2017-10-03 19:23:12',
memo: '不通过原因'
},
{
key: 'op3',
type: '部门初审',
name: '周毛毛',
status: 'agree',
updatedAt: '2017-10-03 19:23:12',
memo: '-'
},
{
key: 'op4',
type: '提交订单',
name: '林东东',
status: 'agree',
updatedAt: '2017-10-03 19:23:12',
memo: '很棒'
}
]
const operation3 = [
{
key: 'op2',
type: '财务复审',
name: '付小小',
status: 'reject',
updatedAt: '2017-10-03 19:23:12',
memo: '不通过原因'
},
{
key: 'op3',
type: '部门初审',
name: '周毛毛',
status: 'agree',
updatedAt: '2017-10-03 19:23:12',
memo: '-'
}
]
const operationColumns = [
{
title: '操作类型',
dataIndex: 'type',
key: 'type'
},
{
title: '操作人',
dataIndex: 'name',
key: 'name'
},
{
title: '执行结果',
dataIndex: 'status',
key: 'status'
},
{
title: '操作时间',
dataIndex: 'updatedAt',
key: 'updatedAt'
},
{
title: '备注',
dataIndex: 'memo',
key: 'memo'
}
]
export {operation1, operation2, operation3, operationColumns}

View File

@ -1,5 +1,5 @@
import Mock from 'mockjs'
import {logos, sayings, positions, avatars, admins} from '../common'
import {positions, avatars, admins} from '../common'
const Random = Mock.Random
@ -27,36 +27,10 @@ const timeList = [
}
]
const welcomeMessages = [
{
CN: '休息一会儿吧',
HK: '休息一會兒吧',
US: 'you may need a break',
},
{
CN: '准备吃什么呢',
HK: '準備吃什麼呢',
US: 'what are you going to eat',
},
{
CN: '要不要打一把 DOTA',
HK: '要不要打一把 DOTA',
US: 'how about a game of DOTA',
},
{
CN: '我猜你可能累了',
HK: '我猜你可能累了',
US: 'i guess you might be tired',
}
]
Random.extend({
admin () {
return this.pick(admins)
},
welcome () {
return this.pick(welcomeMessages)
},
timeFix () {
const time = new Date()
const hour = time.getHours()
@ -68,11 +42,5 @@ Random.extend({
},
position () {
return this.pick(positions)
},
saying () {
return this.pick(sayings)
},
logo () {
return this.pick(logos)
}
})

View File

@ -1,8 +1,5 @@
import Mock from 'mockjs'
import '@/mock/user/current'
import '@/mock/project'
import '@/mock/user/login'
import '@/mock/workplace'
// 设置全局延时
Mock.setup({

View File

@ -1,15 +0,0 @@
import Mock from 'mockjs'
import '@/mock/extend'
const projectArr = Mock.mock({
'list|6': [
{
logo: '@LOGO',
desc: '@SAYING'
}
]
}).list
Mock.mock('/project', 'get', () => {
return projectArr
})

View File

@ -1,11 +0,0 @@
import Mock from 'mockjs'
import '@/mock/extend'
const welcome = Mock.mock({
timeFix: '@TIMEFIX',
message: '@WELCOME'
})
Mock.mock('/user/welcome', 'get', () => {
return welcome
})

View File

@ -1,15 +0,0 @@
import Mock from 'mockjs'
import {activities, templates} from '../common/activityData'
import {teams} from '../../mock/common'
activities.forEach(item => {
item.template = templates[item.activity.type](item.user, item.activity)
})
Mock.mock('/work/activity', 'get', () => {
return activities
})
Mock.mock('/work/team', 'get', () => {
return teams
})

View File

@ -1,65 +0,0 @@
<template>
<div style="text-align: center; margin-top: 48px">
<color-checkbox-group :defaultValues="['1', '3', '4']" @change="changeColor" :multiple="true" style="display: inline-block">
<color-checkbox color="rgb(245, 34, 45)" value="1" />
<color-checkbox color="rgb(250, 84, 28)" value="2" />
<color-checkbox color="rgb(250, 173, 20)" value="3" />
<color-checkbox color="rgb(19, 194, 194)" value="4" />
<color-checkbox color="rgb(82, 196, 26)" value="5" />
<color-checkbox color="rgb(24, 144, 255)" value="6" />
<color-checkbox color="rgb(47, 84, 235)" value="7" />
<color-checkbox color="rgb(114, 46, 209)" value="8" />
<color-checkbox color="rgb(256, 0, 0)" value="9" />
<color-checkbox color="rgb(0, 256, 0)" value="10" />
<color-checkbox color="rgb(0, 0, 256)" value="11" />
<color-checkbox color="rgb(256, 256, 0)" value="12" />
</color-checkbox-group>
<div></div>
<div class="view-color" :style="{backgroundColor: color}"/>
</div>
</template>
<script>
import ColorCheckbox from '../../components/checkbox/ColorCheckbox'
const ColorCheckboxGroup = ColorCheckbox.Group
export default {
name: 'Palette',
data () {
return {
color: 'rgb(245, 34, 45)'
}
},
components: {ColorCheckbox, ColorCheckboxGroup},
methods: {
changeColor (values, colors) {
this.color = this.calculateColor(colors)
},
calculateColor (colors) {
let red = 0
let green = 0
let blue = 0
let values
colors.forEach(color => {
values = color.split('(')[1].split(')')[0].split(',')
red = Math.max(red, parseInt(values[0]))
green += Math.max(green, parseInt(values[1]))
blue += Math.max(blue, parseInt(values[2]))
})
return 'rgb(' + red + ',' + green + ',' + blue + ')'
}
}
}
</script>
<style lang="less" scoped>
.view-color{
margin-top: 48px;
display: inline-block;
height: 96px;
width: 96px;
border-radius: 48px;
border: 1px dashed gray;
}
</style>

View File

@ -1,50 +0,0 @@
<template>
<div style="display: flex">
<task-group class="task-group" title="ToDo" group="task">
<task-item :key="index" v-for="(item, index) in todoList" :content="item" />
</task-group>
<task-group class="task-group" title="In Progress" group="task">
<task-item :key="index" v-for="(item, index) in inproList" :content="item" />
</task-group>
<task-group class="task-group" title="Done" group="task">
<task-item :key="index" v-for="(item, index) in doneList" :content="item" />
</task-group>
</div>
</template>
<script>
import TaskGroup from '../../components/task/TaskGroup'
import TaskItem from '../../components/task/TaskItem'
const todoList = ['任务一', '任务二', '任务三', '任务四', '任务五', '任务六']
const inproList = ['任务七', '任务八', '任务九', '任务十', '任务十一', '任务十二']
const doneList = ['任务十三', '任务十四', '任务十五', '任务十六', '任务十七', '任务十八']
export default {
name: 'TaskCard',
components: {TaskItem, TaskGroup},
data () {
return {
todoList,
inproList,
doneList
}
}
}
</script>
<style lang="less" scoped>
.task-group{
margin: 0 48px;
}
.dragable-ghost{
border: 1px dashed red;
opacity: 1;
}
.dragable-chose{
border: 1px dashed red;
opacity: 0.8;
}
.dragable-drag{
border: 1px dashed red;
opacity: 1;
}
</style>

View File

@ -1,163 +0,0 @@
<template>
<div class="analysis">
<a-row :gutter="[24, 24]">
<a-col :sm="24" :md="12" :xl="6">
<chart-card :loading="loading" :title="$t('totalSales')" total="¥ 189,345">
<a-tooltip :title="$t('introduce')" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<trend style="margin-right: 16px" :term="$t('wow')" :percent="12" :is-increase="true" :scale="0" />
<trend :term="$t('dod')" :target="100" :value="89" :scale="0" />
</div>
<div slot="footer">{{$ta('daily|sales', 'p')}}<span> 234.56</span></div>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6">
<chart-card :loading="loading" :title="$t('visits')" total="¥ 189,345">
<a-tooltip :title="$t('introduce')" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area />
</div>
<div slot="footer">{{$ta('daily|visits', 'p')}}<span> 123,4</span></div>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6">
<chart-card :loading="loading" :title="$t('payments')" total="¥ 189,345">
<a-tooltip :title="$t('introduce')" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar />
</div>
<div slot="footer">{{$t('conversion')}} <span>60%</span></div>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6">
<chart-card :loading="loading" :title="$t('operating')" total="73%">
<a-tooltip :title="$t('introduce')" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-progress target="90" percent="78" color="#13C2C2" height="8px"/>
</div>
<div slot="footer" style="white-space: nowrap;overflow: hidden">
<trend style="margin-right: 16px" :term="$t('wow')" :percent="12" :is-increase="true" :scale="0" />
<trend :term="$t('dod')" :target="100" :value="89" :scale="0" />
</div>
</chart-card>
</a-col>
</a-row>
<a-card :loading="loading" style="margin-top: 24px" :bordered="false" :body-style="{padding: '24px'}">
<div class="salesCard">
<a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<div class="extra-wrap" slot="tabBarExtraContent">
<div class="extra-item">
<a>{{$t('day')}}</a>
<a>{{$t('week')}}</a>
<a>{{$t('month')}}</a>
<a>{{$t('year')}}</a>
</div>
<a-range-picker :style="{width: '256px'}"></a-range-picker>
</div>
<a-tab-pane loading="true" :tab="$t('sales')" key="1">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar :title="$ta('stores|sales|trend', 'p')" />
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<ranking-list :title="$ta('stores|sales|ranking', 'p')" :list="rankList"/>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane :tab="$t('visits')" key="2"><a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar :title="$ta('visits|trend', 'p')" />
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<ranking-list :title="$ta('stores|visits|ranking', 'p')" :list="rankList"/>
</a-col>
</a-row></a-tab-pane>
</a-tabs>
</div>
</a-card>
<a-row style="margin: 0 -12px">
<a-col style="padding: 0 12px" :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
<a-card :loading="loading" :bordered="false" style="margin-top: 24px" :title="$t('search')">
<hot-search />
</a-card>
</a-col>
<a-col style="padding: 0 12px" :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
<a-card :loading="loading" :bordered="false" style="margin-top: 24px;" :title="$t('proportion')">
<sales-data />
<a-radio-group slot="extra" style="margin: -12px 0">
<a-radio-button value="a">{{$t('all')}}</a-radio-button>
<a-radio-button value="b">{{$t('online')}}</a-radio-button>
<a-radio-button value="c">{{$t('stores')}}</a-radio-button>
</a-radio-group>
</a-card>
</a-col>
</a-row>
</div>
</template>
<script>
import ChartCard from '../../../components/card/ChartCard'
import MiniArea from '../../../components/chart/MiniArea'
import MiniBar from '../../../components/chart/MiniBar'
import MiniProgress from '../../../components/chart/MiniProgress'
import Bar from '../../../components/chart/Bar'
import RankingList from '../../../components/chart/RankingList'
import HotSearch from './HotSearch'
import SalesData from './SalesData'
import Trend from '../../../components/chart/Trend'
const rankList = []
for (let i = 0; i < 8; i++) {
rankList.push({
name: '桃源村' + i + '号店',
total: 1234.56 - i * 100
})
}
export default {
name: 'Analysis',
i18n: require('./i18n'),
data () {
return {
rankList,
loading: true
}
},
created() {
setTimeout(() => this.loading = !this.loading, 1000)
},
components: {Trend, SalesData, HotSearch, RankingList, Bar, MiniProgress, MiniBar, MiniArea, ChartCard}
}
</script>
<style lang="less" scoped>
.extra-wrap{
.extra-item{
display: inline-block;
margin-right: 24px;
a:not(:first-child){
margin-left: 24px;
}
}
}
@media screen and (max-width: 992px){
.extra-wrap .extra-item{
display: none;
}
}
@media screen and (max-width: 576px){
.extra-wrap{
display: none;
}
}
</style>

View File

@ -1,142 +0,0 @@
<template>
<div class="hot-search">
<a-row style="margin: 0 -34px">
<a-col style="padding: 0 34px; margin-bottom: 24px" :sm="12" :xs="24">
<div class="num-info">
<span class="title">
{{$t('search')}}
<a-tooltip :title="$t('introduce')">
<a-icon type="info-circle" style="font-size: 14px; margin-left: 8px" />
</a-tooltip>
</span>
<div class="value">
<span class="total">12321</span>
<span class="subtotal">71.2<a-icon type="caret-up" /></span>
</div>
</div>
<mini-area style="height: 45px" />
</a-col>
<a-col style="padding: 0 34px; margin-bottom: 24px" :sm="12" :xs="24">
<div class="num-info">
<span class="title">
{{$t('capita')}}
<a-tooltip :title="$t('introduce')">
<a-icon type="info-circle" style="font-size: 14px; margin-left: 8px" />
</a-tooltip>
</span>
<div class="value">
<span class="total">2.7</span>
<span class="subtotal">71.2<a-icon type="caret-down" /></span>
</div>
</div>
<mini-area style="height: 45px" />
</a-col>
</a-row>
<a-table
:dataSource="searchData"
:columns="tableColumns"
:pagination="{style: { marginBottom: 0 }, pageSize: 5}"
size="small"
rowKey="index"
>
<a href="#/" slot="keyword" slot-scope="text">{{text}}</a>
<span slot="rang" slot-scope="text">{{text}} %<a-icon type="caret-up" /> </span>
</a-table>
</div>
</template>
<script>
import MiniArea from '../../../components/chart/MiniArea'
const searchData = []
for (let i = 0; i < 50; i++) {
searchData.push({
index: i + 1,
keyword: '关键词-' + i,
count: Math.floor(Math.random() * 1000),
range: Math.floor(Math.random() * 100),
status: Math.floor((Math.random() * 10) % 2)
})
}
const columns = [
{
dataIndex: 'index',
key: 'rank'
},
{
dataIndex: 'keyword',
key: 'keyword',
scopedSlots: {customRender: 'keyword'}
},
{
dataIndex: 'count',
key: 'users',
sorter: (a, b) => a.count - b.count
},
{
title: '周涨幅',
dataIndex: 'range',
key: 'range',
scopedSlots: {customRender: 'rang'}
}
]
export default {
name: 'HotSearch',
components: {MiniArea},
i18n: require('./i18n-search'),
data () {
return {
searchData,
columns
}
},
computed: {
tableColumns() {
let columns = this.columns
return columns.map(item => {
item.title = this.$t(item.key)
return item
})
}
}
}
</script>
<style lang="less" scoped>
.num-info{
.title{
color: @text-color-second;
font-size: 14px;
height: 22px;
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
white-space: nowrap;
}
.value{
.total{
color: @title-color;
display: inline-block;
line-height: 32px;
height: 32px;
font-size: 24px;
margin-right: 32px;
}
.subtotal{
color: @text-color-second;
font-size: 16px;
vertical-align: top;
margin-right: 0;
i{
font-size: 12px;
color: red;
transform: scale(.82);
margin-left: 4px;
}
}
}
}
</style>

View File

@ -1,61 +0,0 @@
<template>
<div style="">
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
<v-tooltip :showTitle="false" dataKey="item*percent" />
<v-axis />
<v-legend dataKey="item" position="right" :offsetX="-140"/>
<v-pie position="percent" color="item" :vStyle="pieStyle" :label="labelConfig" />
<v-coord type="theta" :radius="0.75" :innerRadius="0.6" />
</v-chart>
</div>
</template>
<script>
const DataSet = require('@antv/data-set')
const sourceData = [
{ item: '事例一', count: 40 },
{ item: '事例二', count: 21 },
{ item: '事例三', count: 17 },
{ item: '事例四', count: 13 },
{ item: '事例五', count: 9 }
]
const scale = [{
dataKey: 'percent',
min: 0,
formatter: '.0%'
}]
const dv = new DataSet.View().source(sourceData)
dv.transform({
type: 'percent',
field: 'count',
dimension: 'item',
as: 'percent'
})
const data = dv.rows
export default {
name: 'SalesData',
data () {
return {
data,
scale,
height: 385,
pieStyle: {
stroke: '#fff',
lineWidth: 1
},
labelConfig: ['percent', {
formatter: (val, item) => {
return item.point.item + ': ' + val
}
}]
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,31 +0,0 @@
module.exports = {
messages: {
CN: {
search: '搜索用户数',
capita: '人均搜索次数',
rank: '排名',
keyword: '搜索关键词',
count: '用户数',
range: '周涨幅',
introduce: '指标说明'
},
HK: {
search: '搜索用戶數',
capita: '人均搜索次數',
rank: '排名',
keyword: '搜索關鍵詞',
count: '用戶數',
range: '周漲幅',
introduce: '指標說明'
},
US: {
search: 'Search Users',
capita: 'Per Capita Search',
rank: 'Rank',
keyword: 'Keyword',
users: 'Users',
range: 'Weekly Range',
introduce: 'Introduce'
},
}
}

View File

@ -1,73 +0,0 @@
module.exports = {
messages: {
CN: {
introduce: '指标说明',
totalSales: '总销售额',
visits: '访问量',
payments: '支付笔数',
operating: '运营活动效果',
wow: '同周比',
dod: '日环比',
sales: '销售额',
daily: '日均',
day: '今日',
week: '本周',
month: '本月',
year: '本年',
search: '热门搜索',
proportion: '销售额占比',
conversion: '转化率',
trend: '趋势',
ranking: '排行榜',
all: '全渠道',
online: '线上',
stores: '门店',
},
HK: {
introduce: '指標說明',
totalSales: '總銷售額',
visits: '訪問量',
payments: '支付筆數',
operating: '運營活動效果',
wow: '通周比',
dod: '日環比',
sales: '銷售額',
daily: '日均',
day: '今日',
week: '本週',
month: '本月',
year: '本年',
search: '熱門搜索',
proportion: '銷售額佔比',
conversion: '轉化率',
trend: '趨勢',
ranking: '排行榜',
all: '全渠道',
online: '線上',
stores: '門店',
},
US: {
introduce: 'Introduce',
totalSales: 'Total Sales',
visits: 'Visits',
payments: 'Payments',
operating: 'Operational Effect',
wow: 'WoW Change',
dod: 'DoD Change',
sales: 'Sales',
daily: 'Daily',
day: 'All Day',
week: 'All Week',
month: 'All Month',
year: 'All Year',
search: 'Hot Search',
proportion: 'The Proportion Of Sales',
conversion: 'Conversion Rate',
trend: 'Trend',
ranking: 'Ranking',
all: 'All',
online: 'Online',
stores: 'Stores',
}
}
}

View File

@ -1,122 +0,0 @@
<template>
<page-layout :avatar="currUser.avatar">
<div slot="headerContent">
<div class="title">{{welcome.timeFix[lang]}}{{currUser.name}}{{welcome.message[lang]}}</div>
<div>{{currUser.position[lang]}}</div>
</div>
<template slot="extra">
<head-info class="split-right" :title="$t('project')" content="56"/>
<head-info class="split-right" :title="$t('ranking')" content="8/24"/>
<head-info class="split-right" :title="$t('visit')" content="2,223"/>
</template>
<template>
<a-row style="margin: 0 -12px">
<a-col style="padding: 0 12px" :xl="16" :lg="24" :md="24" :sm="24" :xs="24">
<a-card class="project-list" :loading="loading" style="margin-bottom: 24px;" :bordered="false" :title="$t('progress')" :body-style="{padding: 0}">
<a slot="extra">{{$t('all')}}</a>
<div>
<a-card-grid :key="i" v-for="(item, i) in projects">
<a-card :bordered="false" :body-style="{padding: 0}">
<a-card-meta :description="item.desc">
<div slot="title" class="card-title">
<a-avatar size="small" :src="item.logo" />
<span>Alipay</span>
</div>
</a-card-meta>
<div class="project-item">
<a class="group" href="/#/">科学搬砖组</a>
<span class="datetime">9小时前</span>
</div>
</a-card>
</a-card-grid>
</div>
</a-card>
<a-card :loading="loading" :title="$t('dynamic')" :bordered="false">
<a-list>
<a-list-item :key="index" v-for="(item, index) in activities">
<a-list-item-meta>
<a-avatar slot="avatar" :src="item.user.avatar" />
<div slot="title" v-html="item.template" />
<div slot="description">9小时前</div>
</a-list-item-meta>
</a-list-item>
</a-list>
</a-card>
</a-col>
<a-col style="padding: 0 12px" :xl="8" :lg="24" :md="24" :sm="24" :xs="24">
<a-card :title="$t('access')" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a>操作一</a>
<a>操作二</a>
<a>操作三</a>
<a>操作四</a>
<a>操作五</a>
<a>操作六</a>
<a-button size="small" type="primary" ghost icon="plus">{{$t('add')}}</a-button>
</div>
</a-card>
<a-card :loading="loading" :title="`XX ${$t('degree')}`" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div style="min-height: 400px;">
<radar />
</div>
</a-card>
<a-card :loading="loading" :title="$t('team')" :bordered="false">
<div class="members">
<a-row>
<a-col :span="12" v-for="(item, index) in teams" :key="index">
<a>
<a-avatar size="small" :src="item.avatar" />
<span class="member">{{item.name}}</span>
</a>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</template>
</page-layout>
</template>
<script>
import PageLayout from '@/layouts/PageLayout'
import HeadInfo from '@/components/tool/HeadInfo'
import Radar from '@/components/chart/Radar'
import {mapState} from 'vuex'
import {request, METHOD} from '@/utils/request'
export default {
name: 'WorkPlace',
components: {Radar, HeadInfo, PageLayout},
i18n: require('./i18n'),
data () {
return {
projects: [],
loading: true,
activities: [],
teams: [],
welcome: {
timeFix: '',
message: ''
}
}
},
computed: {
...mapState('account', {currUser: 'user'}),
...mapState('setting', ['lang'])
},
created() {
request('/user/welcome', METHOD.GET).then(res => this.welcome = res.data)
request('/work/activity', METHOD.GET).then(res => this.activities = res.data)
request('/work/team', METHOD.GET).then(res => this.teams = res.data)
request('/project', METHOD.GET).then(res => {
this.projects = res.data
this.loading = false
})
}
}
</script>
<style lang="less">
@import "index";
</style>

View File

@ -1,40 +0,0 @@
module.exports = {
messages: {
CN: {
project: '项目数',
ranking: '团队排名',
visit: '项目访问',
progress: '进行中的项目',
all: '全部项目',
access: '快速开始/便捷导航',
dynamic: '动态',
degree: '指数',
team: '团队',
add: '添加'
},
HK: {
project: '項目數',
ranking: '團隊排名',
visit: '項目訪問',
progress: '進行中的項目',
all: '全部項目',
access: '快速開始/便捷導航',
dynamic: '動態',
degree: '指數',
team: '團隊',
add: '添加'
},
US: {
project: 'Project',
ranking: 'Ranking',
visit: 'Visit',
progress: 'Projects in progress',
all: 'All projects',
access: 'Quick start / Easy navigation',
dynamic: 'Dynamic',
degree: 'degree',
team: 'Team',
add: 'Add'
},
}
}

View File

@ -1,59 +0,0 @@
.project-list {
.card-title {
span{
vertical-align: middle;
&:last-child{
margin-left: 12px;
}
}
}
.project-item {
display: flex;
justify-content: space-between;
margin-top: 8px;
overflow: hidden;
font-size: 12px;
color: inherit;
.group{
color: @text-color;
flex: 1 1 0;
&:hover {
color: @primary-color;
}
}
.datetime {
color: @text-color-second;
flex: 0 0 auto;
}
}
.ant-card-meta-description {
height: 44px;
line-height: 22px;
overflow: hidden;
}
}
.item-group{
padding: 20px 0 8px 24px;
font-size: 0;
a{
color: inherit;
display: inline-block;
font-size: 14px;
margin-bottom: 13px;
width: 25%;
}
}
.members {
a {
display: block;
margin: 12px 0;
color: @text-color;
&:hover {
color: @primary-color;
}
.member {
vertical-align: middle;
margin-left: 12px;
}
}
}

26
src/pages/demo/Demo.vue Normal file
View File

@ -0,0 +1,26 @@
<template>
<div class="new-page" :style="`min-height: ${layoutMinHeight}px`">
<h1>{{$t('content')}}</h1>
</div>
</template>
<script>
export default {
name: 'Demo',
inject: ['layoutMinHeight'],
i18n: require('./i18n'),
data() {
return {
}
},
computed: {
desc() {
return this.$t('description')
}
}
}
</script>
<style scoped lang="less">
@import "index";
</style>

16
src/pages/demo/i18n.js Normal file
View File

@ -0,0 +1,16 @@
module.exports = {
messages: {
CN: {
content: '演示页面',
description: '这是一个演示页面'
},
HK: {
content: '演示頁面',
description: '這是一個演示頁面'
},
US: {
content: 'Demo Page',
description: 'This is a demo page'
}
}
}

2
src/pages/demo/index.js Normal file
View File

@ -0,0 +1,2 @@
import Demo from './Demo.vue'
export default Demo

10
src/pages/demo/index.less Normal file
View File

@ -0,0 +1,10 @@
.new-page{
height: 100%;
background-color: @base-bg-color;
text-align: center;
padding: 200px 0 0 0;
//margin-top: -24px;
h1{
font-size: 48px;
}
}

View File

@ -1,169 +0,0 @@
<template>
<page-layout title="单号234231029431" logo="https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png">
<detail-list size="small" :col="2" slot="headerContent">
<detail-list-item term="创建人">曲丽丽</detail-list-item>
<detail-list-item term="订购产品">XX服务</detail-list-item>
<detail-list-item term="创建时间">2018-08-07</detail-list-item>
<detail-list-item term="关联单据"><a>12421</a></detail-list-item>
<detail-list-item term="生效日期">2018-08-07 ~ 2018-12-11</detail-list-item>
<detail-list-item term="备注">请于两个工作日内确认</detail-list-item>
</detail-list>
<template slot="extra">
<head-info title="状态" content="待审批" />
<head-info title="订单金额" content="¥ 568.08" />
</template>
<template slot="action">
<a-button-group style="margin-right: 8px;">
<a-button>操作</a-button>
<a-button>操作</a-button>
<a-button><a-icon type="ellipsis"/></a-button>
</a-button-group>
<a-button type="primary" >主操作</a-button>
</template>
<a-card :bordered="false" title="流程进度">
<a-steps :current="1" progress-dot :direction="isMobile ? 'vertical' : 'horizontal'">
<a-step title="创建项目">
<a-step-item-group :align="isMobile ? 'left' : 'center'" slot="description">
<a-step-item link="/dashboard/workplace" title="曲丽丽" icon="dingding-o"/>
<a-step-item title="2016-12-12 12:32"/>
</a-step-item-group>
</a-step>
<a-step title="部门初审">
<a-step-item-group :align="isMobile ? 'left' : 'center'" slot="description">
<a-step-item link="/form/step" title="周毛毛" icon="dingding-o" />
<a-step-item link="/result/success" title="催一下" icon="bell"/>
</a-step-item-group>
</a-step>
<a-step title="财务复核">
</a-step>
<a-step title="完成">
</a-step>
</a-steps>
</a-card>
<a-card style="margin-top: 24px" :bordered="false" title="用户信息">
<detail-list>
<detail-list-item term="用户姓名">付晓晓</detail-list-item>
<detail-list-item term="会员卡号">32943898021309809423</detail-list-item>
<detail-list-item term="身份证">3321944288191034921</detail-list-item>
<detail-list-item term="联系方式">18112345678</detail-list-item>
<detail-list-item term="联系地址">浙江省杭州市西湖区黄姑山路工专路交叉路口</detail-list-item>
</detail-list>
<detail-list title="信息组">
<detail-list-item term="某某数据">725</detail-list-item>
<detail-list-item term="该数据更新时间">2018-08-08</detail-list-item>
<detail-list-item >&nbsp;</detail-list-item>
<detail-list-item term="某某数据">725</detail-list-item>
<detail-list-item term="该数据更新时间">2018-08-08</detail-list-item>
<detail-list-item >&nbsp;</detail-list-item>
</detail-list>
<a-card type="inner" title="多层信息组">
<detail-list title="组名称" size="small">
<detail-list-item term="负责人">林东东</detail-list-item>
<detail-list-item term="角色码">1234567</detail-list-item>
<detail-list-item term="所属部门">XX公司-YY部</detail-list-item>
<detail-list-item term="过期时间">2018-08-08</detail-list-item>
<detail-list-item term="描述">这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...</detail-list-item>
</detail-list>
<a-divider style="margin: 16px 0" />
<detail-list title="组名称" size="small" :col="1">
<detail-list-item term="学名">林东东</detail-list-item>
<detail-list-item term="角色码">1234567</detail-list-item>
<detail-list-item term="所属部门">XX公司-YY部</detail-list-item>
<detail-list-item term="过期时间">2018-08-08</detail-list-item>
<detail-list-item term="描述">这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...</detail-list-item>
</detail-list>
<a-divider style="margin: 16px 0" />
<detail-list title="组名称" size="small" :col="2">
<detail-list-item term="学名">林东东</detail-list-item>
<detail-list-item term="角色码">1234567</detail-list-item>
<detail-list-item term="所属部门">XX公司-YY部</detail-list-item>
<detail-list-item term="过期时间">2018-08-08</detail-list-item>
<detail-list-item term="描述">这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...</detail-list-item>
</detail-list>
</a-card>
</a-card>
<a-card style="margin-top: 24px" :bordered="false" title="用户近半年来电记录">
<a-list></a-list>
</a-card>
<a-card
style="margin-top: 24px"
:bordered="false"
:tabList="tabList"
:activeTabKey="activeTabKey"
@tabChange="(key) => {this.activeTabKey = key}"
>
<a-table
v-if="activeTabKey === '1'"
:columns="operationColumns"
:dataSource="operation1"
:pagination="false"
/>
<a-table
v-if="activeTabKey === '2'"
:columns="operationColumns"
:dataSource="operation2"
:pagination="false"
/>
<a-table
v-if="activeTabKey === '3'"
:columns="operationColumns"
:dataSource="operation3"
:pagination="false"
/>
</a-card>
</page-layout>
</template>
<script>
import PageLayout from '@/layouts/PageLayout'
import DetailList from '@/components/tool/DetailList'
import AStepItem from '@/components/tool/AStepItem'
import {operation1, operation2, operation3, operationColumns} from '@/mock/common/tableData'
import {mapState} from 'vuex'
import HeadInfo from '@/components/tool/HeadInfo';
const DetailListItem = DetailList.Item
const AStepItemGroup = AStepItem.Group
const tabList = [
{
key: '1',
tab: '操作日志一'
},
{
key: '2',
tab: '操作日志二'
},
{
key: '3',
tab: '操作日志三'
}
]
export default {
name: 'AdvancedDetail',
components: {HeadInfo, AStepItemGroup, AStepItem, DetailListItem, DetailList, PageLayout},
data () {
return {
tabList,
operationColumns,
operation1,
operation2,
operation3,
activeTabKey: '2'
}
},
computed: {
...mapState('setting', ['isMobile'])
},
methods: {
onTabChange (key) {
console.log(key)
}
},
}
</script>
<style lang="less" scoped>
</style>

View File

@ -1,208 +0,0 @@
<template>
<page-layout title="基础详情页">
<a-card :bordered="false">
<detail-list title="退款详情">
<detail-list-item term="取货单号">1000000000</detail-list-item>
<detail-list-item term="状态">已取货</detail-list-item>
<detail-list-item term="销售单号">987654321</detail-list-item>
<detail-list-item term="子订单">1234567890</detail-list-item>
</detail-list>
<a-divider style="margin-bottom: 32px"/>
<detail-list title="用户信息">
<detail-list-item term="用户姓名">付小小</detail-list-item>
<detail-list-item term="联系电话">18100000001</detail-list-item>
<detail-list-item term="常用快递">菜鸟仓储</detail-list-item>
<detail-list-item term="取货地址">浙江省杭州市西湖区万塘路19号</detail-list-item>
<detail-list-item term="备注"></detail-list-item>
</detail-list>
<a-divider style="margin-bottom: 32px"/>
<div class="title">退货商品</div>
<a-table
row-key="id"
style="margin-bottom: 24px"
:columns="goodsColumns"
:dataSource="goodsData"
:pagination="false"
>
</a-table>
<div class="title">退货进度</div>
<a-table
:columns="scheduleColumns"
:dataSource="scheduleData"
:pagination="false"
>
</a-table>
</a-card>
</page-layout>
</template>
<script>
import DetailList from '../../components/tool/DetailList'
import PageLayout from '../../layouts/PageLayout'
const DetailListItem = DetailList.Item
const goodsColumns = [
{
title: '商品编号',
dataIndex: 'id',
key: 'id'
},
{
title: '商品名称',
dataIndex: 'name',
key: 'name'
},
{
title: '商品条码',
dataIndex: 'barcode',
key: 'barcode'
},
{
title: '单价',
dataIndex: 'price',
key: 'price',
align: 'right'
},
{
title: '数量(件)',
dataIndex: 'num',
key: 'num',
align: 'right'
},
{
title: '金额',
dataIndex: 'amount',
key: 'amount',
align: 'right'
}
]
const goodsData = [
{
id: '1234561',
name: '矿泉水 550ml',
barcode: '12421432143214321',
price: '2.00',
num: '1',
amount: '2.00'
},
{
id: '1234562',
name: '凉茶 300ml',
barcode: '12421432143214322',
price: '3.00',
num: '2',
amount: '6.00'
},
{
id: '1234563',
name: '好吃的薯片',
barcode: '12421432143214323',
price: '7.00',
num: '4',
amount: '28.00'
},
{
id: '1234564',
name: '特别好吃的蛋卷',
barcode: '12421432143214324',
price: '8.50',
num: '3',
amount: '25.50'
}
]
const scheduleColumns = [
{
title: '时间',
dataIndex: 'time',
key: 'time'
},
{
title: '当前进度',
dataIndex: 'rate',
key: 'rate'
},
{
title: '状态',
dataIndex: 'status',
key: 'status'
},
{
title: '操作员ID',
dataIndex: 'operator',
key: 'operator'
},
{
title: '耗时',
dataIndex: 'cost',
key: 'cost'
}
]
const scheduleData = [
{
key: '1',
time: '2017-10-01 14:10',
rate: '联系客户',
status: 'processing',
operator: '取货员 ID1234',
cost: '5mins'
},
{
key: '2',
time: '2017-10-01 14:05',
rate: '取货员出发',
status: 'success',
operator: '取货员 ID1234',
cost: '1h'
},
{
key: '3',
time: '2017-10-01 13:05',
rate: '取货员接单',
status: 'success',
operator: '取货员 ID1234',
cost: '5mins'
},
{
key: '4',
time: '2017-10-01 13:00',
rate: '申请审批通过',
status: 'success',
operator: '系统',
cost: '1h'
},
{
key: '5',
time: '2017-10-01 12:00',
rate: '发起退货申请',
status: 'success',
operator: '用户',
cost: '5mins'
}
]
export default {
name: 'BasicDetail',
components: {PageLayout, DetailListItem, DetailList},
data () {
return {
goodsColumns,
goodsData,
scheduleColumns,
scheduleData
}
}
}
</script>
<style lang="less" scoped>
.title {
color: @title-color;
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<exception-page :style="`margin-top: ${marginTop}px; min-height: ${minHeight}px`" type="403" />
<exception-page :style="`min-height: ${minHeight}px`" type="403" />
</template>
<script>
@ -11,11 +11,8 @@ export default {
inject: ['layoutMinHeight'],
computed: {
...mapState('setting', ['multiPage']),
marginTop() {
return this.multiPage ? -24 : 0
},
minHeight() {
return this.multiPage ? this.layoutMinHeight - 32 : this.layoutMinHeight
return this.multiPage ? this.layoutMinHeight : this.layoutMinHeight
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<exception-page :style="`margin-top: ${marginTop}px; min-height: ${minHeight}px`" type="404" />
<exception-page :style="`min-height: ${minHeight}px`" type="404" />
</template>
<script>
@ -11,11 +11,9 @@ export default {
inject: ['layoutMinHeight'],
computed: {
...mapState('setting', ['multiPage']),
marginTop() {
return this.multiPage ? -24 : 0
},
minHeight() {
return this.multiPage ? this.layoutMinHeight - 32 : this.layoutMinHeight
let layoutMinHeight = this.layoutMinHeight || window.innerHeight
return this.multiPage ? layoutMinHeight: layoutMinHeight
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<exception-page :style="`margin-top: ${marginTop}px; min-height: ${minHeight}px`" type="500" />
<exception-page :style="`min-height: ${minHeight}px`" type="500" />
</template>
<script>
@ -11,11 +11,8 @@ export default {
inject: ['layoutMinHeight'],
computed: {
...mapState('setting', ['multiPage']),
marginTop() {
return this.multiPage ? -24 : 0
},
minHeight() {
return this.multiPage ? this.layoutMinHeight - 24 : this.layoutMinHeight
return this.multiPage ? this.layoutMinHeight : this.layoutMinHeight
}
}
}

View File

@ -1,59 +0,0 @@
<template>
<div>
<a-card class="card" :title="$t('repository')" :bordered="false">
<repository-form ref="repository" :showSubmit="false" />
</a-card>
<a-card class="card" :title="$t('task')" :bordered="false">
<task-form ref="task" :showSubmit="false" />
</a-card>
<a-card :title="$t('user')" :bordered="false">
<user-form />
</a-card>
<footer-tool-bar>
<a-button type="primary" @click="validate" :loading="loading">{{$t('submit')}}</a-button>
</footer-tool-bar>
</div>
</template>
<script>
import RepositoryForm from './RepositoryForm'
import TaskForm from './TaskForm'
import UserForm from './UserForm'
import FooterToolBar from '@/components/tool/FooterToolBar'
export default {
name: 'AdvancedForm',
components: {FooterToolBar, UserForm, TaskForm, RepositoryForm},
i18n: require('./i18n'),
data () {
return {
loading: false
}
},
computed: {
desc() {
return this.$t('desc')
}
},
methods: {
validate () {
this.$refs.repository.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
this.$refs.task.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
}
}
}
</script>
<style lang="less" scoped>
.card{
margin-bottom: 24px;
}
</style>

View File

@ -1,116 +0,0 @@
<template>
<a-form @submit="handleSubmit" :form="form" class="form">
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item :label="$t('name')">
<a-input
:placeholder="$ta('input|name')"
v-decorator="['repository.name', {rules: [{ required: true, message: $ta('input|name'), whitespace: true}]}]"
/>
</a-form-item>
</a-col>
<a-col :xl="{span: 6, offset: 2}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item :label="$t('domain')">
<a-input
addonBefore="http://" addonAfter=".github.io"
:placeholder="$ta('input|domain')"
v-decorator="['repository.domain', {rules: [{ required: true, message: $ta('input|domain'), whitespace: true}, {validator: validate}]}]"
/>
</a-form-item>
</a-col>
<a-col :xl="{span: 8, offset: 2}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item :label="$t('manager')">
<a-select
:placeholder="$ta('select|manager')"
v-decorator="['repository.manager', {rules: [{ required: true, message: $ta('select|manager')}]}]"
>
<a-select-option value="王同学">王同学</a-select-option>
<a-select-option value="李同学">李同学</a-select-option>
<a-select-option value="黄同学">黄同学</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item :label="$t('approval')">
<a-select
:placeholder="$ta('select|approval')"
v-decorator="['repository.auditor', {rules: [{ required: true, message: $ta('select|approval')}]}]"
>
<a-select-option value="王晓丽">王晓丽</a-select-option>
<a-select-option value="李军">李军</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :xl="{span: 6, offset: 2}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item :label="$t('date')">
<a-range-picker
style="width: 100%"
v-decorator="['repository.effectiveDate', {rules: [{ required: true, message: $ta('select|date')}]}]"
/>
</a-form-item>
</a-col>
<a-col :xl="{span: 8, offset: 2}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item :label="$t('type')">
<a-select
:placeholder="$ta('select|type')"
v-decorator="['repository.type', {rules: [{ required: true, message: $ta('select|type')}]}]"
>
<a-select-option value="公开">公开</a-select-option>
<a-select-option value="私密">私密</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item v-if="showSubmit">
<a-button htmlType="submit" >Submit</a-button>
</a-form-item>
</a-form>
</template>
<script>
export default {
name: 'RepositoryForm',
props: ['showSubmit'],
i18n: require('./i18n-repository'),
data() {
return {
form: this.$form.createForm(this)
}
},
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
},
validate (rule, value, f) {
if (value !== undefined && value !== 'iczer') {
f('输入\'iczer\'试下?')
}
f()
}
}
}
</script>
<style lang="less" scoped>
.form{
.form-row{
margin: 0 -8px
}
.ant-col-md-12,
.ant-col-sm-24,
.ant-col-lg-6,
.ant-col-lg-8,
.ant-col-lg-10,
.ant-col-xl-8,
.ant-col-xl-6{
padding: 0 8px
}
}
</style>

View File

@ -1,110 +0,0 @@
<template>
<a-form @submit="handleSubmit" :form="form" class="form">
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item :label="$t('name')">
<a-input
v-decorator="['task.name', {rules: [{ required: true, message: $ta('input|name'), whitespace: true}]}]"
:placeholder="$ta('input|name')"
/>
</a-form-item>
</a-col>
<a-col :xl="{span: 6, offset: 2}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item :label="$t('describe')">
<a-input
v-decorator="['task.description', {rules: [{ required: true, message: $ta('input|describe'), whitespace: true}]}]"
:placeholder="$ta('input|describe')"
/>
</a-form-item>
</a-col>
<a-col :xl="{span: 8, offset: 2}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item
:label="$t('executor')"
>
<a-select
:placeholder="$ta('select|executor')"
v-decorator="['task.executor', {rules: [{ required: true, message: $ta('select|executor')}]}]"
>
<a-select-option value="黄丽丽">黄丽丽</a-select-option>
<a-select-option value="李大刀">李大刀</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item :label="$t('duty')">
<a-select
:placeholder="$ta('select|duty')"
v-decorator="['task.manager', {rules: [{ required: true, message: $ta('select|duty')}]}]"
>
<a-select-option value="王伟">王伟</a-select-option>
<a-select-option value="李红军">李红军</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :xl="{span: 6, offset: 2}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item :label="$t('time')">
<a-time-picker
v-decorator="['task.time', {rules: [{ required: true, message: $ta('select|time')}]}]"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :xl="{span: 8, offset: 2}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item :label="$t('type')">
<a-select
:placeholder="$ta('select|type')"
v-decorator="['task.type', {rules: [{ required: true, message: $ta('select|type')}]}]"
>
<a-select-option value="定时执行">定时执行</a-select-option>
<a-select-option value="周期执行">周期执行</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item v-if="showSubmit">
<a-button htmlType="submit" >Submit</a-button>
</a-form-item>
</a-form>
</template>
<script>
export default {
name: 'TaskForm',
props: ['showSubmit'],
i18n: require('./i18n-task'),
data() {
return {
form: this.$form.createForm(this)
}
},
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values)
}
})
}
}
}
</script>
<style lang="less" scoped>
.form{
.form-row{
margin: 0 -8px
}
.ant-col-md-12,
.ant-col-sm-24,
.ant-col-lg-6,
.ant-col-lg-8,
.ant-col-lg-10,
.ant-col-xl-8,
.ant-col-xl-6{
padding: 0 8px
}
}
</style>

View File

@ -1,167 +0,0 @@
<template>
<form :autoFormCreate="(form) => this.form = form">
<a-table
:columns="dataColumns"
:dataSource="dataSource"
:pagination="false"
>
<template v-for="(col, i) in ['name', 'number', 'department']" :slot="col" slot-scope="text, record">
<a-input
:key="col"
v-if="record.editable"
style="margin: -5px 0"
:value="text"
:placeholder="columns[i].title"
@change="e => handleChange(e.target.value, record.key, col)"
/>
<template v-else>{{text}}</template>
</template>
<template slot="operation" slot-scope="text, record">
<template v-if="record.editable">
<span v-if="record.isNew">
<a @click="saveRow(record.key)">{{$t('add')}}</a>
<a-divider type="vertical" />
<a-popconfirm :title="$t('deleteConfirm')" @confirm="remove(record.key)">
<a>{{$t('delete')}}</a>
</a-popconfirm>
</span>
<span v-else>
<a @click="saveRow(record.key)">{{$t('save')}}</a>
<a-divider type="vertical" />
<a @click="cancle(record.key)">{{$t('cancel')}}</a>
</span>
</template>
<span v-else>
<a @click="toggle(record.key)">{{$t('edit')}}</a>
<a-divider type="vertical" />
<a-popconfirm :title="$t('deleteConfirm')" @confirm="remove(record.key)">
<a>{{$t('delete')}}</a>
</a-popconfirm>
</span>
</template>
</a-table>
<a-button style="width: 100%; margin-top: 16px; margin-bottom: 8px" type="dashed" icon="plus" @click="newMember">{{$t('newMember')}}</a-button>
</form>
</template>
<script>
const columns = [
{
title: '成员姓名',
dataIndex: 'name',
key: 'name',
width: '20%',
scopedSlots: { customRender: 'name' }
},
{
title: '工号',
dataIndex: 'number',
key: 'number',
width: '20%',
scopedSlots: { customRender: 'number' }
},
{
title: '所属部门',
dataIndex: 'department',
key: 'department',
width: '40%',
scopedSlots: { customRender: 'department' }
},
{
title: '操作',
key: 'operation',
scopedSlots: { customRender: 'operation' }
}
]
const dataSource = [
{
key: 1,
name: '小明',
number: '001',
editable: false,
department: '行政部'
},
{
key: 2,
name: '李莉',
number: '002',
editable: false,
department: 'IT部'
},
{
key: 3,
name: '王小帅',
number: '003',
editable: false,
department: '财务部'
}
]
export default {
name: 'UserForm',
i18n: require('./i18n-user'),
data () {
return {
columns,
dataSource
}
},
computed: {
dataColumns() {
return this.columns.map(column => {
column.title = this.$t('table.' + column.key)
return column
})
}
},
methods: {
handleSubmit (e) {
e.preventDefault()
},
newMember () {
this.dataSource.push({
key: this.dataSource.length + 1,
name: '',
number: '',
department: '',
editable: true,
isNew: true
})
},
remove (key) {
const newData = this.dataSource.filter(item => item.key !== key)
this.dataSource = newData
},
saveRow (key) {
let target = this.dataSource.filter(item => item.key === key)[0]
target.editable = false
target.isNew = false
},
toggle (key) {
let target = this.dataSource.filter(item => item.key === key)[0]
target.editable = !target.editable
},
getRowByKey (key, newData) {
const data = this.dataSource
return (newData || data).filter(item => item.key === key)[0]
},
cancle (key) {
let target = this.dataSource.filter(item => item.key === key)[0]
target.editable = false
},
handleChange (value, key, column) {
const newData = [...this.dataSource]
const target = newData.filter(item => key === item.key)[0]
if (target) {
target[column] = value
this.dataSource = newData
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,34 +0,0 @@
module.exports = {
messages: {
CN: {
input: '请输入',
select: '请选择',
name: '仓库名',
domain: '仓库域名',
manager: '仓库管理员',
approval: '审批人员',
date: '生效日期',
type: '仓库类型'
},
HK: {
input: '請輸入',
select: '請選擇',
name: '倉庫名',
domain: '倉庫域名',
manager: '倉庫管理員',
approval: '審批人員',
date: '生效日期',
type: '倉庫類型',
},
US: {
input: 'Please enter',
select: 'Please select',
name: 'Repository Name',
domain: 'Repository Domain',
manager: 'Repository Manager',
approval: 'Approval Person',
date: 'Effective Date',
type: 'Repository Type',
}
}
}

View File

@ -1,34 +0,0 @@
module.exports = {
messages: {
CN: {
input: '请输入',
select: '请选择',
name: '任务名',
describe: '任务描述',
executor: '执行人',
duty: '责任人',
time: '提醒时间',
type: '任务类型',
},
HK: {
input: '請輸入',
select: '請選擇',
name: '任務名',
describe: '任務描述',
executor: '執行人',
duty: '責任人',
time: '提醒時間',
type: '任務類型',
},
US: {
input: 'Please enter',
select: 'Please select',
name: 'Task Name',
describe: 'Task Describe',
executor: 'Executor',
duty: 'Duty Person',
time: 'Reminder Time',
type: 'Task Type',
}
}
}

View File

@ -1,49 +0,0 @@
module.exports = {
messages: {
CN: {
add: '添加',
delete: '删除',
save: '保存',
cancel: '取消',
edit: '编辑',
deleteConfirm: '是否要删除此行?',
newMember: '新增成员',
table: {
name: '成员姓名',
number: '工号',
department: '所属部门',
operation: '操作',
}
},
HK: {
add: '添加',
delete: '刪除',
save: '保存',
cancel: '取消',
edit: '編輯',
deleteConfirm: '是否要刪除此行?',
newMember: '新增成員',
table: {
name: '成員姓名',
number: '工號',
department: '所屬部門',
operation: '操作',
}
},
US: {
add: 'add',
delete: 'delete',
save: 'save',
cancel: 'cancel',
edit: 'edit',
deleteConfirm: 'Confirm to delete this row?',
newMember: 'new member',
table: {
name: 'Member Name',
number: 'Job Number',
department: 'Department',
operation: 'Operation',
}
}
}
}

View File

@ -1,25 +0,0 @@
module.exports = {
messages: {
CN: {
desc: '高级表单常见于一次性输入和提交大批量数据的场景。',
repository: '仓库管理',
task: '任务管理',
user: '用户管理',
submit: '提交'
},
HK: {
desc: '高級表單常見於一次性輸入和提交大批量數據的場景。',
repository: '倉庫管理',
task: '任務管理',
user: '用戶管理',
submit: '提交'
},
US: {
desc: 'Advanced forms are common in scenarios where large quantities of data are entered and submitted at one time.',
repository: 'Repository Manage',
task: 'Task Manage',
user: 'User Manage',
submit: 'submit'
}
}
}

View File

@ -1,102 +0,0 @@
<template>
<a-card :body-style="{padding: '24px 32px'}" :bordered="false">
<a-form>
<a-form-item
:label="$t('title')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
>
<a-input :placeholder="$t('titleInput')" />
</a-form-item>
<a-form-item
:label="$t('date')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
>
<a-range-picker style="width: 100%" />
</a-form-item>
<a-form-item
:label="$t('describe')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
>
<a-textarea rows="4" :placeholder="$t('describeInput')"/>
</a-form-item>
<a-form-item
:label="$t('metrics')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
>
<a-textarea rows="4" :placeholder="$t('metricsInput')"/>
</a-form-item>
<a-form-item
:label="$t('customer')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
:required="false"
>
<a-input :placeholder="$t('customerInput')"/>
</a-form-item>
<a-form-item
:label="$t('critics')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
:required="false"
>
<a-input :placeholder="$t('criticsInput')"/>
</a-form-item>
<a-form-item
:label="$t('weight')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
:required="false"
>
<a-input-number :min="0" :max="100"/>
<span>%</span>
</a-form-item>
<a-form-item
:label="$t('disclosure')"
:labelCol="{span: 7}"
:wrapperCol="{span: 10}"
:required="false"
:help="$t('disclosureDesc')"
>
<a-radio-group v-model="value">
<a-radio :value="1">{{$t('public')}}</a-radio>
<a-radio :value="2">{{$t('partially')}}</a-radio>
<a-radio :value="3">{{$t('private')}}</a-radio>
</a-radio-group>
<a-select mode="multiple" v-if="value === 2">
<a-select-option value="4">{{$t('colleague1')}}</a-select-option>
<a-select-option value="5">{{$t('colleague2')}}</a-select-option>
<a-select-option value="6">{{$t('colleague3')}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item style="margin-top: 24px" :wrapperCol="{span: 10, offset: 7}">
<a-button type="primary">{{$t('submit')}}</a-button>
<a-button style="margin-left: 8px">{{$t('save')}}</a-button>
</a-form-item>
</a-form>
</a-card>
</template>
<script>
export default {
name: 'BasicForm',
i18n: require('./i18n'),
data () {
return {
value: 1
}
},
computed: {
desc() {
return this.$t('pageDesc')
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,79 +0,0 @@
module.exports = {
messages: {
CN: {
pageDesc: '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。',
title: '标题',
titleInput: '给目标起个名字',
date: '起止日期',
describe: '目标描述',
describeInput: '请输入你阶段性工作目标',
metrics: '衡量标准',
metricsInput: '请输入衡量标准',
customer: '客户',
customerInput: '请描述你服务的客户,内部客户直接 @姓名/工号',
critics: '邀评人',
criticsInput: '请直接 @姓名/工号,最多可邀请 5 人',
weight: '权重',
disclosure: '目标公开',
disclosureDesc: '客户、邀评人默认被分享',
public: '公开',
partially: '部分公开',
private: '不公开',
submit: '提交',
save: '保存',
colleague1: '同事甲',
colleague2: '同事乙',
colleague3: '同事丙'
},
HK: {
pageDesc: '表單頁用於向用戶收集或驗證信息,基礎表單常見於數據項較少的表單場景。',
title: '標題',
titleInput: '給目標起個名字',
date: '起止日期',
describe: '目標描述',
describeInput: '請輸入你階段性的工作目標',
metrics: '衡量標準',
metricsInput: '請輸入衡量標準',
customer: '客戶',
customerInput: '請描述你服務的客戶,內部客戶直接 @姓名/工號',
critics: '邀評人',
criticsInput: '請直接 @姓名/工號,最多可邀請 5 人',
weight: '圈中人',
disclosure: '目標公開',
disclosureDesc: '客戶、邀評人默認被分享',
public: '公開',
partially: '部分公開',
private: '不公開',
submit: '提交',
save: '保存',
colleague1: '同事甲',
colleague2: '同事乙',
colleague3: '同事丙'
},
US: {
pageDesc: 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.',
title: 'Title',
titleInput: 'Give the target a name',
date: 'Start and end date',
describe: 'Goal description',
describeInput: 'Please enter your work goals',
metrics: 'Metrics',
metricsInput: 'Please enter a metric',
customer: 'Customer',
customerInput: 'Please describe your customer service, internal customers directly @ Name / job number',
critics: 'Inviting critics',
criticsInput: 'Please direct @ Name / job number, you can invite up to 5 people',
weight: 'Weight',
disclosure: 'Target disclosure',
disclosureDesc: 'Customers and invitees are shared by default',
public: 'Public',
partially: 'Partially public',
private: 'Private',
submit: 'Submit',
save: 'Save',
colleague1: 'Colleague A',
colleague2: 'Colleague B',
colleague3: 'Colleague C'
}
}
}

View File

@ -1,61 +0,0 @@
<template>
<div>
<a-form style="max-width: 500px; margin: 40px auto 0;">
<a-form-item
:label="$t('payment')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
>
<a-select value="1" placeholder="ant-design@alipay.com">
<a-select-option value="1">ant-design@alipay.com</a-select-option>
</a-select>
</a-form-item>
<a-form-item
:label="$t('collection')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
>
<a-input-group :compact="true" style="display: inline-block; vertical-align: middle">
<a-select defaultValue="alipay" style="width: 100px">
<a-select-option value="alipay">{{$t('alipay')}}</a-select-option>
<a-select-option value="wexinpay">{{$t('wechat')}}</a-select-option>
</a-select>
<a-input :style="{width: 'calc(100% - 100px)'}" value="test@example.com"/>
</a-input-group>
</a-form-item>
<a-form-item
:label="$t('collectionName')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
>
<a-input value="Alex" />
</a-form-item>
<a-form-item
:label="$t('transferAmount')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
>
<a-input prefix="¥" value="5000" />
</a-form-item>
<a-form-item :wrapperCol="{span: 17, offset: 7}">
<a-button type="primary" @click="nextStep">{{$t('nextStep')}}</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script>
export default {
name: 'Step1',
i18n: require('./i18n'),
methods: {
nextStep () {
this.$emit('nextStep')
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,83 +0,0 @@
<template>
<div>
<a-form style="max-width: 500px; margin: 40px auto 0;">
<a-alert
:closable="true"
:message="$t('note')"
style="margin-bottom: 24px;"
/>
<a-form-item
:label="$t('payment')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
class="stepFormText"
>
ant-design@alipay.com
</a-form-item>
<a-form-item
:label="$t('collection')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
class="stepFormText"
>
test@example.com
</a-form-item>
<a-form-item
:label="$t('collectionName')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
class="stepFormText"
>
Alex
</a-form-item>
<a-form-item
:label="$t('transferAmount')"
:labelCol="{span: 7}"
:wrapperCol="{span: 17}"
class="stepFormText"
>
5,000.00
</a-form-item>
<a-form-item :wrapperCol="{span: 17, offset: 7}">
<a-button :loading="loading" type="primary" @click="nextStep">{{$t('submit')}}</a-button>
<a-button style="margin-left: 8px" @click="prevStep">{{$t('preStep')}}</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script>
export default {
name: 'Step2',
i18n: require('./i18n'),
data () {
return {
loading: false
}
},
methods: {
nextStep () {
let _this = this
_this.loading = true
setTimeout(function () {
_this.$emit('nextStep')
}, 1500)
},
prevStep () {
this.$emit('prevStep')
}
}
}
</script>
<style lang="less" scoped>
.stepFormText {
margin-bottom: 24px;
:global {
.ant-form-item-label,
.ant-form-item-control {
line-height: 22px;
}
}
}
</style>

View File

@ -1,25 +0,0 @@
<template>
<div style="max-width: 500px; margin: 40px auto 0; text-align: center">
<result :title="$t('success')" :is-success="true" />
<a-button type="primary" @click="doOnceAgin">{{$t('doAgain')}}</a-button>
<a-button style="margin-left: 8px">{{$t('bill')}}</a-button>
</div>
</template>
<script>
import Result from '@/components/result/Result'
export default {
name: 'Step3',
i18n: require('./i18n'),
components: {Result},
methods: {
doOnceAgin () {
this.$emit('finish')
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,58 +0,0 @@
<template>
<a-card :bordered="false">
<a-steps class="steps" :current="current">
<a-step :title="$t('input')" />
<a-step :title="$t('confirm')" />
<a-step :title="$t('complete')" />
</a-steps>
<div class="content">
<step1 v-if="current === 0" @nextStep="nextStep"></step1>
<step2 v-if="current === 1" @nextStep="nextStep" @prevStep="prevStep"></step2>
<step3 v-if="current === 2" @prevStep="prevStep" @finish="finish"></step3>
</div>
</a-card>
</template>
<script>
import Step1 from './Step1'
import Step2 from './Step2'
import Step3 from './Step3'
export default {
name: 'StepForm',
i18n: require('./i18n'),
components: {Step1, Step2, Step3},
data () {
return {
current: 0
}
},
computed: {
desc() {
return this.$t('pageDesc')
}
},
methods: {
nextStep () {
if (this.current < 2) {
this.current += 1
}
},
prevStep () {
if (this.current > 0) {
this.current -= 1
}
},
finish () {
this.current = 0
}
}
}
</script>
<style lang="less" scoped>
.steps{
max-width: 950px;
margin: 16px auto;
}
</style>

View File

@ -1,61 +0,0 @@
module.exports = {
messages: {
CN: {
pageDesc: '将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。',
input: '请填写转账信息',
confirm: '确认转账信息',
complete: '完成',
payment: '付款账户',
collection: '收款账户',
alipay: '支付宝',
wechat: '微信',
collectionName: '收款人姓名',
transferAmount: '转账金额',
nextStep: '下一步',
preStep: '上一步',
submit: '提交',
note: '确认转账后,资金将直接打入对方账户,无法退回。',
success: '支付完成',
doAgain: '再转一笔',
bill: '查看账单'
},
HK: {
pageDesc: '將一個冗長或用戶不熟悉的表單任務分成多個步驟,指導用戶完成。',
input: '請填寫轉賬信息',
confirm: '確認轉賬信息',
complete: '完成',
payment: '付款賬戶',
collection: '收款賬戶',
alipay: '支付寶',
wechat: '微信',
collectionName: '收款人姓名',
transferAmount: '裝張金額',
nextStep: '下一步',
preStep: '上一步',
submit: '提交',
note: '確認轉賬後,現金將直接打入對方賬戶,無法退回。',
success: '支付完成',
doAgain: '再轉一筆',
bill: '查看賬單'
},
US: {
pageDesc: 'Divide a long or unfamiliar form task into several steps to guide the user to complete it.',
input: 'Fill transfer information',
confirm: 'Confirm transfer information',
complete: 'Complete',
payment: 'Payment account',
collection: 'Collection account',
alipay: 'Alipay',
wechat: 'Wechat',
collectionName: 'Name of payee',
transferAmount: 'Transfer amount',
nextStep: 'Next',
preStep: 'Back',
submit: 'Submit',
note: 'After confirming the transfer, the funds will be directly transferred into the other party\'s account and cannot be returned.',
success: 'Payment successful',
doAgain: 'Do Again',
bill: 'Check the bill'
}
}
}

View File

@ -1,80 +0,0 @@
<template>
<div class="card-list">
<a-list
:grid="{gutter: 24, lg: 3, md: 2, sm: 1, xs: 1}"
:dataSource="dataSource"
>
<a-list-item slot="renderItem" slot-scope="item">
<template v-if="item.add">
<a-button class="new-btn" type="dashed">
<a-icon type="plus" />新增产品
</a-button>
</template>
<template v-else>
<a-card :hoverable="true">
<a-card-meta >
<div style="margin-bottom: 3px" slot="title">{{item.title}}</div>
<a-avatar class="card-avatar" slot="avatar" :src="item.avatar" size="large" />
<div class="meta-content" slot="description">{{item.content}}</div>
</a-card-meta>
<a slot="actions">操作一</a>
<a slot="actions">操作一</a>
</a-card>
</template>
</a-list-item>
</a-list>
</div>
</template>
<script>
const dataSource = []
dataSource.push({
add: true
})
for (let i = 0; i < 11; i++) {
dataSource.push({
title: 'Alipay',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png',
content: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
})
}
export default {
name: 'CardList',
data () {
return {
desc: '段落示意:蚂蚁金服务设计平台 ant.design用最小的工作量无缝接入蚂蚁金服生态 提供跨越设计与开发的体验解决方案。',
linkList: [
{icon: 'rocket', href: '/#/', title: '快速开始'},
{icon: 'info-circle-o', href: '/#/', title: '产品简介'},
{icon: 'file-text', href: '/#/', title: '产品文档'}
],
extraImage: 'https://gw.alipayobjects.com/zos/rmsportal/RzwpdLnhmvDJToTdfDPe.png',
dataSource
}
}
}
</script>
<style lang="less" scoped>
.card-avatar {
width: 48px;
height: 48px;
border-radius: 48px;
}
.new-btn{
border-radius: 2px;
width: 100%;
height: 187px;
}
.meta-content{
position: relative;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
height: 64px;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
</style>

View File

@ -1,217 +0,0 @@
<template>
<a-card>
<div :class="advanced ? 'search' : null">
<a-form layout="horizontal">
<div :class="advanced ? null: 'fold'">
<a-row >
<a-col :md="8" :sm="24" >
<a-form-item
label="规则编号"
:labelCol="{span: 5}"
:wrapperCol="{span: 18, offset: 1}"
>
<a-input placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24" >
<a-form-item
label="使用状态"
:labelCol="{span: 5}"
:wrapperCol="{span: 18, offset: 1}"
>
<a-select placeholder="请选择">
<a-select-option value="1">关闭</a-select-option>
<a-select-option value="2">运行中</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="8" :sm="24" >
<a-form-item
label="调用次数"
:labelCol="{span: 5}"
:wrapperCol="{span: 18, offset: 1}"
>
<a-input-number style="width: 100%" placeholder="请输入" />
</a-form-item>
</a-col>
</a-row>
<a-row v-if="advanced">
<a-col :md="8" :sm="24" >
<a-form-item
label="更新日期"
:labelCol="{span: 5}"
:wrapperCol="{span: 18, offset: 1}"
>
<a-date-picker style="width: 100%" placeholder="请输入更新日期" />
</a-form-item>
</a-col>
<a-col :md="8" :sm="24" >
<a-form-item
label="使用状态"
:labelCol="{span: 5}"
:wrapperCol="{span: 18, offset: 1}"
>
<a-select placeholder="请选择">
<a-select-option value="1">关闭</a-select-option>
<a-select-option value="2">运行中</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="8" :sm="24" >
<a-form-item
label="描述"
:labelCol="{span: 5}"
:wrapperCol="{span: 18, offset: 1}"
>
<a-input placeholder="请输入" />
</a-form-item>
</a-col>
</a-row>
</div>
<span style="float: right; margin-top: 3px;">
<a-button type="primary">查询</a-button>
<a-button style="margin-left: 8px">重置</a-button>
<a @click="toggleAdvanced" style="margin-left: 8px">
{{advanced ? '收起' : '展开'}}
<a-icon :type="advanced ? 'up' : 'down'" />
</a>
</span>
</a-form>
</div>
<div>
<div class="operator">
<a-button @click="addNew" type="primary">新建</a-button>
<a-button >批量操作</a-button>
<a-dropdown>
<a-menu @click="handleMenuClick" slot="overlay">
<a-menu-item key="delete">删除</a-menu-item>
<a-menu-item key="audit">审批</a-menu-item>
</a-menu>
<a-button>
更多操作 <a-icon type="down" />
</a-button>
</a-dropdown>
</div>
<standard-table
:columns="columns"
:dataSource="dataSource"
:selectedRows.sync="selectedRows"
@clear="onClear"
>
<div slot="description" slot-scope="{text}">
{{text}}
</div>
<div slot="action" slot-scope="{text, record, index}">
<a-icon type="edit" />{{index}}
</div>
</standard-table>
</div>
</a-card>
</template>
<script>
import StandardTable from '@/components/table/StandardTable'
const columns = [
{
title: '规则编号',
dataIndex: 'no'
},
{
title: '描述',
dataIndex: 'description',
scopedSlots: { customRender: 'description' }
},
{
title: '服务调用次数',
dataIndex: 'callNo',
sorter: true,
needTotal: true,
customRender: (text) => text + ' 次'
},
{
title: '状态',
dataIndex: 'status',
needTotal: true
},
{
title: '更新时间',
dataIndex: 'updatedAt',
sorter: true
},
{
title: '操作',
scopedSlots: { customRender: 'action' }
}
]
const dataSource = []
for (let i = 0; i < 100; i++) {
dataSource.push({
key: i,
no: 'NO ' + i,
description: '这是一段描述',
callNo: Math.floor(Math.random() * 1000),
status: Math.floor(Math.random() * 10) % 4,
updatedAt: '2018-07-26'
})
}
export default {
name: 'QueryList',
components: {StandardTable},
data () {
return {
advanced: true,
columns: columns,
dataSource: dataSource,
selectedRows: []
}
},
methods: {
toggleAdvanced () {
this.advanced = !this.advanced
},
remove () {
this.dataSource = this.dataSource.filter(item => this.selectedRows.findIndex(row => row.key === item.key) === -1)
this.selectedRows = []
},
onClear() {
this.$message.info('您清空了勾选的所有行')
},
addNew () {
this.dataSource.unshift({
key: this.dataSource.length,
no: 'NO ' + this.dataSource.length,
description: '这是一段描述',
callNo: Math.floor(Math.random() * 1000),
status: Math.floor(Math.random() * 10) % 4,
updatedAt: '2018-07-26'
})
},
handleMenuClick (e) {
if (e.key === 'delete') {
this.remove()
}
}
}
}
</script>
<style lang="less" scoped>
.search{
margin-bottom: 54px;
}
.fold{
width: calc(100% - 216px);
display: inline-block
}
.operator{
margin-bottom: 18px;
}
@media screen and (max-width: 900px) {
.fold {
width: 100%;
}
}
</style>

View File

@ -1,86 +0,0 @@
<template>
<div>
<a-card :bordered="false">
<div style="display: flex; flex-wrap: wrap">
<head-info title="我的待办" content="8个任务" :bordered="true"/>
<head-info title="本周任务平均处理时间" content="32分钟" :bordered="true"/>
<head-info title="本周完成任务数" content="24个"/>
</div>
</a-card>
<a-card
style="margin-top: 24px"
:bordered="false"
title="标准列表"
>
<div slot="extra">
<a-radio-group>
<a-radio-button>全部</a-radio-button>
<a-radio-button>进行中</a-radio-button>
<a-radio-button>等待中</a-radio-button>
</a-radio-group>
<a-input-search style="margin-left: 16px; width: 272px;" />
</div>
<a-button type="dashed" style="width: 100%" icon="plus">添加</a-button>
<a-list size="large" :pagination="{showSizeChanger: true, showQuickJumper: true, pageSize: 5, total: 50}">
<a-list-item :key="i" v-for="i in 5">
<a-list-item-meta
description="那是一种内在的东西, 他们到达不了,也无法触及的"
>
<a-avatar slot="avatar" size="large" shape="square" src="https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png"/>
<a slot="title">AliPay</a>
</a-list-item-meta>
<div slot="actions">
<a>编辑</a>
</div>
<div slot="actions">
<a-dropdown>
<a-menu slot="overlay">
<a-menu-item><a>编辑</a></a-menu-item>
<a-menu-item><a>删除</a></a-menu-item>
</a-menu>
<a>更多<a-icon type="down"/></a>
</a-dropdown>
</div>
<div class="list-content">
<div class="list-content-item">
<span>Owner</span>
<p>付晓晓</p>
</div>
<div class="list-content-item">
<span>开始时间</span>
<p>2018-07-26 22:44</p>
</div>
<div class="list-content-item">
<a-progress :percent="80" style="width: 180px" />
</div>
</div>
</a-list-item>
</a-list>
</a-card>
</div>
</template>
<script>
import HeadInfo from '../../components/tool/HeadInfo'
export default {
name: 'StandardList',
components: {HeadInfo}
}
</script>
<style lang="less" scoped>
.list-content-item{
color: @text-color-second;
display: inline-block;
vertical-align: middle;
font-size: 14px;
margin-left: 40px;
span{
line-height: 20px;
}
p{
margin: 4px 0 0;
line-height: 22px;
}
}
</style>

View File

@ -1,91 +0,0 @@
<template>
<div>
<search-form />
<a-list
:grid="{gutter: 16, xl: 4, lg: 3, md: 3, sm: 2, xs: 1}"
style="margin: 0 -8px"
>
<a-list-item :key="n" v-for="n in 12" style="padding: 0 8px">
<a-card>
<a-card-meta title="Angular">
<a-avatar slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" size="small" />
</a-card-meta>
<a-tooltip class="tool" title="下载" slot="actions">
<a-icon type="download" />
</a-tooltip>
<a-tooltip class="tool" title="编辑" slot="actions">
<a-icon type="edit" />
</a-tooltip>
<a-tooltip class="tool" title="分享" slot="actions">
<a-icon type="share-alt" />
</a-tooltip>
<a-dropdown class="tool" slot="actions">
<a-icon type="ellipsis" />
<a-menu slot="overlay">
<a-menu-item>1 item</a-menu-item>
<a-menu-item>2 item</a-menu-item>
<a-menu-item>3 item</a-menu-item>
</a-menu>
</a-dropdown>
<div class="content">
<div>
<p>活跃用户</p>
<p>18</p>
</div>
<div>
<p>新增用户</p>
<p>1,338</p>
</div>
</div>
</a-card>
</a-list-item>
</a-list>
</div>
</template>
<script>
import SearchForm from './SearchForm'
export default {
name: 'ApplicationList',
components: {SearchForm}
}
</script>
<style lang="less" scoped>
.clearfix() {
zoom: 1;
&:before,
&:after {
content: ' ';
display: table;
}
&:after {
clear: both;
visibility: hidden;
font-size: 0;
height: 0;
}
}
.content {
.clearfix();
margin-top: 16px;
margin-left: 40px;
& > div {
position: relative;
text-align: left;
float: left;
width: 50%;
p {
line-height: 32px;
font-size: 24px;
margin: 0;
}
p:first-child {
color: @text-color-second;
font-size: 12px;
line-height: 20px;
margin-bottom: 4px;
}
}
}
</style>

View File

@ -1,72 +0,0 @@
<template>
<div>
<search-form />
<a-card :bordered="false">
<a-list itemLayout="vertical">
<a-list-item :key="n" v-for="n in 10">
<a-list-item-meta title="Alipay">
<div slot="description">
<a-tag >Ant Design</a-tag>
<a-tag >设计语言</a-tag>
<a-tag >蚂蚁金服</a-tag>
</div>
</a-list-item-meta>
<div class="content">
<div class="detail">
段落示意蚂蚁金服设计平台 ant.design用最小的工作量无缝接入蚂蚁金服生态提供跨越设计与开发的体验解决方案蚂蚁金服设计平台
ant.design用最小的工作量无缝接入蚂蚁金服生态提供跨越设计与开发的体验解决方案
</div>
<div class="author">
<a-avatar size="small" src="https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png" />
<a>ICZER</a>发布在
<a href="https://github.com/iczer">https://github.com/iczer</a>
<em>2018-08-05 22:23</em>
</div>
</div>
<span slot="actions"><a-icon style="margin-right: 8px" type="star-o" />156</span>
<span slot="actions"><a-icon style="margin-right: 8px" type="like-o" />1435</span>
<span slot="actions"><a-icon style="margin-right: 8px" type="message" />4</span>
</a-list-item>
</a-list>
</a-card>
</div>
</template>
<script>
import SearchForm from './SearchForm'
export default {
name: 'ArticleList',
components: {SearchForm}
}
</script>
<style lang="less" scoped>
.extra{
width: 272px;
height: 1px;
}
.content {
.detail {
line-height: 22px;
max-width: 720px;
}
.author {
color: @text-color-second;
margin-top: 16px;
line-height: 22px;
& > :global(.ant-avatar) {
vertical-align: top;
margin-right: 8px;
width: 20px;
height: 20px;
position: relative;
top: 1px;
}
& > em {
color: @disabled-color;
font-style: normal;
margin-left: 16px;
}
}
}
</style>

View File

@ -1,58 +0,0 @@
<template>
<div>
<search-form />
<a-list
:grid='{ gutter: 24, xl: 4, lg: 3, md: 3, sm: 2, xs: 1 }'
style="margin: 0 -8px"
>
<a-list-item :key="n" v-for="n in 8" style="padding: 0 8px">
<a-card>
<img slot="cover" src="https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png" height="154"/>
<a-card-meta title="Ant Design">
<div slot="description">
城镇中有那么多的酒馆她却偏偏走进了我的酒馆
</div>
</a-card-meta>
<div class="content">
<span>4小时前</span>
<avatar-list>
<avatar-list-item size="small" tips="曲丽丽" src="https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png" />
<avatar-list-item size="small" tips="周星星" src="https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png" />
<avatar-list-item size="small" tips="董娜娜" src="https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png" />
</avatar-list>
</div>
</a-card>
</a-list-item>
</a-list>
</div>
</template>
<script>
import SearchForm from './SearchForm'
import AvatarList from '../../../components/tool/AvatarList'
const AvatarListItem = AvatarList.Item
export default {
name: 'ProjectList',
components: {AvatarListItem, AvatarList, SearchForm}
}
</script>
<style lang="less" scoped>
.content{
display: flex;
margin-top: 16px;
margin-bottom: -4px;
line-height: 20px;
height: 20px;
& > span {
color: @text-color-second;
flex: 1;
font-size: 12px;
}
.avatarList {
flex: 0 1 auto;
}
}
</style>

View File

@ -1,94 +0,0 @@
<template>
<a-card :bordered="false" class="search-form">
<a-form :form="form">
<form-row label="所属类目">
<a-form-item>
<tag-select>
<tag-select-option>类目一</tag-select-option>
<tag-select-option>类目二</tag-select-option>
<tag-select-option>类目三</tag-select-option>
<tag-select-option>类目四</tag-select-option>
<tag-select-option>类目五</tag-select-option>
<tag-select-option>类目六</tag-select-option>
<tag-select-option>类目七</tag-select-option>
<tag-select-option>类目八</tag-select-option>
<tag-select-option>类目九</tag-select-option>
<tag-select-option>类目十</tag-select-option>
<tag-select-option>类目十一</tag-select-option>
<tag-select-option>类目十二</tag-select-option>
<tag-select-option>类目十三</tag-select-option>
<tag-select-option>类目十四</tag-select-option>
<tag-select-option>类目十五</tag-select-option>
<tag-select-option>类目十六</tag-select-option>
</tag-select>
</a-form-item>
</form-row>
<form-row label="owner" style="padding-bottom: 11px">
<a-form-item>
<a-select
mode="multiple" style="max-width: 286px"
v-decorator="['owner', {initialValue: ['1', '2']}]"
>
<a-select-option value="3">我自己</a-select-option>
<a-select-option value="1">吴家豪</a-select-option>
<a-select-option value="2">周星星</a-select-option>
<a-select-option value="4">李宁</a-select-option>
</a-select>
</a-form-item>
<a @click="lookMyself">只看自己的</a>
</form-row>
<form-row label="其他选项">
<a-row>
<a-col :span="8">
<a-form-item label="活跃用户" :labelCol="{span: 6}" :wrapperCol="{span: 12}">
<a-select placeholder="不限">
<a-select-option value="1">周星星</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item
label="好评度"
:labelCol="{span: 6}"
:wrapperCol="{span: 12}"
>
<a-select placeholder="不限">
<a-select-option value="1">优秀</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
</form-row>
</a-form>
</a-card>
</template>
<script>
import TagSelect from '../../../components/tool/TagSelect'
import FormRow from '../../../components/form/FormRow'
const TagSelectOption = TagSelect.Option
export default {
name: 'SearchForm',
components: {FormRow, TagSelectOption, TagSelect},
data() {
return {
form: this.$form.createForm(this)
}
},
methods: {
lookMyself () {
this.form.setFieldsValue({
owner: '3'
})
}
}
}
</script>
<style lang="less" scoped>
.search-form{
margin-bottom: 24px;
}
</style>

View File

@ -1,69 +0,0 @@
<template>
<div>
<div class="search-head">
<div class="search-input">
<a-input-search class="search-ipt" style="width: 522px" placeholder="请输入..." size="large" enterButton="搜索" />
</div>
<div style="padding: 0 24px">
<a-tabs :tabBarStyle="{margin: 0}" @change="navigate" :activeKey="activeKey">
<a-tab-pane tab="文章" key="1"></a-tab-pane>
<a-tab-pane tab="应用" key="2"></a-tab-pane>
<a-tab-pane tab="项目" key="3"></a-tab-pane>
</a-tabs>
</div>
</div>
<div class="search-content">
<router-view />
</div>
</div>
</template>
<script>
export default {
name: 'SearchLayout',
computed: {
activeKey () {
switch (this.$route.path) {
case '/list/search/article':
return '1'
case '/list/search/application':
return '2'
case '/list/search/project':
return '3'
default:
return '1'
}
}
},
methods: {
navigate (key) {
switch (key) {
case '1':
this.$router.push('/list/search/article')
break
case '2':
this.$router.push('/list/search/application')
break
case '3':
this.$router.push('/list/search/project')
break
default:
this.$router.push('/workplace')
}
}
}
}
</script>
<style lang="less" scoped>
.search-head{
background-color: @base-bg-color;
margin: -25px -24px -24px;
.search-input{
text-align: center;
}
}
.search-content{
margin-top: 48px;
}
</style>

View File

@ -111,7 +111,7 @@ export default {
if (result.code >= 0) {
const user = result.data.user
setAuthorization({token: result.data.token, expireAt: new Date(result.data.expireAt)})
this.$router.push('/dashboard/workplace')
this.$router.push('/parent1/demo1')
this.$store.commit('account/setUser', user)
this.$message.success(result.message, 3)
} else {

Some files were not shown because too many files have changed in this diff Show More