Browse Source

Added Table
Added QueryList

Sendya 6 years ago
parent
commit
ee08fcfe69

+ 2 - 0
package.json

@@ -24,6 +24,8 @@
     "@vue/cli-plugin-babel": "^3.0.1",
     "@vue/cli-plugin-eslint": "^3.0.1",
     "@vue/cli-service": "^3.0.1",
+    "less": "^3.8.1",
+    "less-loader": "^4.1.0",
     "node-sass": "^4.9.0",
     "sass-loader": "^7.0.1",
     "vue-template-compiler": "^2.5.17"

+ 1 - 1
public/index.html

@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="zh-cmn-Hans">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">

+ 12 - 0
src/App.vue

@@ -1,9 +1,21 @@
 <template>
+  <a-locale-provider :locale="locale">
   <div id="app">
     <router-view/>
   </div>
+  </a-locale-provider>
 </template>
+<script>
+  import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
 
+  export default {
+    data () {
+      return {
+        locale: zhCN,
+      }
+    }
+  }
+</script>
 <style>
   #app {
     height: 100%;

+ 2 - 2
src/components/ChartCard.vue

@@ -1,5 +1,5 @@
 <template>
-    <a-card :body-style="{ padding: '20px 24px 8px' }" :bordered="false">
+    <a-card :loading="loading" :body-style="{ padding: '20px 24px 8px' }" :bordered="false">
         <div class="chart-card-header">
             <div class="meta">
                 <span class="chart-card-title">{{ title }}</span>
@@ -23,7 +23,7 @@
 <script>
   export default {
     name: "ChartCard",
-    props: ['title', 'total']
+    props: ['title', 'total', 'loading']
   }
 </script>
 

+ 3 - 1
src/components/LayoutContent.vue

@@ -4,7 +4,9 @@
 
             <!-- pageHeader , route meta hideHeader:true on hide -->
             <s-page-header></s-page-header>
-            <s-route-view></s-route-view>
+            <div class="content">
+                <s-route-view></s-route-view>
+            </div>
         </div>
 
         <s-route-view v-else></s-route-view>

+ 46 - 0
src/components/LayoutFooter.vue

@@ -0,0 +1,46 @@
+<template>
+    <div class="footer">
+        <div class="links">
+            <a href="#">Pro 首页</a>
+            <a href="#"><a-icon type="github"/></a>
+            <a href="#">Ant Design</a>
+        </div>
+        <div class="copyright">
+            Copyright <a-icon type="copyright" /> 2018 <span>白鹭学园技术组出品</span>
+        </div>
+    </div>
+</template>
+
+<script>
+  export default {
+    name: "LayoutFooter"
+  }
+</script>
+
+<style lang="scss" scoped>
+    .footer {
+        padding: 0 16px;
+        margin: 48px 0 24px;
+        text-align: center;
+
+        .links {
+            margin-bottom: 8px;
+
+            a {
+                color: rgba(0,0,0,.45);
+
+                &:hover {
+                    color: rgba(0,0,0,.65);
+                }
+
+                &:not(:last-child) {
+                    margin-right: 40px;
+                }
+            }
+        }
+        .copyright {
+            color: rgba(0,0,0,.45);
+            font-size: 14px;
+        }
+    }
+</style>

+ 5 - 1
src/components/chart/Bar.vue

@@ -1,7 +1,11 @@
 <template>
     <div :style="{ padding: '0 0 32px 32px' }">
         <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
-        <v-chart :force-fit="true" height="254" :data="data" :padding="['auto', 'auto', 40, 50]">
+        <v-chart
+                height="254"
+                :data="data"
+                :forceFit="true"
+                :padding="['auto', 'auto', '40', '50']">
             <v-tooltip />
             <v-axis />
             <v-bar position="x*y"/>

+ 250 - 0
src/components/table/StandardTable.vue

@@ -0,0 +1,250 @@
+<template>
+    <div class="standard-table">
+        <div class="alert">
+            <a-alert type="info" :show-icon="true">
+                <div slot="message">
+                    已选择&nbsp;<a style="font-weight: 600">{{ selectedRows.length }}</a>&nbsp;&nbsp;
+                    <template v-for="(item, index) in needTotalList" v-if="item.needTotal">
+                        {{ item.title }} 总计&nbsp;
+                        <a :key="index" style="font-weight: 600">
+                            {{ item.customRender ? item.customRender(item.total) : item.total }}
+                        </a>&nbsp;&nbsp;
+                    </template>
+                    <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+                </div>
+            </a-alert>
+        </div>
+        <a-table
+           :size="size"
+           :bordered="bordered"
+           :loading="loading"
+           :columns="columns"
+           :dataSource="current"
+           :rowKey="rowKey"
+           :pagination="pagination"
+           :rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: updateSelect }"
+        >
+        </a-table>
+    </div>
+</template>
+
+<script>
+  export default {
+    name: "StandardTable",
+    // props: ['bordered', 'loading', 'columns', 'data', 'rowKey', 'pagination', 'selectedRows'],
+    props: {
+
+      /**
+       * 数据加载函数,返回值必须是 Promise
+       * 默认情况下必须传递 data 参数;
+       *    如果使用本地数据渲染表格,业务代码中将获取本地数据包装为 Promise 即可。
+       *
+       * currentData 用于向外暴露表格当前渲染的数据,
+       * 业务开发中也可以直接修改 currentData,从而重新渲染表格(仅推荐用于客户端排序、数据过滤等场景)
+       */
+      data: {
+        type: Function,
+        required: true
+      },
+      dataSource: {
+        type: Array,
+        default () {
+          return []
+        }
+      },
+      columns: {
+        type: Array,
+        required: true
+      },
+/*      pagination: {
+        type: Object,
+        default () {
+          return {}
+        }
+      },*/
+      pageSize: {
+        type: Number,
+        default: 10
+      },
+      pageNum: {
+        type: Number,
+        default: 1
+      },
+      pageSizeOptions: {
+        type: Array,
+        default () {
+          return ['10', '20', '30', '40', '50']
+        }
+      },
+      responseParamsName: {
+        type: Object,
+        default () {
+          return {}
+        }
+      },
+      bordered: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * 表格大小风格,default, middle, small
+       */
+      size: {
+        type: String,
+        default: 'default'
+      },
+      rowKey: {
+        type: String
+      },
+      selectedRows: {
+        type: Array
+      }
+    },
+    data () {
+      return {
+        needTotalList: [],
+        selectedRowKeys: [],
+
+        loading: true,
+
+        total: 0,
+        pageNumber: this.pageNum,
+        currentPageSize: this.pageSize,
+        defaultCurrent: 1,
+        sortParams: {},
+
+        current: [],
+        pagination: {},
+        paramsName: {},
+      }
+    },
+    created () {
+      //数据请求参数配置
+      this.paramsName = Object.assign(
+        {},
+        {
+          pageNumber: "pageNo",
+          pageSize: "pageSize",
+          total: "totalCount",
+          results: "data",
+          sortColumns: "sortColumns"
+        },
+        this.responseParamsName
+      );
+
+      this.needTotalList = this.initTotalList(this.columns)
+
+      // load data
+      this.loadData( { pageNum: this.pageNumber } )
+    },
+    methods: {
+      updateSelect (selectedRowKeys, selectedRows) {
+        this.selectedRowKeys = selectedRowKeys
+        let list = this.needTotalList
+        this.needTotalList = list.map(item => {
+          return {
+            ...item,
+            total: selectedRows.reduce((sum, val) => {
+              return sum + val[item.dataIndex]
+            }, 0)
+          }
+        })
+        this.$emit('change', selectedRowKeys, selectedRows)
+      },
+      initTotalList (columns) {
+        const totalList = []
+        columns.forEach(column => {
+          if (column.needTotal) {
+            totalList.push({ ...column, total: 0 })
+          }
+        })
+        return totalList
+      },
+
+      loadData (params) {
+        let that = this
+        that.loading = true
+        params = Object.assign({}, params)
+        const remoteParams = Object.assign({}, that.sortParams)
+        remoteParams[that.paramsName.pageNumber] = params.pageNum || that.pageNumber
+        remoteParams[that.paramsName.pageSize] = params.pageSize || that.currentPageSize
+
+        if (params.pageNum) {
+          that.pageNumber = params.pageNum
+        }
+        if (params.pageSize) {
+          that.currentPageSize = params.pageSize
+        }
+
+        let dataPromise = that.data(remoteParams)
+
+        dataPromise.then( response => {
+          if (!response) {
+            that.loading = false
+            return
+          }
+          let results = response[that.paramsName.results]
+          results = (results instanceof Array && results) || []
+
+          that.current = results
+
+          that.$emit("update:currentData", that.current.slice())
+          that.$emit("dataloaded", that.current.slice())
+
+          that.total = response[that.paramsName.total] * 1
+          that.pagination = that.pager()
+          that.loading = false
+        }, () => {
+          // error callback
+          that.loading = false
+        })
+      },
+      // eslint-disable-next-line
+      onPagerChange (page, pageSize) {
+        this.pageNumber = page
+        this.loadData({ pageNum: page })
+      },
+      onPagerSizeChange (current, size) {
+        this.currentPageSize = size
+        /*
+        if (current === this.pageNumber) this.loadData()
+        console.log('page-size-change', current, size)
+        */
+      },
+      onClearSelected () {
+        this.selectedRowKeys = []
+        this.updateSelect([], [])
+      },
+      pager () {
+        return {
+          total: this.total,
+          showTotal: total => `共有 ${total} 条`,
+          showSizeChanger: true,
+          pageSizeOptions: this.pageSizeOptions,
+          pageSize: this.pageSize,
+          defaultCurrent: this.defaultCurrent,
+          onChange: this.onPagerChange,
+          onShowSizeChange: this.onPagerSizeChange
+        }
+      }
+    },
+    watch: {
+      'selectedRows': function (selectedRows) {
+        this.needTotalList = this.needTotalList.map(item => {
+          return {
+            ...item,
+            total: selectedRows.reduce( (sum, val) => {
+              return sum + val[item.dataIndex]
+            }, 0)
+          }
+        })
+      }
+    }
+  }
+</script>
+
+<style scoped>
+    .alert {
+        margin-bottom: 16px;
+    }
+</style>

+ 3 - 3
src/main.js

@@ -5,14 +5,14 @@ import store from './store/'
 
 import { VueAxios } from "@/utils/request"
 
-import AntDesign from 'ant-design-vue'
+import Antd from 'ant-design-vue'
 import Viser from 'viser-vue'
-import 'ant-design-vue/dist/antd.css';  // or 'ant-design-vue/dist/antd.less'
+import 'ant-design-vue/dist/antd.less';  // or 'ant-design-vue/dist/antd.less'
 
 
 import '@/permission' // permission control
 
-Vue.use(AntDesign)
+Vue.use(Antd)
 Vue.use(VueAxios, router)
 Vue.use(Viser)
 

+ 6 - 1
src/views/Layout.vue

@@ -8,6 +8,9 @@
             <s-layout-header :collapsed="collapsed" @toggle="toggle"></s-layout-header>
             <!-- layout content -->
             <s-layout-content></s-layout-content>
+            <a-layout-footer style="padding: 0px">
+                <s-layout-footer />
+            </a-layout-footer>
         </a-layout>
     </a-layout>
 </template>
@@ -16,6 +19,7 @@
 import SiderMenu from '@/components/menu/SiderMenu'
 import LayoutHeader from '@/components/LayoutHeader'
 import LayoutContent from '@/components/LayoutContent'
+import LayoutFooter from '@/components/LayoutFooter'
 import { asyncRouterMap } from '@/router/index'
 
 export default {
@@ -23,7 +27,8 @@ export default {
   components: {
     "s-sider-menu": SiderMenu,
     "s-layout-header": LayoutHeader,
-    "s-layout-content": LayoutContent
+    "s-layout-content": LayoutContent,
+    "s-layout-footer": LayoutFooter
   },
   data() {
     return {

+ 3 - 2
src/views/Login.vue

@@ -22,7 +22,7 @@
                       fieldDecoratorId="username"
                       :fieldDecoratorOptions="{rules: [{ required: true, message: '请输入帐户名或邮箱地址' }, { validator: this.handleUsernameOrEmail }], validateTrigger: 'blur'}"
               >
-                <a-input size="large" type="text" v-model="formLogin.username" placeholder="帐户名或邮箱地址">
+                <a-input size="large" type="text" v-model="formLogin.username" placeholder="帐户名或邮箱地址 / admin">
                   <a-icon slot="prefix" type='user' :style="{ color: 'rgba(0,0,0,.25)' }" />
                 </a-input>
               </a-form-item>
@@ -30,7 +30,7 @@
               <a-form-item
                       fieldDecoratorId="password"
                       :fieldDecoratorOptions="{rules: [{ required: true, message: '请输入密码' }], validateTrigger: 'blur'}">
-                <a-input size="large" type="password" v-model="formLogin.password" placeholder="密码">
+                <a-input size="large" type="password" v-model="formLogin.password" placeholder="密码 / admin">
                   <a-icon slot="prefix" type='lock' :style="{ color: 'rgba(0,0,0,.25)' }" />
                 </a-input>
               </a-form-item>
@@ -207,6 +207,7 @@
                                   this.$notification['success']({
                                       message: '提示',
                                       description: '验证码获取成功,您的验证码为:' + res.result.captcha,
+                                      duration: 8
                                   })
                               })
                               .catch(err => {

+ 50 - 19
src/views/dashboard/Analysis.vue

@@ -2,7 +2,7 @@
     <div>
         <a-row :gutter="24">
             <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
-                <chart-card title="总销售额" total="¥126,560">
+                <chart-card :loading="loading" title="总销售额" total="¥126,560">
                     <a-tooltip title="指标说明" slot="action">
                         <a-icon type="info-circle-o" />
                     </a-tooltip>
@@ -18,11 +18,11 @@
                             <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span>
                         </div>
                     </div>
-                    <div slot="footer">日均销售额      <span>¥ 234.56</span></div>
+                    <div slot="footer">日均销售额<span>¥ 234.56</span></div>
                 </chart-card>
             </a-col>
             <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
-                <chart-card title="总销售额" total="¥126,560">
+                <chart-card :loading="loading" title="总销售额" total="¥126,560">
                     <a-tooltip title="指标说明" slot="action">
                         <a-icon type="info-circle-o" />
                     </a-tooltip>
@@ -33,7 +33,7 @@
                 </chart-card>
             </a-col>
             <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
-                <chart-card title="总销售额" total="¥126,560">
+                <chart-card :loading="loading" title="总销售额" total="¥126,560">
                     <a-tooltip title="指标说明" slot="action">
                         <a-icon type="info-circle-o" />
                     </a-tooltip>
@@ -49,11 +49,11 @@
                             <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span>
                         </div>
                     </div>
-                    <div slot="footer">日均销售额      <span>¥ 234.56</span></div>
+                    <div slot="footer">日均销售额<span>¥ 234.56</span></div>
                 </chart-card>
             </a-col>
             <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
-                <chart-card title="总销售额" total="¥126,560">
+                <chart-card :loading="loading" title="总销售额" total="¥126,560">
                     <a-tooltip title="指标说明" slot="action">
                         <a-icon type="info-circle-o" />
                     </a-tooltip>
@@ -69,12 +69,12 @@
                             <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span>
                         </div>
                     </div>
-                    <div slot="footer">日均销售额      <span>¥ 234.56</span></div>
+                    <div slot="footer">日均销售额<span>¥ 234.56</span></div>
                 </chart-card>
             </a-col>
         </a-row>
 
-        <a-card :bordered="false" :body-style="{padding: '0'}">
+        <a-card :loading="loading" :bordered="false" :body-style="{padding: '0'}">
             <div class="salesCard">
                 <a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
                     <div class="extra-wrapper" slot="tabBarExtraContent">
@@ -84,7 +84,7 @@
                             <a>本月</a>
                             <a>本年</a>
                         </div>
-                        <a-range-picker :style="{width: '256px'}"></a-range-picker>
+                        <a-range-picker :style="{width: '256px'}" />
                     </div>
                     <a-tab-pane loading="true" tab="销售额" key="1">
                         <a-row>
@@ -110,16 +110,40 @@
 
         <a-row :gutter="12">
             <a-col :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
-                <a-card :bordered="false" title="Card Title" :style="{ marginTop: '24px' }">
-                    <a href="#" slot="extra">more</a>
+                <a-card :loading="loading" :bordered="false" title="线上热门搜索" :style="{ marginTop: '24px' }">
+                    <a-dropdown :trigger="['click']" placement="bottomLeft" slot="extra">
+                        <a class="ant-dropdown-link" href="#">
+                            <a-icon type="ellipsis" />
+                        </a>
+                        <a-menu slot="overlay">
+                            <a-menu-item>
+                                <a href="javascript:;">操作一</a>
+                            </a-menu-item>
+                            <a-menu-item>
+                                <a href="javascript:;">操作二</a>
+                            </a-menu-item>
+                        </a-menu>
+                    </a-dropdown>
                     <p>card content</p>
                     <p>card content</p>
                     <p>card content</p>
                 </a-card>
             </a-col>
             <a-col :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
-                <a-card :bordered="false" title="Card Title"  :style="{ marginTop: '24px' }">
-                    <a href="#" slot="extra">more</a>
+                <a-card :loading="loading" :bordered="false" title="销售额类别占比"  :style="{ marginTop: '24px' }">
+                    <a-dropdown :trigger="['click']" placement="bottomLeft" slot="extra">
+                        <a class="ant-dropdown-link" href="#">
+                            <a-icon type="ellipsis" />
+                        </a>
+                        <a-menu slot="overlay">
+                            <a-menu-item>
+                                <a href="javascript:;">操作一</a>
+                            </a-menu-item>
+                            <a-menu-item>
+                                <a href="javascript:;">操作二</a>
+                            </a-menu-item>
+                        </a-menu>
+                    </a-dropdown>
                     <p>card content</p>
                     <p>card content</p>
                     <p>card content</p>
@@ -130,30 +154,27 @@
 </template>
 
 <script>
+  import moment from "moment"
   import ChartCard from '@/components/ChartCard'
   import ACol from "ant-design-vue/es/grid/Col"
   import ATooltip from "ant-design-vue/es/tooltip/Tooltip"
-  import ADatePicker from 'ant-design-vue/es/date-picker'
   import MiniArea from '@/components/chart/MiniArea'
   import RankList from '@/components/chart/RankList'
   import Bar from '@/components/chart/Bar'
 
-  const ARangePicker = ADatePicker.RangePicker
   const rankList = []
   for (let i = 0; i < 7; i++) {
     rankList.push({
-      name: '桃源村' + (i+1) + '号店',
+      name: '白鹭岛 ' + (i+1) + ' 号店',
       total: 1234.56 - i * 100
     })
   }
 
-
   export default {
     name: "Analysis",
     components: {
       ATooltip,
       ACol,
-      ARangePicker,
       ChartCard,
       MiniArea,
       RankList,
@@ -161,8 +182,15 @@
     },
     data() {
       return {
+        moment,
+        loading: true,
         rankList
       }
+    },
+    created() {
+      setTimeout(() => {
+        this.loading = !this.loading
+      }, 1000)
     }
   }
 </script>
@@ -170,10 +198,13 @@
 <style lang="scss" scoped>
     .extra-wrapper {
         line-height: 55px;
+        padding-right: 24px;
+
         .extra-item{
             display: inline-block;
             margin-right: 24px;
-            a{
+
+            a {
                 margin-left: 24px;
             }
         }

+ 182 - 6
src/views/list/TableList.vue

@@ -1,15 +1,191 @@
 <template>
-    <div>
-        TableList
-    </div>
+    <a-card :bordered="false">
+        <div :class="advanced ? 'search' : null">
+            <a-form layout="horizontal">
+                <div :class="advanced ? null : 'fold'">
+                    <a-row :gutter="48">
+                        <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 :gutter="48" 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>
+
+        <standard-table
+            size="default"
+            :columns="columns"
+            :data="loadData"
+            :selectedRows="selectedRows"
+            @change="onChange"
+        >
+        </standard-table>
+    </a-card>
 </template>
 
 <script>
+  import StandardTable from '@/components/table/StandardTable'
+  import AForm from "ant-design-vue/es/form/Form";
+
+  const data = []
+
+  for (let i = 0; i < 100; i++) {
+    data.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: "TableList"
+    name: "TableList",
+    components: {
+      AForm,
+      StandardTable
+    },
+    data () {
+      return {
+        // 高级搜索 展开/关闭
+        advanced: false,
+        // 查询参数
+        queryParam: {},
+        // 表头
+        columns: [
+          {
+            title: '规则编号',
+            dataIndex: 'no'
+          },
+          {
+            title: '描述',
+            dataIndex: 'description'
+          },
+          {
+            title: '服务调用次数',
+            dataIndex: 'callNo',
+            sorter: true,
+            needTotal: true,
+            customRender: (text) => text + ' 次'
+          },
+          {
+            title: '状态',
+            dataIndex: 'status',
+            needTotal: true
+          },
+          {
+            title: '更新时间',
+            dataIndex: 'updatedAt',
+            sorter: true
+          }
+        ],
+        // 加载数据方法 必须为 Promise 对象
+        loadData: parameter => {
+          return this.$http.get('/service', {
+            params: Object.assign(parameter, this.queryParam)
+          }).then(res => {
+            return res.result
+          })
+        },
+        selectedRowKeys: [],
+        selectedRows: []
+      }
+    },
+    methods: {
+
+      onChange (selectedRowKeys, selectedRows) {
+        this.selectedRowKeys = selectedRowKeys
+        this.selectedRows = selectedRows
+      },
+      toggleAdvanced () {
+        this.advanced = !this.advanced
+      },
+    }
   }
 </script>
 
-<style scoped>
-
+<style lang="scss" 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>

+ 12 - 0
vue.config.js

@@ -6,6 +6,18 @@ module.exports = {
       chunks: ['chunk-vendors', 'chunk-common', 'index']
     }
   },
+  css: {
+    loaderOptions: {
+      less: {
+        modifyVars: {
+          'primary-color': '#1DA57A',
+          'link-color': '#1DA57A',
+          'border-radius-base': '2px',
+        },
+        javascriptEnabled: true,
+      }
+    }
+  },
   devServer: {
     proxy: {
       '/api': {

+ 47 - 2
yarn.lock

@@ -1293,6 +1293,10 @@ arrify@^1.0.0, arrify@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
 
+asap@~2.0.3:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+
 asn1.js@^4.0.0:
   version "4.10.1"
   resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
@@ -1935,6 +1939,10 @@ clone@^1.0.2:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
 
+clone@^2.1.1, clone@^2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
+
 co@^4.6.0:
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -2863,7 +2871,7 @@ entities@~1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
 
-errno@^0.1.3, errno@~0.1.7:
+errno@^0.1.1, errno@^0.1.3, errno@~0.1.7:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
   dependencies:
@@ -3935,6 +3943,10 @@ ignore@^3.3.3, ignore@^3.3.5:
   version "3.3.10"
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
 
+image-size@~0.5.0:
+  version "0.5.5"
+  resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"
+
 import-cwd@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
@@ -4501,6 +4513,29 @@ lcid@^1.0.0:
   dependencies:
     invert-kv "^1.0.0"
 
+less-loader@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.1.0.tgz#2c1352c5b09a4f84101490274fd51674de41363e"
+  dependencies:
+    clone "^2.1.1"
+    loader-utils "^1.1.0"
+    pify "^3.0.0"
+
+less@^3.8.1:
+  version "3.8.1"
+  resolved "https://registry.yarnpkg.com/less/-/less-3.8.1.tgz#f31758598ef5a1930dd4caefa9e4340641e71e1d"
+  dependencies:
+    clone "^2.1.2"
+  optionalDependencies:
+    errno "^0.1.1"
+    graceful-fs "^4.1.2"
+    image-size "~0.5.0"
+    mime "^1.4.1"
+    mkdirp "^0.5.0"
+    promise "^7.1.1"
+    request "^2.83.0"
+    source-map "~0.6.0"
+
 levn@^0.3.0, levn@~0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
@@ -4808,6 +4843,10 @@ mime@1.4.1:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
 
+mime@^1.4.1:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
+
 mime@^2.0.3, mime@^2.1.0:
   version "2.3.1"
   resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369"
@@ -5890,6 +5929,12 @@ promise-inflight@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
 
+promise@^7.1.1:
+  version "7.3.1"
+  resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+  dependencies:
+    asap "~2.0.3"
+
 proxy-addr@~2.0.3:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93"
@@ -6231,7 +6276,7 @@ request@2.87.0:
     tunnel-agent "^0.6.0"
     uuid "^3.1.0"
 
-request@^2.87.0:
+request@^2.83.0, request@^2.87.0:
   version "2.88.0"
   resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
   dependencies: