zcy hace 4 años
padre
commit
5d5058f31a

+ 2 - 0
package.json

@@ -43,6 +43,8 @@
     "eslint": "6.7.2",
     "eslint-plugin-vue": "6.2.2",
     "html-webpack-plugin": "3.2.0",
+    "less": "^3.9.0",
+    "less-loader": "^5.0.0",
     "mockjs": "1.0.1-beta3",
     "runjs": "4.3.2",
     "sass": "1.26.8",

+ 16 - 1
src/api/request.js

@@ -1,5 +1,12 @@
 import request from '@/utils/request'
 
+export function deleteAction(url, parameter) {
+  return request({
+    url: url + parameter,
+    method: 'delete'
+  })
+}
+
 export function getAction(url, parameter) {
   return request({
     url: url,
@@ -12,6 +19,14 @@ export function postAction(url, parameter) {
   return request({
     url: url,
     method: 'post',
-    params: parameter
+    data: parameter
+  })
+}
+
+export function httpAction(url, parameter, method) {
+  return request({
+    url: url,
+    method: method,
+    data: parameter
   })
 }

+ 246 - 0
src/components/JModal/index.vue

@@ -0,0 +1,246 @@
+<template>
+  <a-modal
+    ref="modal"
+    :class="getClass(modalClass)"
+    :style="getStyle(modalStyle)"
+    :visible="visible"
+    :ok-text="okText"
+    v-bind="_attrs"
+    destroy-on-close
+    v-on="$listeners"
+    @ok="handleOk"
+    @cancel="handleCancel"
+  >
+
+    <slot />
+    <!--有设置标题-->
+    <template v-if="!isNoTitle" slot="title">
+      <a-row class="j-modal-title-row" type="flex">
+        <a-col class="left">
+          <slot name="title">{{ title }}</slot>
+        </a-col>
+        <a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen">
+          <a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon" />
+        </a-col>
+      </a-row>
+    </template>
+    <!--没有设置标题-->
+    <template v-else slot="title">
+      <a-row class="j-modal-title-row" type="flex">
+        <a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen">
+          <a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon" />
+        </a-col>
+      </a-row>
+    </template>
+
+    <!-- 处理 scopedSlots -->
+    <template v-for="slotName of scopedSlotsKeys" :slot="slotName">
+      <slot :name="slotName" />
+    </template>
+
+    <!-- 处理 slots -->
+    <template v-for="slotName of slotsKeys" v-slot:[slotName]>
+      <slot :name="slotName" />
+    </template>
+
+  </a-modal>
+</template>
+
+<script>
+
+import { getClass, getStyle } from '@/utils/props-util'
+import { triggerWindowResizeEvent } from '@/utils/util'
+
+export default {
+  name: 'JModal',
+  props: {
+    title: String,
+    // 可使用 .sync 修饰符
+    visible: Boolean,
+    // 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
+    fullscreen: {
+      type: Boolean,
+      default: false
+    },
+    // 是否允许切换全屏(允许后右上角会出现一个按钮)
+    switchFullscreen: {
+      type: Boolean,
+      default: false
+    },
+    // 点击确定按钮的时候是否关闭弹窗
+    okClose: {
+      type: Boolean,
+      default: true
+    },
+    okText: {
+      type: String,
+      default: '确定'
+    }
+  },
+  data() {
+    return {
+      // 内部使用的 slots ,不再处理
+      usedSlots: ['title'],
+      // 实际控制是否全屏的参数
+      innerFullscreen: this.fullscreen
+    }
+  },
+  computed: {
+    // 一些未处理的参数或特殊处理的参数绑定到 a-modal 上
+    _attrs() {
+      const attrs = { ...this.$attrs }
+      // 如果全屏就将宽度设为 100%
+      if (this.innerFullscreen) {
+        attrs['width'] = '100%'
+      }
+      return attrs
+    },
+    modalClass() {
+      return {
+        'j-modal-box': true,
+        'fullscreen': this.innerFullscreen,
+        'no-title': this.isNoTitle,
+        'no-footer': this.isNoFooter
+      }
+    },
+    modalStyle() {
+      const style = {}
+      // 如果全屏就将top设为 0
+      if (this.innerFullscreen) {
+        style['top'] = '0'
+      }
+      return style
+    },
+    isNoTitle() {
+      return !this.title && !this.allSlotsKeys.includes('title')
+    },
+    isNoFooter() {
+      return this._attrs['footer'] === null
+    },
+    slotsKeys() {
+      return Object.keys(this.$slots).filter(key => !this.usedSlots.includes(key))
+    },
+    scopedSlotsKeys() {
+      return Object.keys(this.$scopedSlots).filter(key => !this.usedSlots.includes(key))
+    },
+    allSlotsKeys() {
+      return Object.keys(this.$slots).concat(Object.keys(this.$scopedSlots))
+    },
+    // 切换全屏的按钮图标
+    fullscreenButtonIcon() {
+      return this.innerFullscreen ? 'fullscreen-exit' : 'fullscreen'
+    }
+  },
+  watch: {
+    visible() {
+      if (this.visible) {
+        this.innerFullscreen = this.fullscreen
+      }
+    },
+    innerFullscreen(val) {
+      this.$emit('update:fullscreen', val)
+    }
+  },
+  methods: {
+
+    getClass(clazz) {
+      return { ...getClass(this), ...clazz }
+    },
+    getStyle(style) {
+      return { ...getStyle(this), ...style }
+    },
+
+    close(boolen) {
+      this.$emit('close', boolen)
+    },
+
+    handleOk() {
+      if (this.okClose) {
+        this.close(true)
+      }
+    },
+    handleCancel() {
+      this.close(false)
+    },
+
+    /** 切换全屏 */
+    toggleFullscreen() {
+      this.innerFullscreen = !this.innerFullscreen
+      triggerWindowResizeEvent()
+    }
+
+  }
+}
+</script>
+
+<style lang="less">
+  .j-modal-box {
+    &.fullscreen {
+      top: 0;
+      left: 0;
+      padding: 0;
+
+      // 兼容1.6.2版本的antdv
+      & .ant-modal {
+        top: 0;
+        padding: 0;
+        height: 100vh;
+      }
+
+      & .ant-modal-content {
+        height: 100vh;
+        border-radius: 0;
+
+        & .ant-modal-body {
+          /* title 和 footer 各占 55px */
+          height: calc(100% - 55px - 55px);
+          overflow: auto;
+        }
+      }
+
+      &.no-title, &.no-footer {
+        .ant-modal-body {
+          height: calc(100% - 55px);
+        }
+      }
+      &.no-title.no-footer {
+        .ant-modal-body {
+          height: 100%;
+        }
+      }
+    }
+
+    .j-modal-title-row {
+      .left {
+        width: calc(100% - 56px - 56px);
+      }
+
+      .right {
+        width: 56px;
+        position: inherit;
+
+        .ant-modal-close {
+          right: 56px;
+          color: rgba(0, 0, 0, 0.45);
+
+          &:hover {
+            color: rgba(0, 0, 0, 0.75);
+          }
+        }
+      }
+    }
+    &.no-title{
+      .ant-modal-header {
+        padding: 0px 24px;
+        border-bottom: 0px !important;
+      }
+    }
+  }
+
+  @media (max-width: 767px) {
+    .j-modal-box.fullscreen {
+      margin: 0;
+      max-width: 100vw;
+    }
+  }
+</style>

+ 120 - 0
src/components/dict/JDictSelectTag.vue

@@ -0,0 +1,120 @@
+<template>
+  <a-radio-group v-if="tagType=='radio'" :value="getValueSting" :disabled="disabled" @change="handleInput">
+    <a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
+  </a-radio-group>
+
+  <a-radio-group
+    v-else-if="tagType=='radioButton'"
+    button-style="solid"
+    :value="getValueSting"
+    :disabled="disabled"
+    @change="handleInput"
+  >
+    <a-radio-button v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio-button>
+  </a-radio-group>
+
+  <a-select
+    v-else-if="tagType=='select'"
+    :size="size"
+    :get-popup-container="getPopupContainer"
+    :placeholder="placeholder"
+    :disabled="disabled"
+    :value="getValueSting"
+    @change="handleInput"
+  >
+    <a-select-option :value="undefined">请选择</a-select-option>
+    <a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
+      <span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
+        {{ item.text || item.label }}
+      </span>
+    </a-select-option>
+  </a-select>
+</template>
+
+<script>
+import { getAction, postAction } from '@/api/request'
+
+export default {
+  name: 'JDictSelectTag',
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  props: {
+    dictCode: String,
+    placeholder: String,
+    disabled: Boolean,
+    value: [String, Number],
+    type: String,
+    getPopupContainer: {
+      type: Function,
+      default: (node) => node.parentNode
+    },
+    size: {
+      type: String,
+      default: 'default'
+    }
+  },
+  data() {
+    return {
+      dictOptions: [],
+      tagType: ''
+    }
+  },
+  computed: {
+    getValueSting() {
+      // update-begin author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
+      // 当有null或“” placeholder不显示
+      return this.value != null ? this.value.toString() : undefined
+      // update-end author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
+    }
+  },
+  watch: {
+    dictCode: {
+      immediate: true,
+      handler() {
+        this.initDictData()
+      }
+    }
+  },
+  created() {
+    // console.log(this.dictCode);
+    if (!this.type || this.type === 'list') {
+      this.tagType = 'select'
+    } else {
+      this.tagType = this.type
+    }
+    // 获取字典数据
+    // this.initDictData();
+  },
+  methods: {
+    initDictData() {
+      // 根据字典Code, 初始化字典数组
+      getAction(`/sys/dict/getDictItems`, { code: this.dictCode }).then((res) => {
+        if (res.code === 200) {
+          this.dictOptions = res.rows
+        }
+      })
+    },
+    handleInput(e = '') {
+      let val
+      if (Object.keys(e).includes('target')) {
+        val = e.target.value
+      } else {
+        val = e
+      }
+      console.log(val)
+      this.$emit('change', val)
+    },
+    setCurrentDictOptions(dictOptions) {
+      this.dictOptions = dictOptions
+    },
+    getCurrentDictOptions() {
+      return this.dictOptions
+    }
+  }
+}
+</script>
+
+<style scoped>
+</style>

+ 127 - 0
src/components/dict/JMultiSelectTag.vue

@@ -0,0 +1,127 @@
+<template>
+  <a-checkbox-group v-if="tagType=='checkbox'" :value="arrayValue" :disabled="disabled" @change="onChange">
+    <a-checkbox v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text || item.label }}</a-checkbox>
+  </a-checkbox-group>
+
+  <a-select
+    v-else-if="tagType=='select'"
+    :value="arrayValue"
+    :disabled="disabled"
+    mode="multiple"
+    :placeholder="placeholder"
+    :get-popup-container="getParentContainer"
+    option-filter-prop="children"
+    :filter-option="filterOption"
+    allow-clear
+    @change="onChange"
+  >
+    <a-select-option
+      v-for="(item,index) in dictOptions"
+      :key="index"
+      :value="item.value"
+    >
+      <span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
+        {{ item.text || item.label }}
+      </span>
+    </a-select-option>
+  </a-select>
+
+</template>
+
+<script>
+import { getAction, postAction } from '@/api/request'
+export default {
+  name: 'JMultiSelectTag',
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  props: {
+    dictCode: String,
+    placeholder: String,
+    disabled: Boolean,
+    value: String,
+    type: String,
+    options: Array,
+    spliter: {
+      type: String,
+      required: false,
+      default: ','
+    },
+    popContainer: {
+      type: String,
+      default: '',
+      required: false
+    }
+  },
+  data() {
+    return {
+      dictOptions: [],
+      tagType: '',
+      arrayValue: !this.value ? [] : this.value.split(this.spliter)
+    }
+  },
+  watch: {
+    options: function(val) {
+      this.setCurrentDictOptions(val)
+    },
+    dictCode: {
+      immediate: true,
+      handler() {
+        this.initDictData()
+      }
+    },
+    value(val) {
+      if (!val) {
+        this.arrayValue = []
+      } else {
+        this.arrayValue = this.value.split(this.spliter)
+      }
+    }
+  },
+  created() {
+    if (!this.type || this.type === 'list_multi') {
+      this.tagType = 'select'
+    } else {
+      this.tagType = this.type
+    }
+    // 获取字典数据
+    // this.initDictData();
+  },
+  methods: {
+    initDictData() {
+      if (this.options && this.options.length > 0) {
+        this.dictOptions = [...this.options]
+      } else {
+        // 根据字典Code, 初始化字典数组
+        getAction(`/sys/dict/getDictItems/${this.dictCode}`, null).then((res) => {
+          if (res.code === 200) {
+            this.dictOptions = res.rows
+          }
+        })
+      }
+    },
+    onChange(selectedValue) {
+      this.$emit('change', selectedValue.join(this.spliter))
+    },
+    setCurrentDictOptions(dictOptions) {
+      this.dictOptions = dictOptions
+    },
+    getCurrentDictOptions() {
+      return this.dictOptions
+    },
+    getParentContainer(node) {
+      if (!this.popContainer) {
+        return node.parentNode
+      } else {
+        return document.querySelector(this.popContainer)
+      }
+    },
+    // update--begin--autor:lvdandan-----date:20201120------for:LOWCOD-1086 下拉多选框,搜索时只字典code进行搜索不能通过字典text搜索
+    filterOption(input, option) {
+      return option.componentOptions.children[0].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+    }
+    // update--end--autor:lvdandan-----date:20201120------for:LOWCOD-1086 下拉多选框,搜索时只字典code进行搜索不能通过字典text搜索
+  }
+}
+</script>

+ 243 - 0
src/components/dict/JSearchSelectTag.vue

@@ -0,0 +1,243 @@
+<template>
+
+  <a-select
+    v-if="async"
+    v-model="selectedAsyncValue"
+    show-search
+    label-in-value
+    :disabled="disabled"
+    :get-popup-container="getParentContainer"
+    :placeholder="placeholder"
+    style="width: 100%"
+    :filter-option="false"
+    allow-clear
+    :not-found-content="loading ? undefined : null"
+    @search="loadData"
+    @change="handleAsyncChange"
+  >
+    <a-spin v-if="loading" slot="notFoundContent" size="small" />
+    <a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
+  </a-select>
+
+  <a-select
+    v-else
+    v-model="selectedValue"
+    :get-popup-container="getParentContainer"
+    show-search
+    :disabled="disabled"
+    :placeholder="placeholder"
+    option-filter-prop="children"
+    style="width: 100%"
+    :filter-option="filterOption"
+    allow-clear
+    :not-found-content="loading ? undefined : null"
+    @change="handleChange"
+  >
+    <a-spin v-if="loading" slot="notFoundContent" size="small" />
+    <a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
+  </a-select>
+
+</template>
+
+<script>
+import { getAction, postAction } from '@/api/request'
+import debounce from 'lodash/debounce'
+
+export default {
+  name: 'JSearchSelectTag',
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  props: {
+    disabled: Boolean,
+    value: [String, Number],
+    dict: String,
+    dictOptions: Array,
+    async: Boolean,
+    placeholder: {
+      type: String,
+      default: '请选择',
+      required: false
+    },
+    popContainer: {
+      type: String,
+      default: '',
+      required: false
+    },
+    pageSize: {
+      type: Number,
+      default: 10,
+      required: false
+    },
+    getPopupContainer: {
+      type: Function,
+      default: null
+    }
+  },
+  data() {
+    this.loadData = debounce(this.loadData, 800)// 消抖
+    this.lastLoad = 0
+    return {
+      loading: false,
+      selectedValue: [],
+      selectedAsyncValue: [],
+      options: []
+    }
+  },
+  watch: {
+    'value': {
+      immediate: true,
+      handler(val) {
+        if (!val) {
+          if (val == 0) {
+            this.initSelectValue()
+          } else {
+            this.selectedValue = []
+            this.selectedAsyncValue = []
+          }
+        } else {
+          this.initSelectValue()
+        }
+      }
+    },
+    'dict': {
+      handler() {
+        this.initDictData()
+      }
+    },
+    'dictOptions': {
+      deep: true,
+      handler(val) {
+        if (val && val.length > 0) {
+          this.options = [...val]
+        }
+      }
+    }
+  },
+  created() {
+    this.initDictData()
+  },
+  methods: {
+    initSelectValue() {
+      if (this.async) {
+        if (!this.selectedAsyncValue || !this.selectedAsyncValue.key || this.selectedAsyncValue.key != this.value) {
+          console.log('这才请求后台')
+          getAction(`/sys/dict/loadDictItem/${this.dict}`, { key: this.value }).then(res => {
+            if (res.code === 200) {
+              const obj = {
+                key: this.value,
+                label: res.result
+              }
+              this.selectedAsyncValue = { ...obj }
+            }
+          })
+        }
+      } else {
+        this.selectedValue = this.value.toString()
+      }
+    },
+    loadData(value) {
+      console.log('数据加载', value)
+      this.lastLoad += 1
+      const currentLoad = this.lastLoad
+      this.options = []
+      this.loading = true
+      // 字典code格式:table,text,code
+      getAction(`/sys/dict/loadDict/${this.dict}`, { keyword: value, pageSize: this.pageSize }).then(res => {
+        this.loading = false
+        if (res.code === 200) {
+          if (currentLoad != this.lastLoad) {
+            return
+          }
+          this.options = res.result
+          console.log('我是第一个', res)
+        } else {
+          this.$message.warning(res.message)
+        }
+      })
+    },
+    initDictData() {
+      if (!this.async) {
+        // 如果字典项集合有数据
+        if (this.dictOptions && this.dictOptions.length > 0) {
+          this.options = [...this.dictOptions]
+        } else {
+          // 根据字典Code, 初始化字典数组
+          let dictStr = ''
+          if (this.dict) {
+            const arr = this.dict.split(',')
+            if (arr[0].indexOf('where') > 0) {
+              const tbInfo = arr[0].split('where')
+              dictStr = tbInfo[0].trim() + ',' + arr[1] + ',' + arr[2] + ',' + encodeURIComponent(tbInfo[1])
+            } else {
+              dictStr = this.dict
+            }
+            getAction(`/sys/dict/getDictItems/${dictStr}`, null).then((res) => {
+              if (res.code === 200) {
+                this.dictOptions = res.rows
+              }
+            })
+          }
+        }
+      } else {
+        // 异步一开始也加载一点数据
+        this.loading = true
+        getAction(`/sys/dict/loadDict/${this.dict}`, { pageSize: this.pageSize, keyword: '' }).then(res => {
+          this.loading = false
+          if (res.success) {
+            this.options = res.result
+          } else {
+            this.$message.warning(res.message)
+          }
+        })
+      }
+    },
+    filterOption(input, option) {
+      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+    },
+    handleChange(selectedValue) {
+      console.log('selectedValue', selectedValue)
+      this.selectedValue = selectedValue
+      this.callback()
+    },
+    handleAsyncChange(selectedObj) {
+      // update-begin-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
+      if (selectedObj) {
+        this.selectedAsyncValue = selectedObj
+        this.selectedValue = selectedObj.key
+      } else {
+        this.selectedAsyncValue = null
+        this.selectedValue = null
+        this.options = null
+        this.loadData('')
+      }
+      this.callback()
+      // update-end-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
+    },
+    callback() {
+      this.$emit('change', this.selectedValue)
+    },
+    setCurrentDictOptions(dictOptions) {
+      this.options = dictOptions
+    },
+    getCurrentDictOptions() {
+      return this.options
+    },
+    getParentContainer(node) {
+      if (typeof this.getPopupContainer === 'function') {
+        return this.getPopupContainer(node)
+      } else if (!this.popContainer) {
+        return node.parentNode
+      } else {
+        return document.querySelector(this.popContainer)
+      }
+    }
+
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 181 - 0
src/components/dict/README.md

@@ -0,0 +1,181 @@
+# JDictSelectTag 组件用法
+----
+- 从字典表获取数据,dictCode格式说明: 字典code
+```html
+<j-dict-select-tag  v-model="queryParam.sex" placeholder="请输入用户性别"
+                  dictCode="sex"/>
+```
+
+v-decorator用法:
+```html
+<j-dict-select-tag  v-decorator="['sex', {}]" :triggerChange="true" placeholder="请输入用户性别"
+                  dictCode="sex"/>
+```
+
+- 从数据库表获取字典数据,dictCode格式说明: 表名,文本字段,取值字段
+```html
+<j-dict-select-tag v-model="queryParam.username" placeholder="请选择用户名称" 
+                   dictCode="sys_user,realname,id"/>
+```
+
+
+
+# JDictSelectUtil.js 列表字典函数用法
+----
+
+- 第一步: 引入依赖方法
+```html
+       import {initDictOptions, filterDictText} from '@/components/dict/JDictSelectUtil'
+```
+
+- 第二步: 在created()初始化方法执行字典配置方法
+```html
+      //初始化字典配置
+      this.initDictConfig();
+```
+      
+- 第三步: 实现initDictConfig方法,加载列表所需要的字典(列表上有多个字典项,就执行多次initDictOptions方法)
+      
+```html
+      initDictConfig() {
+        //初始化字典 - 性别
+        initDictOptions('sex').then((res) => {
+          if (res.success) {
+            this.sexDictOptions = res.result;
+          }
+        });
+      },
+```
+      
+- 第四步: 实现字段的customRender方法
+```html
+     customRender: (text, record, index) => {
+       //字典值替换通用方法
+       return filterDictText(this.sexDictOptions, text);
+     }
+```
+
+
+# JMultiSelectTag 多选组件
+下拉/checkbox
+
+## 参数配置
+| 参数           | 类型   | 必填 |说明|
+|--------------|---------|----|---------|
+| placeholder      |string   | | placeholder |
+| disabled      |Boolean   | | 是否禁用 |
+| type      |string   | | 多选类型 select/checkbox 默认是select |
+| dictCode      |string   | | 数据字典编码或者表名,显示字段名,存储字段名拼接而成的字符串,如果提供了options参数 则此参数可不填|
+| options      |Array   | | 多选项,如果dictCode参数未提供,可以设置此参数加载多选项 |
+
+使用示例
+----
+```vue
+<template>
+  <a-form>
+    <a-form-item label="下拉多选" style="width: 300px">
+      <j-multi-select-tag
+        v-model="selectValue"
+        :options="dictOptions"
+        placeholder="请做出你的选择">
+      </j-multi-select-tag>
+      {{ selectValue }}
+    </a-form-item>
+
+    <a-form-item label="checkbox">
+      <j-multi-select-tag
+        v-model="checkboxValue"
+        :options="dictOptions"
+        type="checkbox">
+      </j-multi-select-tag>
+      {{ checkboxValue }}
+    </a-form-item>
+  </a-form >
+</template>
+
+<script>
+  import JMultiSelectTag from '@/components/dict/JMultiSelectTag'
+  export default {
+    components: {JMultiSelectTag},
+    data() {
+      return {
+        selectValue:"",
+        checkboxValue:"",
+        dictOptions:[{
+          label:"选项一",
+          value:"1"
+        },{
+          label:"选项二",
+          value:"2"
+        },{
+          label:"选项三",
+          value:"3"
+        }]
+      }
+    }
+  }
+</script>
+```
+
+# JSearchSelectTag 字典表的搜索组件
+下拉搜索组件,支持异步加载,异步加载用于大数据量的字典表
+
+## 参数配置
+| 参数           | 类型   | 必填 |说明|
+|--------------|---------|----|---------|
+| placeholder      |string   | | placeholder |
+| disabled      |Boolean   | | 是否禁用 |
+| dict      |string   | | 表名,显示字段名,存储字段名拼接而成的字符串,如果提供了dictOptions参数 则此参数可不填|
+| dictOptions      |Array   | | 多选项,如果dict参数未提供,可以设置此参数加载多选项 |
+| async      |Boolean   | | 是否支持异步加载,设置成true,则通过输入的内容加载远程数据,否则在本地过滤数据,默认false|
+
+使用示例
+----
+```vue
+<template>
+  <a-form>
+    <a-form-item label="下拉搜索" style="width: 300px">
+      <j-search-select-tag
+        placeholder="请做出你的选择"
+        v-model="selectValue"
+        :dictOptions="dictOptions">
+      </j-search-select-tag>
+      {{ selectValue }}
+    </a-form-item>
+
+    <a-form-item label="异步加载" style="width: 300px">
+      <j-search-select-tag
+        placeholder="请做出你的选择"
+        v-model="asyncSelectValue"
+        dict="sys_depart,depart_name,id"
+        :async="true">
+      </j-search-select-tag>
+      {{ asyncSelectValue }}
+    </a-form-item>
+  </a-form >
+</template>
+
+<script>
+  import JSearchSelectTag from '@/components/dict/JSearchSelectTag'
+  export default {
+    components: {JSearchSelectTag},
+    data() {
+      return {
+        selectValue:"",
+        asyncSelectValue:"",
+        dictOptions:[{
+          text:"选项一",
+          value:"1"
+        },{
+          text:"选项二",
+          value:"2"
+        },{
+          text:"选项三",
+          value:"3"
+        }]
+      }
+    }
+  }
+</script>
+```
+

+ 12 - 0
src/components/dict/index.js

@@ -0,0 +1,12 @@
+import JDictSelectTag from './JDictSelectTag.vue'
+import JMultiSelectTag from './JMultiSelectTag.vue'
+import JSearchSelectTag from './JSearchSelectTag.vue'
+
+export default {
+  install: function(Vue) {
+    Vue.component('JDictSelectTag', JDictSelectTag)
+    Vue.component('JMultiSelectTag', JMultiSelectTag)
+    Vue.component('JSearchSelectTag', JSearchSelectTag)
+
+  }
+}

+ 3 - 3
src/layout/components/Navbar.vue

@@ -17,9 +17,9 @@
 
         <screenfull id="screenfull" class="right-menu-item hover-effect" />
 
-        <el-tooltip content="Global Size" effect="dark" placement="bottom">
-          <size-select id="size-select" class="right-menu-item hover-effect" />
-        </el-tooltip>
+<!--        <el-tooltip content="Global Size" effect="dark" placement="bottom">-->
+<!--          <size-select id="size-select" class="right-menu-item hover-effect" />-->
+<!--        </el-tooltip>-->
 
       </template>
 

+ 48 - 9
src/main.js

@@ -4,9 +4,29 @@ import Cookies from 'js-cookie'
 
 import 'normalize.css/normalize.css' // a modern alternative to CSS resets
 
-import Element from 'element-ui'
+import {
+  Card,
+  MenuItem,
+  MenuItemGroup,
+  Menu,
+  Breadcrumb,
+  BreadcrumbItem,
+  Form,
+  FormItem,
+  Input,
+  Tooltip,
+  Button,
+  Row,
+  Col,
+  Dropdown,
+  DropdownItem,
+  DropdownMenu,
+  Select,
+  Option,
+  Switch
+} from 'element-ui'
+
 import './styles/element-variables.scss'
-import enLang from 'element-ui/lib/locale/lang/en'// 如果使用中文语言包请默认支持,无需额外引入,请删除该依赖
 import Antd from 'ant-design-vue'
 import 'ant-design-vue/dist/antd.css'
 
@@ -19,10 +39,12 @@ import router from './router'
 import './icons' // icon
 import './permission' // permission control
 import './utils/error-log' // error log
-
-import * as filters from './filters' // global filters
+import JDictSelectTag from './components/dict/index.js'
+import JMultiSelectTag from './components/dict/index.js'
+import * as filters from './filters'
 Vue.use(Antd)
-
+Vue.use(JDictSelectTag)
+Vue.use(JMultiSelectTag)
 /**
  * If you don't want to use mock-server
  * you want to use MockJs for mock api
@@ -36,10 +58,27 @@ if (process.env.NODE_ENV === 'production') {
   mockXHR()
 }
 
-Vue.use(Element, {
-  size: Cookies.get('size') || 'medium', // set element-ui default size
-  locale: enLang // 如果使用中文,无需设置,请删除
-})
+Vue.use(Switch)
+Vue.use(Option)
+Vue.use(Select)
+Vue.use(Dropdown)
+Vue.use(DropdownItem)
+Vue.use(DropdownMenu)
+Vue.use(Form)
+Vue.use(FormItem)
+Vue.use(Input)
+Vue.use(Tooltip)
+Vue.use(Button)
+Vue.use(Col)
+Vue.use(Row)
+
+
+Vue.use(Card)
+Vue.use(MenuItemGroup)
+Vue.use(MenuItem)
+Vue.use(Menu)
+Vue.use(Breadcrumb)
+Vue.use(BreadcrumbItem)
 
 // register global utility filters
 Object.keys(filters).forEach(key => {

+ 42 - 41
src/mixin/listMixin.js

@@ -3,9 +3,8 @@
  * 高级查询按钮调用 superQuery方法  高级查询组件ref定义为superQueryModal
  * data中url定义 list为查询列表  delete为删除单条记录  deleteBatch为批量删除
  */
-import Vue from 'vue'
-import { filterObj } from '@/utils/util'
-import { postAction, getAction } from '@/api/request'
+import {filterObj} from '@/utils/util'
+import {postAction, getAction, deleteAction} from '@/api/request'
 import store from '@/store'
 
 export const listMixin = {
@@ -61,7 +60,7 @@ export const listMixin = {
   computed: {
     // token header
     tokenHeader() {
-      const head = { 'Authorization': store.getters.token }
+      const head = {'Authorization': store.getters.token}
       return head
     }
   },
@@ -77,18 +76,18 @@ export const listMixin = {
       }
       var params = this.getQueryParams()// 查询条件
       this.loading = true
-      postAction(this.url.list, params).then((res) => {
-        if (res.success) {
+      getAction(this.url.list, params).then((res) => {
+        if (res.code === 200) {
           // update-begin---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
-          this.dataSource = res.result.records || res.result
-          if (res.result.total) {
-            this.ipagination.total = res.result.total
+          this.dataSource = res.rows
+          if (res.total) {
+            this.ipagination.total = res.total
           } else {
             this.ipagination.total = 0
           }
           // update-end---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
         } else {
-          this.$message.warning(res.message)
+          this.$message.warning(res.msg)
         }
       }).finally(() => {
         this.loading = false
@@ -116,16 +115,16 @@ export const listMixin = {
         sqp['superQueryParams'] = encodeURI(this.superQueryParams)
         sqp['superQueryMatchType'] = this.superQueryMatchType
       }
-      var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters)
-      param.field = this.getQueryField()
-      param.pageNo = this.ipagination.current
+      var param = Object.assign(sqp, this.queryParam)
+      // param.field = this.getQueryField()
+      param.pageNum = this.ipagination.current
       param.pageSize = this.ipagination.pageSize
       return filterObj(param)
     },
     getQueryField() {
       // TODO 字段权限控制
       var str = 'id,'
-      this.columns.forEach(function(value) {
+      this.columns.forEach(function (value) {
         str += ',' + value.dataIndex
       })
       return str
@@ -149,8 +148,8 @@ export const listMixin = {
       this.queryParam = {}
       this.loadData(1)
     },
-    batchDel: function() {
-      if (!this.url.deleteBatch) {
+    batchDel: function () {
+      if (!this.url.delete) {
         this.$message.error('请设置url.deleteBatch属性!')
         return
       }
@@ -166,17 +165,17 @@ export const listMixin = {
         this.$confirm({
           title: '确认删除',
           content: '是否删除选中数据?',
-          onOk: function() {
+          onOk: function () {
             that.loading = true
-            postAction(that.url.deleteBatch, { ids: ids }).then((res) => {
-              if (res.success) {
+            deleteAction(that.url.delete, ids).then((res) => {
+              if (res.code === 200) {
                 // 重新计算分页问题
                 that.reCalculatePage(that.selectedRowKeys.length)
-                that.$message.success(res.message)
+                that.$message.success(res.msg)
                 that.loadData()
                 that.onClearSelected()
               } else {
-                that.$message.warning(res.message)
+                that.$message.warning(res.msg)
               }
             }).finally(() => {
               that.loading = false
@@ -185,20 +184,20 @@ export const listMixin = {
         })
       }
     },
-    handleDelete: function(id) {
+    handleDelete: function (id) {
       if (!this.url.delete) {
         this.$message.error('请设置url.delete属性!')
         return
       }
       var that = this
-      deleteAction(that.url.delete, { id: id }).then((res) => {
-        if (res.success) {
+      deleteAction(that.url.delete, id).then((res) => {
+        if (res.code === 200) {
           // 重新计算分页问题
           that.reCalculatePage(1)
-          that.$message.success(res.message)
+          that.$message.success(res.msg)
           that.loadData()
         } else {
-          that.$message.warning(res.message)
+          that.$message.warning(res.msg)
         }
       })
     },
@@ -213,12 +212,15 @@ export const listMixin = {
       }
       console.log('currentIndex', currentIndex)
     },
-    handleEdit: function(record) {
+    handleEdit: function (record) {
       this.$refs.modalForm.edit(record)
       this.$refs.modalForm.title = '编辑'
       this.$refs.modalForm.disableSubmit = false
     },
-    handleAdd: function() {
+    handleAdd: function () {
+      console.log(this.$refs);
+      debugger
+      console.log(this.$refs.modalForm);
       this.$refs.modalForm.add()
       this.$refs.modalForm.title = '新增'
       this.$refs.modalForm.disableSubmit = false
@@ -247,7 +249,7 @@ export const listMixin = {
       // 清空列表选中
       this.onClearSelected()
     },
-    handleDetail: function(record) {
+    handleDetail: function (record) {
       this.$refs.modalForm.edit(record)
       this.$refs.modalForm.title = '详情'
       this.$refs.modalForm.disableSubmit = true
@@ -273,9 +275,9 @@ export const listMixin = {
           return
         }
         if (typeof window.navigator.msSaveBlob !== 'undefined') {
-          window.navigator.msSaveBlob(new Blob([data], { type: 'application/vnd.ms-excel' }), fileName + '.xls')
+          window.navigator.msSaveBlob(new Blob([data], {type: 'application/vnd.ms-excel'}), fileName + '.xls')
         } else {
-          const url = window.URL.createObjectURL(new Blob([data], { type: 'application/vnd.ms-excel' }))
+          const url = window.URL.createObjectURL(new Blob([data], {type: 'application/vnd.ms-excel'}))
           const link = document.createElement('a')
           link.style.display = 'none'
           link.href = url
@@ -298,16 +300,16 @@ export const listMixin = {
         if (info.file.response.success) {
           // this.$message.success(`${info.file.name} 文件上传成功`);
           if (info.file.response.code === 201) {
-            const { message, result: { msg, fileUrl, fileName }} = info.file.response
+            const {message, result: {msg, fileUrl, fileName}} = info.file.response
             const href = fileUrl
             this.$warning({
-              title: message,
-              content: (<div>
-                <span>{msg}</span><br/>
-                <span>具体详情请 <a href={href} target='_blank' download={fileName}>点击下载</a> </span>
-              </div>
-              )
-            })
+                title: message,
+                content: ( < div >
+                  < span > {msg} < /span><br/ >
+                  < span > 具体详情请 < a href = {href} target = '_blank' download = {fileName} > 点击下载 < /a> </span >
+              < /div>
+            )
+          })
           } else {
             this.$message.success(info.file.response.message || `${info.file.name} 文件上传成功`)
           }
@@ -328,8 +330,7 @@ export const listMixin = {
               mask: false,
               onOk: () => {
                 store.dispatch('Logout').then(() => {
-                  Vue.ls.remove(ACCESS_TOKEN)
-                  window.location.reload()
+                  this.$router.push(`/login?redirect=${this.$route.fullPath}`)
                 })
               }
             })

+ 113 - 0
src/utils/props-util.js

@@ -0,0 +1,113 @@
+/**
+ * 该文件截取自 "ant-design-vue/es/_util/props-util.js" 文件,并对其做出特殊修改
+ */
+function classNames() {
+  const classes = []
+
+  for (let i = 0; i < arguments.length; i++) {
+    const arg = arguments[i]
+    if (!arg) continue
+
+    const argType = typeof arg
+
+    if (argType === 'string' || argType === 'number') {
+      classes.push(arg)
+    } else if (Array.isArray(arg) && arg.length) {
+      const inner = classNames.apply(null, arg)
+      if (inner) {
+        classes.push(inner)
+      }
+    } else if (argType === 'object') {
+      for (const key in arg) {
+        if (arg.hasOwnProperty(key) && arg[key]) {
+          classes.push(key)
+        }
+      }
+    }
+  }
+  return classes.join(' ')
+}
+
+const camelizeRE = /-(\w)/g
+
+function camelize(str) {
+  return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))
+}
+
+function objectCamelize(obj) {
+  const res = {}
+  Object.keys(obj).forEach(k => (res[camelize(k)] = obj[k]))
+  return res
+}
+
+function parseStyleText(cssText = '', camel) {
+  const res = {}
+  const listDelimiter = /;(?![^(]*\))/g
+  const propertyDelimiter = /:(.+)/
+  cssText.split(listDelimiter).forEach(function(item) {
+    if (item) {
+      const tmp = item.split(propertyDelimiter)
+      if (tmp.length > 1) {
+        const k = camel ? camelize(tmp[0].trim()) : tmp[0].trim()
+        res[k] = tmp[1].trim()
+      }
+    }
+  })
+  return res
+}
+
+export function getClass(ele) {
+  let data = {}
+  if (ele.data) {
+    data = ele.data
+  } else if (ele.$vnode && ele.$vnode.data) {
+    data = ele.$vnode.data
+  }
+  const tempCls = data.class || {}
+  const staticClass = data.staticClass
+  let cls = {}
+  staticClass &&
+  staticClass.split(' ').forEach(c => {
+    cls[c.trim()] = true
+  })
+  if (typeof tempCls === 'string') {
+    tempCls.split(' ').forEach(c => {
+      cls[c.trim()] = true
+    })
+  } else if (Array.isArray(tempCls)) {
+    classNames(tempCls)
+      .split(' ')
+      .forEach(c => {
+        cls[c.trim()] = true
+      })
+  } else {
+    cls = { ...cls, ...tempCls }
+  }
+  return cls
+}
+
+export function getStyle(ele, camel) {
+  getClass(ele)
+
+  let data = {}
+  if (ele.data) {
+    data = ele.data
+  } else if (ele.$vnode && ele.$vnode.data) {
+    data = ele.$vnode.data
+  }
+
+  // update-begin-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
+  let style = data.style || {}
+  let staticStyle = data.staticStyle
+  staticStyle = staticStyle ? objectCamelize(data.staticStyle) : {}
+  // update-end-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
+
+  if (typeof style === 'string') {
+    style = parseStyleText(style, camel)
+  } else if (camel && style) {
+    // 驼峰化
+    style = objectCamelize(style)
+  }
+  return { ...staticStyle, ...style }
+}
+

+ 3 - 4
src/utils/request.js

@@ -48,8 +48,9 @@ service.interceptors.response.use(
     } else {
       const res = response.data
       // if the custom code is not 20000, it is judged as an error.
-      if (res.code !== 0) {
-        debugger
+      if (res.code === 200) {
+        return res
+      } else {
         Message({
           message: res.msg || 'Error',
           type: 'error',
@@ -70,8 +71,6 @@ service.interceptors.response.use(
           })
         }
         return Promise.reject(new Error(res.msg || 'Error'))
-      } else {
-        return res
       }
     }
   },

+ 3 - 0
src/utils/util.js

@@ -75,3 +75,6 @@ export function formatDate(value, fmt) {
     return value.substr(0, fmt.length)
   }
 }
+
+
+

+ 111 - 0
src/views/basics/pillar/CheckAndEditModel.vue

@@ -0,0 +1,111 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="800"
+    :visible="visible"
+    :mask-closable="false"
+    cancel-text="关闭"
+    @close="close"
+  >
+    <a-form-model ref="form" :label-col="labelCol" :wrapper-col="wrapperCol" :rules="validatorRules" :model="model">
+      <a-form-model-item label="文书名称" prop="name">
+        <a-input v-model="model.name" />
+      </a-form-model-item>
+<!--      <a-form-model-item label="文书类型" prop="type">-->
+<!--        <j-dict-select-tag-->
+<!--          v-model="model.type"-->
+<!--          style="width: 360px"-->
+<!--          dict-code="word_type"-->
+<!--        />-->
+<!--      </a-form-model-item>-->
+      <a-form-model-item label="文书描述" prop="remarks">
+        <a-input v-model="model.remarks" />
+      </a-form-model-item>
+    </a-form-model>
+  </j-modal>
+</template>
+<script>
+import { httpAction } from '@/api/request'
+import JModal from '@/components/JModal'
+export default {
+  name: 'CheckAndEditModel',
+  components: {
+    JModal
+  },
+  data() {
+    return {
+      labelCol: { span: 4 },
+      wrapperCol: { span: 14 },
+      dataSource: [],
+      title: '',
+      visible: false,
+      isCheck: false,
+      model: {},
+      validatorRules: {
+        name: [{ required: true, message: '请输入' }],
+        type: [{ required: true, message: '请选择' }]
+      },
+      url: {
+        add: '/business/catenary/bus/zzdzxx/add',
+        edit: '/business/catenary/bus/zzdzxx/update'
+      }
+    }
+  },
+  created() {
+  },
+  methods: {
+    add() {
+      this.model = {}
+      this.visible = true
+    },
+    edit(record) {
+      debugger
+      this.model = Object.assign({}, record)
+      this.visible = true
+    },
+    close(isSubmit) {
+      if (isSubmit) {
+        this.checkData()
+      } else {
+        this.visible = false
+      }
+    },
+    checkData() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.saveData()
+        } else {
+          return false
+        }
+      })
+    },
+    saveData(result) {
+      let url, type
+      if (!this.model.id) {
+        url = this.url.add
+        type = 'post'
+      } else {
+        debugger
+        url = this.url.edit
+        type = 'put'
+      }
+      if (result) {
+        this.model.fileName = result.fileName
+        this.model.tempUrl = result.tempUrl
+      } else {
+        this.model.fileName = ''
+        this.model.tempUrl = ''
+      }
+      httpAction(url, this.model, type).then((res) => {
+        if (res.code === 200) {
+          this.$message.success(res.msg)
+          this.$emit('ok')
+          this.visible = false
+        } else {
+          console.log(res)
+        }
+      })
+    }
+  }
+}
+</script>

+ 64 - 82
src/views/basics/pillar/index.vue

@@ -5,16 +5,53 @@
     <div class="table-page-search-wrapper">
       <!-- 搜索区域 -->
       <a-form layout="inline" @keyup.enter.native="searchQuery">
-            <a-form-item label="名称" :label-col="{span: 5}" :wrapper-col="{span: 18, offset: 1}">
-              <a-input v-model="queryParam.roleName" placeholder="请输入名称查询" />
-            </a-form-item>
-            <a-form-item label="创建时间" :label-col="{span: 5}" :wrapper-col="{span: 18, offset: 1}">
-              <a-input v-model="queryParam.roleName" placeholder="请输入名称查询" />
-            </a-form-item>
-          <a-form-item>
-              <a-button type="primary" @click="searchQuery">查询</a-button>
-              <a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
-          </a-form-item>
+        <a-form-item>
+          <j-dict-select-tag
+            v-model="queryParam.xb"
+            style="width: 150px"
+            placeholder="选择线别"
+            dict-code="sj_plan_status"
+          />
+        </a-form-item>
+        <a-form-item>
+          <j-dict-select-tag
+            v-model="queryParam.sb"
+            style="width: 150px"
+            placeholder="选择所别"
+            dict-code="sj_plan_status"
+          />
+        </a-form-item>
+        <a-form-item>
+          <j-dict-select-tag
+            v-model="queryParam.hb"
+            style="width: 150px"
+            placeholder="选择行别"
+            dict-code="sj_plan_status"
+          />
+        </a-form-item>
+        <a-form-item>
+          <j-dict-select-tag
+            v-model="queryParam.yy"
+            style="width: 150px"
+            placeholder="选择原因类型"
+            dict-code="sj_plan_status"
+          />
+        </a-form-item>
+        <a-form-item>
+          <a-input
+            v-model="queryParam.glb"
+            style="width: 150px"
+            placeholder="输入公里标"
+          />
+        </a-form-item>
+        <a-form-item>
+          <a-date-picker v-model="queryParam.date1" format="YYYY/MM/DD" placeholder="时间范围" />-
+          <a-date-picker v-model="queryParam.date2" format="YYYY/MM/DD" placeholder="时间范围" />
+        </a-form-item>
+        <a-form-item>
+          <a-button type="primary" @click="searchQuery">查询</a-button>
+          <a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
+        </a-form-item>
       </a-form>
     </div>
 
@@ -57,25 +94,18 @@
       >
 
         <span slot="action" slot-scope="text, record">
-          <a @click="handleEdit(record)">编辑</a>
+          <a-button size="small" type="primary" @click="handleEdit(record)">
+            编辑
+          </a-button>
           <a-divider type="vertical" />
-          <a-dropdown>
-            <a class="ant-dropdown-link">
-              更多 <a-icon type="down" />
-            </a>
-            <a-menu slot="overlay">
-              <a-menu-item>
-                <a @click="handlePerssion(record.id)">授权</a>
-              </a-menu-item>
-              <a-menu-item>
-                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
-                  <a>删除</a>
-                </a-popconfirm>
-              </a-menu-item>
-            </a-menu>
-          </a-dropdown>
+          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+            <a-button size="small" type="danger">
+              删除
+            </a-button>
+          </a-popconfirm>
         </span>
       </a-table>
+      <check-and-edit-model ref="modalForm" @ok="modalFormOk" />
     </div>
     <!-- table区域-end -->
     <!-- 表单区域 -->
@@ -83,68 +113,24 @@
 </template>
 <script>
 import { listMixin } from '@/mixin/listMixin'
+import columns from './indexColumns'
+import CheckAndEditModel from './CheckAndEditModel'
+
 export default {
   name: 'RoleList',
   components: {
+    CheckAndEditModel
   },
   mixins: [listMixin],
   data() {
     return {
-      description: '角色管理页面',
       // 查询条件
-      queryParam: { roleName: '' },
+      queryParam: {},
       // 表头
-      columns: [
-        {
-          title: '#',
-          dataIndex: '',
-          key: 'rowIndex',
-          width: 60,
-          align: 'center',
-          customRender: function(t, r, index) {
-            return parseInt(index) + 1
-          }
-        },
-        {
-          title: '角色名称',
-          align: 'center',
-          dataIndex: 'roleName'
-        },
-        {
-          title: '角色编码',
-          align: 'center',
-          dataIndex: 'roleCode'
-        },
-        {
-          title: '备注',
-          align: 'center',
-          dataIndex: 'description'
-        },
-        {
-          title: '创建时间',
-          dataIndex: 'createTime',
-          align: 'center',
-          sorter: true
-        },
-        {
-          title: '更新时间',
-          dataIndex: 'updateTime',
-          align: 'center',
-          sorter: true
-        },
-        {
-          title: '操作',
-          dataIndex: 'action',
-          align: 'center',
-          scopedSlots: { customRender: 'action' }
-        }
-      ],
+      columns: columns(this),
       url: {
-        list: '/business/bus/zzdzxx/list',
-        delete: '/sys/role/delete',
-        deleteBatch: '/sys/role/deleteBatch',
-        exportXlsUrl: '/sys/role/exportXls',
-        importExcelUrl: 'sys/role/importExcel'
+        list: '/business/catenary/bus/zzdzxx/list',
+        delete: '/business/catenary/bus/zzdzxx/'
       }
     }
   },
@@ -154,10 +140,6 @@ export default {
     }
   },
   methods: {
-    handlePerssion: function(roleId) {
-      // alert(roleId);
-      this.$refs.modalUserRole.show(roleId)
-    }
   }
 }
 </script>

+ 79 - 0
src/views/basics/pillar/indexColumns.js

@@ -0,0 +1,79 @@
+function columns(vm) {
+  const cols = [
+    {
+      title: '序号',
+      key: 'rowIndex',
+      width: 60,
+      align: 'center',
+      customRender: function(t, r, index) {
+        return parseInt(index) + 1
+      }
+    },
+    {
+      title: '线别',
+      align: 'center',
+      dataIndex: 'xb',
+      scopedSlots: { customRender: 'xb' },
+      key: 'xb',
+      width: 300
+    },
+    {
+      title: '区间/站场',
+      align: 'center',
+      dataIndex: 'qj',
+      key: 'qj'
+    },
+    {
+      title: '车间/工区',
+      align: 'center',
+      dataIndex: 'bm',
+      key: 'bm'
+    },
+    {
+      title: '行别',
+      align: 'center',
+      dataIndex: 'hb',
+      key: 'hb'
+    },
+    {
+      title: '支柱号',
+      align: 'center',
+      dataIndex: 'zzh',
+      key: 'zzh'
+    },
+    {
+      title: '公里标',
+      align: 'center',
+      dataIndex: 'glb',
+      key: 'glb'
+    },
+    {
+      title: '规格型号',
+      align: 'center',
+      dataIndex: 'zzxh',
+      key: 'zzxh'
+    },
+    {
+      title: '支柱类型',
+      align: 'center',
+      dataIndex: 'zzlx',
+      key: 'zzlx'
+    },
+    {
+      title: '安装时间',
+      align: 'center',
+      dataIndex: 'createTime',
+      key: 'createTime'
+    },
+    {
+      title: '操作',
+      dataIndex: 'action',
+      align: 'center',
+      slots: { title: 'actionName' },
+      scopedSlots: { customRender: 'action' }
+    }
+  ]
+  return cols
+}
+
+export default columns

+ 1 - 1
src/views/login/index.vue

@@ -94,7 +94,7 @@
             type="primary"
             style="width:100%;margin-bottom:30px;"
             @click.native.prevent="handleLogin"
-          ><h2 style="margin: 5px">登  录</h2>
+          ><h2 style="margin: 5px;color: white">登  录</h2>
           </el-button>
         </el-form>
       </el-col>