From b2bcbec3fafc7c06f84d6746ab55f05b4284a556 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E9=99=8C?= <xiaomo.drip@gmail.com>
Date: Wed, 7 Jun 2023 18:31:42 +0800
Subject: [PATCH] no message

---
 src/assets/style/theme/theme-base.scss |  16 +-
 src/assets/style/theme/theme.scss      |   6 +
 src/assets/style/yxt-public.scss       |  16 +-
 src/components/index.js                |   1 +
 src/components/x-avatar/index.vue      | 143 +++++
 src/config/d2p-extends/types.js        | 383 +++++++-----
 src/views/system/user/crud.js          | 779 +++++++++++++------------
 7 files changed, 783 insertions(+), 561 deletions(-)
 create mode 100644 src/components/x-avatar/index.vue

diff --git a/src/assets/style/theme/theme-base.scss b/src/assets/style/theme/theme-base.scss
index 4d420b9..0bd2612 100644
--- a/src/assets/style/theme/theme-base.scss
+++ b/src/assets/style/theme/theme-base.scss
@@ -27,7 +27,7 @@
   .d2-layout-header-aside-content {
     @extend %full;
     .d2-theme-header {
-      height: 60px;
+      height: 50px;
       .d2-theme-header-menu {
         overflow: hidden;
         &.is-scrollable {
@@ -53,7 +53,7 @@
           }
         }
         .d2-theme-header-menu__prev, .d2-theme-header-menu__next {
-          height: 60px;
+          height: 50px;
           position: absolute;
           top: 0;
           font-size: 20px;
@@ -121,7 +121,7 @@
         float: left;
         text-align: center;
         img {
-          height: 60px;
+          height: 50px;
         }
       }
       .logo-transition {
@@ -130,8 +130,8 @@
       // 折叠侧边栏切换按钮
       .toggle-aside-btn {
         float: left;
-        height: 60px;
-        width: 60px;
+        height: 50px;
+        width: 25px;
         display: flex;
         justify-content: center;
         align-items: center;
@@ -167,7 +167,7 @@
       // 顶栏右侧的按钮
       .d2-header-right {
         float: right;
-        height: 60px;
+        height: 50px;
         display: flex;
         align-items: center;
         .btn-text {
@@ -244,7 +244,7 @@
           height: 41px;
           // 多页面控制器
           .d2-multiple-page-control-group {
-            padding-right: 20px;
+            padding-right: 16px;
             .d2-multiple-page-control-content {
               overflow: auto;
               position: relative;
@@ -285,7 +285,7 @@
             .d2-container-full {
               position: absolute;
               top: 0px;
-              right: 20px;
+              right: 16px;
               bottom: 0px;
               left: 0px;
               display: flex;
diff --git a/src/assets/style/theme/theme.scss b/src/assets/style/theme/theme.scss
index 243c3a7..681a35c 100644
--- a/src/assets/style/theme/theme.scss
+++ b/src/assets/style/theme/theme.scss
@@ -1,6 +1,12 @@
 // 每个主题特有的设置
 .theme-#{$theme-name} {
 
+  .page-compact {
+    .d2-crud-pagination{
+      padding: 5px 0;
+    }
+  }
+
   .el-message {
     &.el-message--info {
       background-color: $theme-message-info-background-color;
diff --git a/src/assets/style/yxt-public.scss b/src/assets/style/yxt-public.scss
index b59894f..1519e21 100644
--- a/src/assets/style/yxt-public.scss
+++ b/src/assets/style/yxt-public.scss
@@ -48,22 +48,22 @@
 /*滚动条凹槽的颜色,还可以设置边框属性 */
 *::-webkit-scrollbar-track-piece {
   background-color: #f8f8f8;
-  -webkit-border-radius: 2em;
-  -moz-border-radius: 2em;
-  border-radius: 2em;
+  -webkit-border-radius: 1em;
+  -moz-border-radius: 1em;
+  border-radius: 1em;
 }
 /*滚动条的宽度*/
 *::-webkit-scrollbar {
-  width: 9px;
-  height: 9px;
+  width: 6px;
+  height: 6px; 
 }
 /*滚动条的设置*/
 *::-webkit-scrollbar-thumb {
   background-color: #dddddd;
   background-clip: padding-box;
-  -webkit-border-radius: 2em;
-  -moz-border-radius: 2em;
-  border-radius: 2em;
+  -webkit-border-radius: 1em;
+  -moz-border-radius: 1em;
+  border-radius: 1em;
 }
 /*滚动条鼠标移上去*/
 *::-webkit-scrollbar-thumb:hover {
diff --git a/src/components/index.js b/src/components/index.js
index 7ad05b2..66ab344 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -12,4 +12,5 @@ Vue.component('manyToMany', () => import('./many-to-many/index.vue'))
 Vue.component('d2p-tree-selector', () => import('./tree-selector/lib/tree-selector.vue'))
 Vue.component('dept-format', () => import('./dept-format/lib/dept-format.vue'))
 Vue.component('dvaHtml2pdf', () => import('./dvaHtml2pdf/index.vue'))
+Vue.component('x-avatar', () => import('./x-avatar/index.vue'))
 Vue.component('table-progress', tableProgress)
diff --git a/src/components/x-avatar/index.vue b/src/components/x-avatar/index.vue
new file mode 100644
index 0000000..44cee7b
--- /dev/null
+++ b/src/components/x-avatar/index.vue
@@ -0,0 +1,143 @@
+<template>
+  <span class="d2p-image-format">
+     <el-image
+       :style="{width:imgWidth,height:imgHeight,borderRadius:imgborderRadius,border:'1px solid #eee'}"
+       v-for="url in urls"  :key="url" :src="url"
+       v-bind="_elProps" >
+        <div slot="placeholder" class="image-slot">
+        </div>
+       <template v-if="error==='slot'">
+         <div slot="error" class="image-slot">
+            <slot name="error"/>
+         </div>
+       </template>
+       <template v-else-if="error">
+         <div slot="error" class="image-slot">
+            <img :src="error" width="50%"/>
+         </div>
+       </template>
+     </el-image>
+  </span>
+</template>
+
+<script>
+// 图片行展示组件
+export default {
+  name: 'x-avatar',
+  props: {
+    // 图片的url
+    // 'url' 或 ['url1','url2']
+    value: {
+      type: [String, Array],
+      require: true
+    },
+    // 图片的宽度设置
+    width: {
+      require: false,
+      default: 30
+    },
+    // 图片的高度设置
+    height: {
+      require: false,
+      default: 30
+    },
+    // 图片的高度设置
+    borderRadius: {
+      require: false,
+      default: 4
+    },
+    fit: {
+      default: 'contain'
+    },
+    // 内部封装[el-image](https://element.eleme.cn/#/zh-CN/component/image)组件的属性参数<br/>
+    elProps: {
+      type: Object
+    },
+    error: {
+      default: undefined
+    },
+    // 构建下载url方法
+    buildUrl: {
+      type: Function,
+      default: function (value, item) { return value }
+    }
+  },
+  data () {
+    return {
+    }
+  },
+  computed: {
+    urls () {
+      const urls = []
+      if (this.value == null || this.value === '') {
+        return urls
+      }
+      if (typeof (this.value) === 'string') {
+        urls.push(this.value)
+      } else if (this.value instanceof Array) {
+        for (const item of this.value) {
+          if (item == null) {
+            continue
+          }
+          if (item.url != null) {
+            urls.push(item.url)
+          } else {
+            urls.push(item)
+          }
+        }
+      } else {
+        urls.push(this.value.url)
+      }
+      const arr = []
+      for (const url of urls) {
+        arr.push(this.buildUrl(url))
+      }
+      return arr
+    },
+    imgborderRadius () {
+      if (typeof (this.borderRadius) === 'number') {
+        return this.borderRadius + 'px'
+      }
+      return this.borderRadius
+    },
+    imgHeight () {
+      if (typeof (this.height) === 'number') {
+        return this.height + 'px'
+      }
+      return this.height
+    },
+    imgWidth () {
+      if (typeof (this.width) === 'number') {
+        return this.width + 'px'
+      }
+      return this.width
+    },
+    _elProps () {
+      const defaultElProps = { fit: this.fit, previewSrcList: this.urls }
+      Object.assign(defaultElProps, this.elProps)
+      return defaultElProps
+    }
+  },
+  mounted () {
+  },
+  methods: {
+    handleClick () {
+      // this.$emit('input', !this.value)
+    }
+  }
+}
+</script>
+<style lang="scss">
+.d2p-image-format{
+  .image-slot{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 100%;
+  }
+  .el-image-viewer__close {
+    color: #fff;
+  }
+}
+
+</style>
diff --git a/src/config/d2p-extends/types.js b/src/config/d2p-extends/types.js
index c052b87..d48b08d 100644
--- a/src/config/d2p-extends/types.js
+++ b/src/config/d2p-extends/types.js
@@ -1,170 +1,235 @@
 import util from '@/libs/util.js'
 export default {
-  'image-uploader': {
-    form: { component: { name: 'd2p-file-uploader', props: { elProps: { listType: 'picture-card', accept: '.png,.jpeg,.jpg,.ico,.bmp,.gif' } } } },
-    component: { name: 'd2p-images-format' },
-    view: {
-      component: { props: { height: 100, width: 100 } }
-    },
-    align: 'center',
-    // 提交时,处理数据
-    valueResolve (row, col) {
-      const value = row[col.key]
-      if (value != null) {
-        if (value.length >= 0) {
-          if (value instanceof Array) {
-            row[col.key] = value.toString()
-          } else {
-            row[col.key] = value
-          }
-        } else {
-          row[col.key] = null
+    'image-uploader': {
+        form: {
+            component: {
+                name: 'd2p-file-uploader',
+                props: {
+                    elProps: {
+                        listType: 'picture-card',
+                        accept: '.png,.jpeg,.jpg,.ico,.bmp,.gif'
+                    }
+                }
+            }
+        },
+        component: {
+            name: 'd2p-images-format'
+        },
+        view: {
+            component: {
+                props: {
+                    height: 100,
+                    width: 100
+                }
+            }
+        },
+        align: 'center',
+        // 提交时,处理数据
+        valueResolve(row, col) {
+            const value = row[col.key]
+            if (value != null) {
+                if (value.length >= 0) {
+                    if (value instanceof Array) {
+                        row[col.key] = value.toString()
+                    } else {
+                        row[col.key] = value
+                    }
+                } else {
+                    row[col.key] = null
+                }
+            }
+        },
+        // 接收时,处理数据
+        valueBuilder(row, col) {
+            const value = row[col.key]
+            if (value != null && value) {
+                row[col.key] = value.split(',')
+                // 进行组装地址,纠正地址
+                row[col.key].map((val, index) => {
+                    if (val.startsWith('/api')) {
+                        row[col.key][index] = val
+                    } else if (val.startsWith('/')) {
+                        row[col.key][index] = util.baseURL() + val.slice(1)
+                    } else {
+                        row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
+                    }
+                })
+            }
         }
-      }
     },
-    // 接收时,处理数据
-    valueBuilder (row, col) {
-      const value = row[col.key]
-      if (value != null && value) {
-        row[col.key] = value.split(',')
-        // 进行组装地址,纠正地址
-        row[col.key].map((val, index) => {
-          if (val.startsWith('/api')) {
-            row[col.key][index] = val
-          } else if (val.startsWith('/')) {
-            row[col.key][index] = util.baseURL() + val.slice(1)
-          } else {
-            row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
-          }
-        })
-      }
-    }
-  },
-  'avatar-uploader': {
-    form: { component: { name: 'd2p-file-uploader', props: { elProps: { limit: 1, listType: 'avatar', accept: '.png,.jpeg,.jpg,.ico,.bmp,.gif', showFileList: false } } } },
-    component: { name: 'd2p-images-format' },
-    view: {
-      component: { props: { height: 100, width: 100 } }
-    },
-    align: 'center',
-    // 提交时,处理数据
-    valueResolve (row, col) {
-      const value = row[col.key]
-      if (value != null) {
-        if (value.length >= 0) {
-          if (value instanceof Array) {
-            row[col.key] = value.toString()
-          } else {
-            row[col.key] = value
-          }
-        } else {
-          row[col.key] = null
+    'avatar-uploader': {
+        form: {
+            component: {
+                name: 'd2p-file-uploader',
+                props: {
+                    elProps: {
+                        limit: 1,
+                        listType: 'avatar',
+                        accept: '.png,.jpeg,.jpg,.ico,.bmp,.gif',
+                        showFileList: false
+                    }
+                }
+            }
+        },
+        component: {
+            name: 'd2p-images-format'
+        },
+        view: {
+            component: {
+                props: {
+                    height: 100,
+                    width: 100
+                }
+            }
+        },
+        align: 'center',
+        // 提交时,处理数据
+        valueResolve(row, col) {
+            const value = row[col.key]
+            if (value != null) {
+                if (value.length >= 0) {
+                    if (value instanceof Array) {
+                        row[col.key] = value.toString()
+                    } else {
+                        row[col.key] = value
+                    }
+                } else {
+                    row[col.key] = null
+                }
+            }
+        },
+        // 接收时,处理数据
+        valueBuilder(row, col) {
+            const value = row[col.key]
+            if (value != null && value) {
+                row[col.key] = value.split(',')
+                // 进行组装地址,纠正地址
+                row[col.key].map((val, index) => {
+                    if (val.startsWith('/api')) {
+                        row[col.key][index] = val
+                    } else if (val.startsWith('/')) {
+                        row[col.key][index] = util.baseURL() + val.slice(1)
+                    } else {
+                        row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
+                    }
+                })
+            }
         }
-      }
     },
-    // 接收时,处理数据
-    valueBuilder (row, col) {
-      const value = row[col.key]
-      if (value != null && value) {
-        row[col.key] = value.split(',')
-        // 进行组装地址,纠正地址
-        row[col.key].map((val, index) => {
-          if (val.startsWith('/api')) {
-            row[col.key][index] = val
-          } else if (val.startsWith('/')) {
-            row[col.key][index] = util.baseURL() + val.slice(1)
-          } else {
-            row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
-          }
-        })
-      }
-    }
-  },
-  'file-uploader': {
-    form: { component: { name: 'd2p-file-uploader', props: { elProps: { listType: 'text' } } } },
-    component: { name: 'd2p-files-format' },
-    // 提交时,处理数据
-    valueResolve (row, col) {
-      const value = row[col.key]
-      if (value != null) {
-        if (value.length >= 0) {
-          if (value instanceof Array) {
-            row[col.key] = value.toString()
-          } else {
-            row[col.key] = value
-          }
-        } else {
-          row[col.key] = null
+    'file-uploader': {
+        form: {
+            component: {
+                name: 'd2p-file-uploader',
+                props: {
+                    elProps: {
+                        listType: 'text'
+                    }
+                }
+            }
+        },
+        component: {
+            name: 'd2p-files-format'
+        },
+        // 提交时,处理数据
+        valueResolve(row, col) {
+            const value = row[col.key]
+            if (value != null) {
+                if (value.length >= 0) {
+                    if (value instanceof Array) {
+                        row[col.key] = value.toString()
+                    } else {
+                        row[col.key] = value
+                    }
+                } else {
+                    row[col.key] = null
+                }
+            }
+        },
+        // 接收时,处理数据
+        valueBuilder(row, col) {
+            const value = row[col.key]
+            if (value != null && value) {
+                row[col.key] = value.split(',')
+                // 进行组装地址,纠正地址
+                row[col.key].map((val, index) => {
+                    if (val.startsWith('/api')) {
+                        row[col.key][index] = val
+                    } else if (val.startsWith('/')) {
+                        row[col.key][index] = util.baseURL() + val.slice(1)
+                    } else {
+                        row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
+                    }
+                })
+            }
         }
-      }
     },
-    // 接收时,处理数据
-    valueBuilder (row, col) {
-      const value = row[col.key]
-      if (value != null && value) {
-        row[col.key] = value.split(',')
-        // 进行组装地址,纠正地址
-        row[col.key].map((val, index) => {
-          if (val.startsWith('/api')) {
-            row[col.key][index] = val
-          } else if (val.startsWith('/')) {
-            row[col.key][index] = util.baseURL() + val.slice(1)
-          } else {
-            row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
-          }
-        })
-      }
-    }
-  },
-  'avatar-cropper': {
-    form: { component: { name: 'd2p-cropper-uploader', props: { accept: '.png,.jpeg,.jpg,.ico,.bmp,.gif', cropper: { viewMode: 1 } } } },
-    component: { name: 'd2p-images-format' },
-    align: 'center',
-    view: {
-      component: { 
-        props: { height: 100, width: 100 },
-        slots:{ //scoped插槽jsx
-             default:(h,scope)=>{ //默认的scoped插槽
-                return ('<div>{scope.data}</div>')
-             }
-          },
-      }
-    },
-    // 提交时,处理数据
-    valueResolve (row, col) {
-      const value = row[col.key]
-      if (value != null) {
-        if (value.length >= 0) {
-          if (value instanceof Array) {
-            row[col.key] = value.toString()
-          } else {
-            row[col.key] = value
-          }
-        } else {
-          row[col.key] = null
+    'avatar-cropper': {
+        form: {
+            component: {
+                name: 'd2p-cropper-uploader',
+                props: {
+                    accept: '.png,.jpeg,.jpg,.ico,.bmp,.gif',
+                    cropper: {
+                        viewMode: 1
+                    }
+                }
+            }
+        },
+        component: {
+            name: 'x-avatar'
+        },
+        align: 'center',
+        view: {
+            component: {
+                props: {
+                    height: 100,
+                    width: 100
+                },
+            }
+        },
+        // 提交时,处理数据
+        valueResolve(row, col) {
+            const value = row[col.key]
+            if (value != null) {
+                if (value.length >= 0) {
+                    if (value instanceof Array) {
+                        row[col.key] = value.toString()
+                    } else {
+                        row[col.key] = value
+                    }
+                } else {
+                    row[col.key] = null
+                }
+            }
+        },
+        // 接收时,处理数据
+        valueBuilder(row, col) {
+            const value = row[col.key]
+            if (value != null && value) {
+                row[col.key] = value.split(',')
+                // 进行组装地址,纠正地址
+                row[col.key].map((val, index) => {
+                    if (val.startsWith('/api')) {
+                        row[col.key][index] = val
+                    } else if (val.startsWith('/')) {
+                        row[col.key][index] = util.baseURL() + val.slice(1)
+                    } else {
+                        row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
+                    }
+                })
+            }
         }
-      }
     },
-    // 接收时,处理数据
-    valueBuilder (row, col) {
-      const value = row[col.key]
-      if (value != null && value) {
-        row[col.key] = value.split(',')
-        // 进行组装地址,纠正地址
-        row[col.key].map((val, index) => {
-          if (val.startsWith('/api')) {
-            row[col.key][index] = val
-          } else if (val.startsWith('/')) {
-            row[col.key][index] = util.baseURL() + val.slice(1)
-          } else {
-            row[col.key][index] = !val.startsWith('http') ? util.baseURL() + val : val
-          }
-        })
-      }
+    'tree-selector': {
+        form: {
+            component: {
+                name: 'd2p-tree-selector',
+                props: {}
+            }
+        },
+        component: {
+            name: 'values-format',
+            props: {}
+        }
     }
-  },
-  'tree-selector': {
-    form: { component: { name: 'd2p-tree-selector', props: { } } },
-    component: { name: 'values-format', props: {} }
-  }
-}
+}
\ No newline at end of file
diff --git a/src/views/system/user/crud.js b/src/views/system/user/crud.js
index 04d0509..1f95d49 100644
--- a/src/views/system/user/crud.js
+++ b/src/views/system/user/crud.js
@@ -1,394 +1,401 @@
-import { request } from '@/api/service'
-
+import {
+    request
+} from '@/api/service'
 export const crudOptions = (vm) => {
-  // util.filterParams(vm, ['dept_name', 'role_info{name}', 'dept_name_all'])
-  return {
-    pageOptions: {
-      compact: true
-    },
-    options: {
-      height: '100%',
-      // tableType: 'vxe-table',
-      // rowKey: true,
-      rowId: 'id'
-    },
-    selectionRow: {
-      align: 'center',
-      width: 46
-    },
-    rowHandle: {
-      width: 240,
-      fixed: 'right',
-      view: {
-        thin: true,
-        text: '',
-        disabled () {
-          return !vm.hasPermissions('Retrieve')
+    // util.filterParams(vm, ['dept_name', 'role_info{name}', 'dept_name_all'])
+    return {
+        pageOptions: {
+            compact: true
         },
-      },
-      edit: {
-        thin: true,
-        text: '',
-        disabled () {
-          return !vm.hasPermissions('Update')
-        }
-      },
-      remove: {
-        thin: true,
-        text: '',
-        disabled () {
-          return !vm.hasPermissions('Delete')
-        }
-      },
-      custom: [
-        {
-          thin: true,
-          text: '密码重置',
-          size: 'small',
-          type: 'warning',
-          icon: 'el-icon-refresh-left',
-          show () {
-            return vm.hasPermissions('ResetPassword')
-          },
-          emit: 'resetPassword'
-        }
-      ]
-    },
-    viewOptions: {
-      componentType: 'form'
-    },
-    formOptions: {
-      defaultSpan: 12 // 默认的表单 span
-    },
-    // indexRow: { // 或者直接传true,不显示title,不居中
-    //   title: '序号',
-    //   align: 'center',
-    //   width: 60
-    // },
-    columns: [
-      {
-        title: 'UID',
-        align: 'center',
-        key: 'uid',
-        form: {
-          disabled: true
-        }
-      },
-      {
-        title: '关键词',
-        key: 'search',
-        show: false,
-        disabled: true,
-        search: {
-          disabled: false
+        options: {
+            height: '100%',
+            // tableType: 'vxe-table',
+            // rowKey: true,
+            rowId: 'id',
+            size: 'mini',
+            stripe: true,
+            fit: true,
         },
-        form: {
-          disabled: true,
-          component: {
-            placeholder: '请输入关键词'
-          }
+        selectionRow: {
+            align: 'center',
+            width: 46
         },
-        view: {
-          disabled: true
-        }
-      },
-      {
-        title: '头像',
-        key: 'avatar',
-        type: 'avatar-cropper',
-        width: 60,
-        align: 'center',
-        form: {
-          component: {
-            props: {
-              elProps: { // 与el-uploader 配置一致
-                multiple: false,
-                limit: 1 // 限制5个文件
-              },
-              sizeLimit: 500 * 1024 // 不能超过限制
-            },
-            span: 24
-          },
-          helper: '限制文件大小不能超过500k'
-        }
-      },
-      {
-        title: '账号',
-        key: 'username',
-        search: {
-          disabled: false
-        },
-        minWidth: 100,
-        type: 'input',
-        form: {
-          rules: [ // 表单校验规则
-            {
-              required: true,
-              message: '账号必填项'
-            }
-          ],
-          component: {
-            placeholder: '请输入账号'
-          },
-          itemProps: {
-            class: { yxtInput: true }
-          }
-        }
-      },
-      {
-        title: '密码',
-        key: 'password',
-        minWidth: 90,
-        type: 'input',
-        form: {
-          rules: [ // 表单校验规则
-            {
-              required: true,
-              message: '密码必填项'
-            }
-          ],
-          component: {
-            span: 12,
-            showPassword: true,
-            placeholder: '请输入密码'
-          },
-          value: vm.systemConfig('base.default_password'),
-          editDisabled: true,
-          itemProps: {
-            class: { yxtInput: true }
-          }
-        },
-        disabled: true,
-        valueResolve (row, key) {
-          if (row.password) {
-            row.password = vm.$md5(row.password)
-          }
-        }
-      },
-      {
-        title: '姓名',
-        key: 'name',
-        sortable: 'custom',
-        minWidth: 90,
-        search: {
-          disabled: false
-        },
-        type: 'input',
-        form: {
-          rules: [ // 表单校验规则
-            {
-              required: true,
-              message: '姓名必填项'
-            }
-          ],
-          component: {
-            span: 12,
-            placeholder: '请输入姓名'
-          },
-          itemProps: {
-            class: { yxtInput: true }
-          }
-        }
-      },
-      {
-        title: '用户组',
-        key: 'dept',
-        search: {
-          disabled: true
-        },
-        minWidth: 140,
-        type: 'tree-selector',
-        dict: {
-          cache: true,
-          isTree: true,
-          url: '/system/dept/all_dept/',
-          value: 'id', // 数据字典中value字段的属性名
-          label: 'name' // 数据字典中label字段的属性名
-        },
-        form: {
-          rules: [ // 表单校验规则
-            {
-              required: true,
-              message: '必填项'
-            }
-          ],
-          itemProps: {
-            class: { yxtInput: true }
-          },
-          component: {
-            span: 12,
-            pagination: true,
-            props: { multiple: false }
-          }
-        },
-        component: {
-          name: 'foreignKey',
-          valueBinding: 'dept_name'
-        }
-      },
-      {
-        title: '角色',
-        key: 'role',
-        search: {
-          disabled: true
-        },
-        minWidth: 130,
-        type: 'table-selector',
-        dict: {
-          cache: false,
-          url: '/system/role/',
-          value: 'id', // 数据字典中value字段的属性名
-          label: 'name', // 数据字典中label字段的属性名
-          getData: (url, dict, {
-            form,
-            component
-          }) => {
-            return request({
-              url: url,
-              params: {
-                page: 1,
-                limit: 10
-              }
-            }).then(ret => {
-              component._elProps.page = ret.data.page
-              component._elProps.limit = ret.data.limit
-              component._elProps.total = ret.data.total
-              return ret.data.data
-            })
-          }
-        },
-        form: {
-          rules: [ // 表单校验规则
-            {
-              required: true,
-              message: '必填项'
-            }
-          ],
-          itemProps: {
-            class: { yxtInput: true }
-          },
-          component: {
-            span: 12,
-            pagination: true,
-            props: { multiple: true },
-            elProps: {
-              columns: [
-                {
-                  field: 'name',
-                  title: '角色名称'
+        rowHandle: {
+            width: 240,
+            fixed: 'right',
+            view: {
+                thin: true,
+                text: '',
+                disabled() {
+                    return !vm.hasPermissions('Retrieve')
                 },
-                {
-                  field: 'key',
-                  title: '权限标识'
-                }
-              ]
-            }
-          }
-        },
-        component: {
-          name: 'manyToMany',
-          valueBinding: 'role_info',
-          children: 'name'
-        }
-      },
-      {
-        title: '手机号码',
-        key: 'mobile',
-        search: {
-          disabled: false
-        },
-        minWidth: 110,
-        type: 'input',
-        form: {
-          rules: [
-            {
-              max: 20,
-              message: '请输入正确的手机号码',
-              trigger: 'blur'
             },
-            {
-              pattern: /^1[3-9]\d{9}$/,
-              message: '请输入正确的手机号码'
+            edit: {
+                thin: true,
+                text: '',
+                disabled() {
+                    return !vm.hasPermissions('Update')
+                }
+            },
+            remove: {
+                thin: true,
+                text: '',
+                disabled() {
+                    return !vm.hasPermissions('Delete')
+                }
+            },
+            custom: [{
+                thin: true,
+                text: '密码重置',
+                size: 'small',
+                type: 'warning',
+                icon: 'el-icon-refresh-left',
+                show() {
+                    return vm.hasPermissions('ResetPassword')
+                },
+                emit: 'resetPassword'
+            }]
+        },
+        viewOptions: {
+            componentType: 'form'
+        },
+        formOptions: {
+            defaultSpan: 12 // 默认的表单 span
+        },
+        // indexRow: { // 或者直接传true,不显示title,不居中
+        //   title: '序号',
+        //   align: 'center',
+        //   width: 60
+        // },
+        columns: [{
+            title: 'UID',
+            align: 'center',
+            key: 'uid',
+            form: {
+                disabled: true
             }
-          ],
-          itemProps: {
-            class: { yxtInput: true }
-          },
-          component: {
-            placeholder: '请输入手机号码'
-          }
-        }
-      }, {
-        title: '邮箱',
-        key: 'email',
-        minWidth: 180,
-        form: {
-          rules: [
-            {
-              type: 'email',
-              message: '请输入正确的邮箱地址',
-              trigger: ['blur', 'change']
+        }, {
+            title: '关键词',
+            key: 'search',
+            show: false,
+            disabled: true,
+            search: {
+                disabled: false
+            },
+            form: {
+                disabled: true,
+                component: {
+                    placeholder: '请输入关键词'
+                }
+            },
+            view: {
+                disabled: true
             }
-          ],
-          component: {
-            placeholder: '请输入邮箱'
-          }
-        }
-      },
-      {
-        title: '性别',
-        key: 'gender',
-        type: 'radio',
-        width: 70,
-        dict: {
-          data: vm.dictionary('gender')
-        },
-        form: {
-          value: 1,
-          component: {
-            span: 12
-          }
-        },
-        component: { props: { color: 'auto' } } // 自动染色
-      }, {
-        title: '用户类型',
-        key: 'user_type',
-        search: {
-          disabled: false
-        },
-        width: 145,
-        type: 'select',
-        dict: {
-          data: vm.dictionary('user_type')
-        },
-        form: {
-          show: false,
-          value: 0,
-          component: {
-            span: 12
-          }
-        }
-      }, {
-        title: '状态',
-        key: 'is_active',
-        search: {
-          disabled: false
-        },
-        width: 70,
-        type: 'radio',
-        dict: {
-          data: vm.dictionary('button_status_bool')
-        },
-        form: {
-          value: true,
-          component: {
-            span: 12
-          }
-        }
-      },
-    ].concat(vm.commonEndColumns({
-      create_datetime: { showTable: false },
-      update_datetime: { showTable: false }
-    }))
-  }
-}
+        }, {
+            title: '头像',
+            key: 'avatar',
+            type: 'avatar-cropper',
+            width: 60,
+            align: 'center',
+            form: {
+                component: {
+                    props: {
+                        elProps: { // 与el-uploader 配置一致
+                            multiple: false,
+                            limit: 1 // 限制5个文件
+                        },
+                        sizeLimit: 500 * 1024 // 不能超过限制
+                    },
+                    span: 24
+                },
+                helper: '限制文件大小不能超过500k'
+            }
+        }, {
+            title: '账号',
+            key: 'nickname',
+            search: {
+                disabled: false
+            },
+            minWidth: 100,
+            type: 'input',
+            form: {
+                rules: [ // 表单校验规则
+                    {
+                        required: true,
+                        message: '账号必填项'
+                    }
+                ],
+                component: {
+                    placeholder: '请输入账号'
+                },
+                itemProps: {
+                    class: {
+                        yxtInput: true
+                    }
+                }
+            }
+        }, {
+            title: '密码',
+            key: 'password',
+            minWidth: 90,
+            type: 'input',
+            form: {
+                rules: [ // 表单校验规则
+                    {
+                        required: true,
+                        message: '密码必填项'
+                    }
+                ],
+                component: {
+                    span: 12,
+                    showPassword: true,
+                    placeholder: '请输入密码'
+                },
+                value: vm.systemConfig('base.default_password'),
+                editDisabled: true,
+                itemProps: {
+                    class: {
+                        yxtInput: true
+                    }
+                }
+            },
+            disabled: true,
+            valueResolve(row, key) {
+                if (row.password) {
+                    row.password = vm.$md5(row.password)
+                }
+            }
+        }, {
+            title: '姓名',
+            key: 'name',
+            sortable: 'custom',
+            minWidth: 90,
+            search: {
+                disabled: false
+            },
+            type: 'input',
+            form: {
+                rules: [ // 表单校验规则
+                    {
+                        required: true,
+                        message: '姓名必填项'
+                    }
+                ],
+                component: {
+                    span: 12,
+                    placeholder: '请输入姓名'
+                },
+                itemProps: {
+                    class: {
+                        yxtInput: true
+                    }
+                }
+            }
+        }, {
+            title: '用户组',
+            key: 'dept',
+            search: {
+                disabled: true
+            },
+            minWidth: 140,
+            type: 'tree-selector',
+            dict: {
+                cache: true,
+                isTree: true,
+                url: '/system/dept/all_dept/',
+                value: 'id', // 数据字典中value字段的属性名
+                label: 'name' // 数据字典中label字段的属性名
+            },
+            form: {
+                rules: [ // 表单校验规则
+                    {
+                        required: true,
+                        message: '必填项'
+                    }
+                ],
+                itemProps: {
+                    class: {
+                        yxtInput: true
+                    }
+                },
+                component: {
+                    span: 12,
+                    pagination: true,
+                    props: {
+                        multiple: false
+                    }
+                }
+            },
+            component: {
+                name: 'foreignKey',
+                valueBinding: 'dept_name'
+            }
+        }, {
+            title: '角色',
+            key: 'role',
+            search: {
+                disabled: true
+            },
+            minWidth: 130,
+            type: 'table-selector',
+            dict: {
+                cache: false,
+                url: '/system/role/',
+                value: 'id', // 数据字典中value字段的属性名
+                label: 'name', // 数据字典中label字段的属性名
+                getData: (url, dict, {
+                    form,
+                    component
+                }) => {
+                    return request({
+                        url: url,
+                        params: {
+                            page: 1,
+                            limit: 10
+                        }
+                    }).then(ret => {
+                        component._elProps.page = ret.data.page
+                        component._elProps.limit = ret.data.limit
+                        component._elProps.total = ret.data.total
+                        return ret.data.data
+                    })
+                }
+            },
+            form: {
+                rules: [ // 表单校验规则
+                    {
+                        required: true,
+                        message: '必填项'
+                    }
+                ],
+                itemProps: {
+                    class: {
+                        yxtInput: true
+                    }
+                },
+                component: {
+                    span: 12,
+                    pagination: true,
+                    props: {
+                        multiple: true
+                    },
+                    elProps: {
+                        columns: [{
+                            field: 'name',
+                            title: '角色名称'
+                        }, {
+                            field: 'key',
+                            title: '权限标识'
+                        }]
+                    }
+                }
+            },
+            component: {
+                name: 'manyToMany',
+                valueBinding: 'role_info',
+                children: 'name'
+            }
+        }, {
+            title: '手机号码',
+            key: 'mobile',
+            search: {
+                disabled: false
+            },
+            minWidth: 110,
+            type: 'input',
+            form: {
+                rules: [{
+                    max: 20,
+                    message: '请输入正确的手机号码',
+                    trigger: 'blur'
+                }, {
+                    pattern: /^1[3-9]\d{9}$/,
+                    message: '请输入正确的手机号码'
+                }],
+                itemProps: {
+                    class: {
+                        yxtInput: true
+                    }
+                },
+                component: {
+                    placeholder: '请输入手机号码'
+                }
+            }
+        }, {
+            title: '邮箱',
+            key: 'email',
+            minWidth: 180,
+            form: {
+                rules: [{
+                    type: 'email',
+                    message: '请输入正确的邮箱地址',
+                    trigger: ['blur', 'change']
+                }],
+                component: {
+                    placeholder: '请输入邮箱'
+                }
+            }
+        }, {
+            title: '性别',
+            key: 'gender',
+            type: 'radio',
+            width: 70,
+            dict: {
+                data: vm.dictionary('gender')
+            },
+            form: {
+                value: 1,
+                component: {
+                    span: 12
+                }
+            },
+            component: {
+                props: {
+                    color: 'auto'
+                }
+            } // 自动染色
+        }, {
+            title: '用户类型',
+            key: 'user_type',
+            search: {
+                disabled: false
+            },
+            width: 145,
+            type: 'select',
+            dict: {
+                data: vm.dictionary('user_type')
+            },
+            form: {
+                show: false,
+                value: 0,
+                component: {
+                    span: 12
+                }
+            }
+        }, {
+            title: '状态',
+            key: 'is_active',
+            search: {
+                disabled: false
+            },
+            width: 70,
+            type: 'radio',
+            dict: {
+                data: vm.dictionary('button_status_bool')
+            },
+            form: {
+                value: true,
+                component: {
+                    span: 12
+                }
+            }
+        }, ].concat(vm.commonEndColumns({
+            create_datetime: {
+                showTable: false
+            },
+            update_datetime: {
+                showTable: false
+            }
+        }))
+    }
+}
\ No newline at end of file