瀏覽代碼

feat: 用户管理重写-部门树,表格渲染

fengjingtao 2 年之前
父節點
當前提交
80d540790e
共有 1 個文件被更改,包括 182 次插入629 次删除
  1. 182 629
      src/views/system/user/index.vue

+ 182 - 629
src/views/system/user/index.vue

@@ -10,9 +10,12 @@
             placeholder="请输入部门名称"
             clearable
             size="small"
-            prefix-icon="el-icon-search"
             style="margin-bottom: 20px"
-          />
+          >
+            <template #prefix>
+              <Icon icon="ep:search" />
+            </template>
+          </el-input>
         </div>
         <div class="head-container">
           <el-tree
@@ -20,10 +23,11 @@
             :props="defaultProps"
             :expand-on-click-node="false"
             :filter-node-method="filterNode"
-            ref="tree"
+            ref="treeRef"
+            node-key="id"
             default-expand-all
             highlight-current
-            @node-click="handleNodeClick"
+            @node-click="handleDeptNodeClick"
           />
         </div>
       </el-col>
@@ -43,7 +47,7 @@
               placeholder="请输入用户名称"
               clearable
               style="width: 240px"
-              @keyup.enter.native="handleQuery"
+              @keyup.enter="handleQuery"
             />
           </el-form-item>
           <el-form-item label="手机号码" prop="mobile">
@@ -52,7 +56,7 @@
               placeholder="请输入手机号码"
               clearable
               style="width: 240px"
-              @keyup.enter.native="handleQuery"
+              @keyup.enter="handleQuery"
             />
           </el-form-item>
           <el-form-item label="状态" prop="status">
@@ -83,8 +87,8 @@
             />
           </el-form-item>
           <el-form-item>
-            <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
-            <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+            <el-button type="primary" @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
+            <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
           </el-form-item>
         </el-form>
 
@@ -93,41 +97,37 @@
             <el-button
               type="primary"
               plain
-              icon="el-icon-plus"
-              size="mini"
+              size="small"
               @click="handleAdd"
               v-hasPermi="['system:user:create']"
-              >新增</el-button
+              ><Icon icon="ep:plus" />新增</el-button
             >
           </el-col>
           <el-col :span="1.5">
             <el-button
               type="info"
-              icon="el-icon-upload2"
-              size="mini"
+              size="small"
               @click="handleImport"
               v-hasPermi="['system:user:import']"
-              >导入</el-button
+              ><Icon icon="ep:upload" />导入</el-button
             >
           </el-col>
           <el-col :span="1.5">
             <el-button
               type="warning"
-              icon="el-icon-download"
-              size="mini"
+              size="small"
               @click="handleExport"
               :loading="exportLoading"
               v-hasPermi="['system:user:export']"
-              >导出</el-button
+              ><Icon icon="ep:download" />导出</el-button
             >
           </el-col>
-          <right-toolbar
+          <!-- <right-toolbar
             :showSearch.sync="showSearch"
             @queryTable="getList"
             :columns="columns"
-          ></right-toolbar>
+          ></right-toolbar> -->
         </el-row>
-
         <el-table v-loading="loading" :data="userList">
           <el-table-column
             label="用户编号"
@@ -169,7 +169,7 @@
             width="120"
           />
           <el-table-column label="状态" key="status" v-if="columns[5].visible" align="center">
-            <template v-slot="scope">
+            <template #default="scope">
               <el-switch
                 v-model="scope.row.status"
                 :active-value="0"
@@ -185,7 +185,7 @@
             v-if="columns[6].visible"
             width="160"
           >
-            <template v-slot="scope">
+            <template #default="scope">
               <span>{{ parseTime(scope.row.createTime) }}</span>
             </template>
           </el-table-column>
@@ -195,14 +195,13 @@
             width="160"
             class-name="small-padding fixed-width"
           >
-            <template v-slot="scope">
+            <template #default="scope">
               <el-button
-                size="mini"
+                size="small"
                 type="text"
-                icon="el-icon-edit"
                 @click="handleUpdate(scope.row)"
                 v-hasPermi="['system:user:update']"
-                >修改</el-button
+                ><Icon icon="ep:edit" />修改</el-button
               >
               <el-dropdown
                 @command="(command) => handleCommand(command, scope.$index, scope.row)"
@@ -212,630 +211,184 @@
                   'system:permission:assign-user-role'
                 ]"
               >
-                <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
-                <el-dropdown-menu slot="dropdown">
-                  <el-dropdown-item
-                    command="handleDelete"
-                    v-if="scope.row.id !== 1"
-                    size="mini"
-                    type="text"
-                    icon="el-icon-delete"
-                    v-hasPermi="['system:user:delete']"
-                    >删除</el-dropdown-item
-                  >
-                  <el-dropdown-item
-                    command="handleResetPwd"
-                    size="mini"
-                    type="text"
-                    icon="el-icon-key"
-                    v-hasPermi="['system:user:update-password']"
-                    >重置密码</el-dropdown-item
-                  >
-                  <el-dropdown-item
-                    command="handleRole"
-                    size="mini"
-                    type="text"
-                    icon="el-icon-circle-check"
-                    v-hasPermi="['system:permission:assign-user-role']"
-                    >分配角色</el-dropdown-item
-                  >
-                </el-dropdown-menu>
+                <el-button size="small" type="text"><Icon icon="ep:d-arrow-right" />更多</el-button>
+                <template #dropdown>
+                  <el-dropdown-menu>
+                    <el-dropdown-item
+                      command="handleDelete"
+                      v-if="scope.row.id !== 1"
+                      size="small"
+                      type="text"
+                      v-hasPermi="['system:user:delete']"
+                      ><Icon icon="ep:delete" />删除</el-dropdown-item
+                    >
+                    <el-dropdown-item
+                      command="handleResetPwd"
+                      size="small"
+                      type="text"
+                      v-hasPermi="['system:user:update-password']"
+                      ><Icon icon="ep:key" />重置密码</el-dropdown-item
+                    >
+                    <el-dropdown-item
+                      command="handleRole"
+                      size="small"
+                      type="text"
+                      v-hasPermi="['system:permission:assign-user-role']"
+                      ><Icon icon="ep:circle-check" />分配角色</el-dropdown-item
+                    >
+                  </el-dropdown-menu>
+                </template>
               </el-dropdown>
             </template>
           </el-table-column>
         </el-table>
-
         <pagination
           v-show="total > 0"
           :total="total"
-          :page.sync="queryParams.pageNo"
-          :limit.sync="queryParams.pageSize"
+          v-model:page="queryParams.pageNo"
+          v-model:limit="queryParams.pageSize"
           @pagination="getList"
         />
       </el-col>
     </el-row>
-
-    <!-- 添加或修改参数配置对话框 -->
-    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="用户昵称" prop="nickname">
-              <el-input v-model="form.nickname" placeholder="请输入用户昵称" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="归属部门" prop="deptId">
-              <treeselect
-                v-model="form.deptId"
-                :options="deptOptions"
-                :show-count="true"
-                :clearable="false"
-                placeholder="请选择归属部门"
-                :normalizer="normalizer"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="手机号码" prop="mobile">
-              <el-input v-model="form.mobile" placeholder="请输入手机号码" maxlength="11" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="邮箱" prop="email">
-              <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item v-if="form.id === undefined" label="用户名称" prop="username">
-              <el-input v-model="form.username" placeholder="请输入用户名称" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.id === undefined" label="用户密码" prop="password">
-              <el-input
-                v-model="form.password"
-                placeholder="请输入用户密码"
-                type="password"
-                show-password
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="用户性别">
-              <el-select v-model="form.sex" placeholder="请选择">
-                <el-option
-                  v-for="dict in sexDictDatas"
-                  :key="parseInt(dict.value)"
-                  :label="dict.label"
-                  :value="parseInt(dict.value)"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="岗位">
-              <el-select v-model="form.postIds" multiple placeholder="请选择">
-                <el-option
-                  v-for="item in postOptions"
-                  :key="item.id"
-                  :label="item.name"
-                  :value="item.id"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="备注">
-              <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">确 定</el-button>
-        <el-button @click="cancel">取 消</el-button>
-      </div>
-    </el-dialog>
-
-    <!-- 用户导入对话框 -->
-    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
-      <el-upload
-        ref="upload"
-        :limit="1"
-        accept=".xlsx, .xls"
-        :headers="upload.headers"
-        :action="upload.url + '?updateSupport=' + upload.updateSupport"
-        :disabled="upload.isUploading"
-        :on-progress="handleFileUploadProgress"
-        :on-success="handleFileSuccess"
-        :auto-upload="false"
-        drag
-      >
-        <i class="el-icon-upload"></i>
-        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
-        <div class="el-upload__tip text-center" slot="tip">
-          <div class="el-upload__tip" slot="tip">
-            <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
-          </div>
-          <span>仅允许导入xls、xlsx格式文件。</span>
-          <el-link
-            type="primary"
-            :underline="false"
-            style="font-size: 12px; vertical-align: baseline"
-            @click="importTemplate"
-            >下载模板</el-link
-          >
-        </div>
-      </el-upload>
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitFileForm">确 定</el-button>
-        <el-button @click="upload.open = false">取 消</el-button>
-      </div>
-    </el-dialog>
-
-    <!-- 分配角色 -->
-    <el-dialog title="分配角色" :visible.sync="openRole" width="500px" append-to-body>
-      <el-form :model="form" label-width="80px">
-        <el-form-item label="用户名称">
-          <el-input v-model="form.username" :disabled="true" />
-        </el-form-item>
-        <el-form-item label="用户昵称">
-          <el-input v-model="form.nickname" :disabled="true" />
-        </el-form-item>
-        <el-form-item label="角色">
-          <el-select v-model="form.roleIds" multiple placeholder="请选择">
-            <el-option
-              v-for="item in roleOptions"
-              :key="parseInt(item.id)"
-              :label="item.name"
-              :value="parseInt(item.id)"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitRole">确 定</el-button>
-        <el-button @click="cancelRole">取 消</el-button>
-      </div>
-    </el-dialog>
   </div>
 </template>
 
-<script>
+<script setup lang="ts" name="User">
+import type { ElTree } from 'element-plus'
+import { handleTree, defaultProps } from '@/utils/tree'
+import { listSimpleDeptApi } from '@/api/system/dept'
+import { listSimplePostsApi, PostVO } from '@/api/system/post'
+import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import { UserVO } from '@/api/system/user'
 import {
-  createUserApi as addUser,
-  updateUserStatusApi as changeUserStatus,
-  deleteUserApi as delUser,
-  exportUserApi as exportUser,
-  // TODO: praseStrEmpty(id)
-  getUserApi as getUser,
-  importUserTemplateApi as importTemplate,
-  getUserPageApi as listUser,
-  resetUserPwdApi as resetUserPwd,
-  updateUserApi as updateUser
+  // createUserApi,
+  // updateUserStatusApi,
+  // deleteUserApi,
+  // exportUserApi,
+  // getUserApi,
+  // importUserTemplateApi,
+  getUserPageApi
+  // resetUserPwdApid,
+  // updateUserApi
 } from '@/api/system/user'
-// TODO: change
-import Treeselect from '@riophae/vue-treeselect'
-// TODO: change???
-import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 
-import { listSimpleDeptApi } from '@/api/system/dept'
-import { listSimplePostsApi } from '@/api/system/post'
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  username: undefined,
+  mobile: undefined,
+  status: undefined,
+  deptId: undefined,
+  createTime: []
+})
+const showSearch = ref(true)
+// 数据字典
+const statusDictDatas = getDictOptions(DICT_TYPE.COMMON_STATUS)
+// const sexDictDatas = getDictOptions(DICT_TYPE.SYSTEM_USER_SEX)
 
-import { CommonStatusEnum } from '@/utils/constants'
-import { DICT_TYPE, getDictDatas } from '@/utils/dict'
-import { assignUserRole, listUserRoles } from '@/api/system/permission'
-import { listSimpleRoles } from '@/api/system/role'
-import { getBaseHeader } from '@/utils/request'
-
-export default {
-  name: 'User',
-  components: { Treeselect },
-  data() {
-    return {
-      // 遮罩层
-      loading: true,
-      // 导出遮罩层
-      exportLoading: false,
-      // 显示搜索条件
-      showSearch: true,
-      // 总条数
-      total: 0,
-      // 用户表格数据
-      userList: null,
-      // 弹出层标题
-      title: '',
-      // 部门树选项
-      deptOptions: undefined,
-      // 是否显示弹出层
-      open: false,
-      // 部门名称
-      deptName: undefined,
-      // 默认密码
-      initPassword: undefined,
-      // 性别状态字典
-      sexOptions: [],
-      // 岗位选项
-      postOptions: [],
-      // 角色选项
-      roleOptions: [],
-      // 表单参数
-      form: {},
-      defaultProps: {
-        children: 'children',
-        label: 'name'
-      },
-      // 用户导入参数
-      upload: {
-        // 是否显示弹出层(用户导入)
-        open: false,
-        // 弹出层标题(用户导入)
-        title: '',
-        // 是否禁用上传
-        isUploading: false,
-        // 是否更新已经存在的用户数据
-        updateSupport: 0,
-        // 设置上传的请求头部
-        headers: getBaseHeader(),
-        // 上传的地址
-        url: process.env.VUE_APP_BASE_API + '/admin-api/system/user/import'
-      },
-      // 查询参数
-      queryParams: {
-        pageNo: 1,
-        pageSize: 10,
-        username: undefined,
-        mobile: undefined,
-        status: undefined,
-        deptId: undefined,
-        createTime: []
-      },
-      // 列信息
-      columns: [
-        { key: 0, label: `用户编号`, visible: true },
-        { key: 1, label: `用户名称`, visible: true },
-        { key: 2, label: `用户昵称`, visible: true },
-        { key: 3, label: `部门`, visible: true },
-        { key: 4, label: `手机号码`, visible: true },
-        { key: 5, label: `状态`, visible: true },
-        { key: 6, label: `创建时间`, visible: true }
-      ],
-      // 表单校验
-      rules: {
-        username: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }],
-        nickname: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }],
-        password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
-        email: [
-          {
-            type: 'email',
-            message: "'请输入正确的邮箱地址",
-            trigger: ['blur', 'change']
-          }
-        ],
-        mobile: [
-          {
-            pattern:
-              /^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/,
-            message: '请输入正确的手机号码',
-            trigger: 'blur'
-          }
-        ]
-      },
-      // 是否显示弹出层(角色权限)
-      openRole: false,
+// ========== 创建部门树结构 ==========
+const deptName = ref('')
+const deptOptions = ref<Tree[]>([]) // 树形结构
+const treeRef = ref<InstanceType<typeof ElTree>>()
+const getTree = async () => {
+  const res = await listSimpleDeptApi()
+  deptOptions.value.push(...handleTree(res))
+}
+const filterNode = (value: string, data: Tree) => {
+  if (!value) return true
+  return data.name.includes(value)
+}
+const handleDeptNodeClick = async (row: { [key: string]: any }) => {
+  queryParams.deptId = row.id
+  // await reload()
+  getList()
+}
+// 获取岗位列表
+const postOptions = ref<PostVO[]>([]) //岗位列表
+const getPostOptions = async () => {
+  const res = await listSimplePostsApi()
+  postOptions.value.push(...res)
+}
+// 用户列表
+const userList = ref<UserVO[]>([])
+const loading = ref(false)
+const total = ref(0)
+const columns = ref([
+  { key: 0, label: `用户编号`, visible: true },
+  { key: 1, label: `用户名称`, visible: true },
+  { key: 2, label: `用户昵称`, visible: true },
+  { key: 3, label: `部门`, visible: true },
+  { key: 4, label: `手机号码`, visible: true },
+  { key: 5, label: `状态`, visible: true },
+  { key: 6, label: `创建时间`, visible: true }
+])
+const getList = () => {
+  loading.value = true
+  getUserPageApi(queryParams).then((response) => {
+    userList.value = response.list
+    total.value = response.total
+    loading.value = false
+  })
+}
+const handleQuery = () => {}
+const resetQuery = () => {}
+const handleAdd = () => {}
+const handleImport = () => {}
+const exportLoading = ref(false)
+const handleExport = () => {}
+const handleStatusChange = () => {}
+const handleUpdate = () => {}
+const handleCommand = () => {}
+// ========== 初始化 ==========
+onMounted(async () => {
+  getList()
+  await getPostOptions()
+  await getTree()
+})
 
-      // 枚举
-      SysCommonStatusEnum: CommonStatusEnum,
-      // 数据字典
-      statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS),
-      sexDictDatas: getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)
-    }
-  },
-  watch: {
-    // 根据名称筛选部门树
-    deptName(val) {
-      this.$refs.tree.filter(val)
+const parseTime = (time) => {
+  if (!time) {
+    return null
+  }
+  const format = '{y}-{m}-{d} {h}:{i}:{s}'
+  let date
+  if (typeof time === 'object') {
+    date = time
+  } else {
+    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
+      time = parseInt(time)
+    } else if (typeof time === 'string') {
+      time = time
+        .replace(new RegExp(/-/gm), '/')
+        .replace('T', ' ')
+        .replace(new RegExp(/\.[\d]{3}/gm), '')
     }
-  },
-  created() {
-    this.getList()
-    this.getTreeselect()
-    // this.getConfigKey("sys.user.init-password").then(response => {
-    //   this.initPassword = response.msg;
-    // });
-  },
-  methods: {
-    // 更多操作
-    handleCommand(command, index, row) {
-      switch (command) {
-        case 'handleUpdate':
-          this.handleUpdate(row) //修改客户信息
-          break
-        case 'handleDelete':
-          this.handleDelete(row) //红号变更
-          break
-        case 'handleResetPwd':
-          this.handleResetPwd(row)
-          break
-        case 'handleRole':
-          this.handleRole(row)
-          break
-        default:
-          break
-      }
-    },
-    /** 查询用户列表 */
-    getList() {
-      this.loading = true
-      listUser(this.queryParams).then((response) => {
-        this.userList = response.data.list
-        this.total = response.data.total
-        this.loading = false
-      })
-    },
-    /** 查询部门下拉树结构 + 岗位下拉 */
-    getTreeselect() {
-      listSimpleDeptApi().then((response) => {
-        // 处理 deptOptions 参数
-        this.deptOptions = []
-        this.deptOptions.push(...this.handleTree(response.data, 'id'))
-      })
-      listSimplePostsApi().then((response) => {
-        // 处理 postOptions 参数
-        this.postOptions = []
-        this.postOptions.push(...response.data)
-      })
-    },
-    // 筛选节点
-    filterNode(value, data) {
-      if (!value) return true
-      return data.name.indexOf(value) !== -1
-    },
-    // 节点单击事件
-    handleNodeClick(data) {
-      this.queryParams.deptId = data.id
-      this.getList()
-    },
-    // 用户状态修改
-    handleStatusChange(row) {
-      let text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用'
-      this.$modal
-        .confirm('确认要"' + text + '""' + row.username + '"用户吗?')
-        .then(function () {
-          return changeUserStatus(row.id, row.status)
-        })
-        .then(() => {
-          this.$modal.msgSuccess(text + '成功')
-        })
-        .catch(function () {
-          row.status =
-            row.status === CommonStatusEnum.ENABLE
-              ? CommonStatusEnum.DISABLE
-              : CommonStatusEnum.ENABLE
-        })
-    },
-    // 取消按钮
-    cancel() {
-      this.open = false
-      this.reset()
-    },
-    // 取消按钮(角色权限)
-    cancelRole() {
-      this.openRole = false
-      this.reset()
-    },
-    // 表单重置
-    reset() {
-      this.form = {
-        id: undefined,
-        deptId: undefined,
-        username: undefined,
-        nickname: undefined,
-        password: undefined,
-        mobile: undefined,
-        email: undefined,
-        sex: undefined,
-        status: '0',
-        remark: undefined,
-        postIds: [],
-        roleIds: []
-      }
-      this.resetForm('form')
-    },
-    /** 搜索按钮操作 */
-    handleQuery() {
-      this.queryParams.pageNo = 1
-      this.getList()
-    },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.resetForm('queryForm')
-      this.handleQuery()
-    },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset()
-      // 获得下拉数据
-      this.getTreeselect()
-      // 打开表单,并设置初始化
-      this.open = true
-      this.title = '添加用户'
-      this.form.password = this.initPassword
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset()
-      this.getTreeselect()
-      const id = row.id
-      getUser(id).then((response) => {
-        this.form = response.data
-        this.open = true
-        this.title = '修改用户'
-        this.form.password = ''
-      })
-    },
-    /** 重置密码按钮操作 */
-    handleResetPwd(row) {
-      this.$prompt('请输入"' + row.username + '"的新密码', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消'
-      })
-        .then(({ value }) => {
-          resetUserPwd(row.id, value).then((response) => {
-            this.$modal.msgSuccess('修改成功,新密码是:' + value)
-          })
-        })
-        .catch(() => {})
-    },
-    /** 分配用户角色操作 */
-    handleRole(row) {
-      this.reset()
-      const id = row.id
-      // 处理了 form 的用户 username 和 nickname 的展示
-      this.form.id = id
-      this.form.username = row.username
-      this.form.nickname = row.nickname
-      // 打开弹窗
-      this.openRole = true
-      // 获得角色列表
-      listSimpleRoles().then((response) => {
-        // 处理 roleOptions 参数
-        this.roleOptions = []
-        this.roleOptions.push(...response.data)
-      })
-      // 获得角色拥有的菜单集合
-      listUserRoles(id).then((response) => {
-        // 设置选中
-        this.form.roleIds = response.data
-      })
-    },
-    /** 提交按钮 */
-    submitForm: function () {
-      this.$refs['form'].validate((valid) => {
-        if (valid) {
-          if (this.form.id !== undefined) {
-            updateUser(this.form).then((response) => {
-              this.$modal.msgSuccess('修改成功')
-              this.open = false
-              this.getList()
-            })
-          } else {
-            addUser(this.form).then((response) => {
-              this.$modal.msgSuccess('新增成功')
-              this.open = false
-              this.getList()
-            })
-          }
-        }
-      })
-    },
-    /** 提交按钮(角色权限) */
-    submitRole: function () {
-      if (this.form.id !== undefined) {
-        assignUserRole({
-          userId: this.form.id,
-          roleIds: this.form.roleIds
-        }).then((response) => {
-          this.$modal.msgSuccess('分配角色成功')
-          this.openRole = false
-          this.getList()
-        })
-      }
-    },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const ids = row.id || this.ids
-      this.$modal
-        .confirm('是否确认删除用户编号为"' + ids + '"的数据项?')
-        .then(function () {
-          return delUser(ids)
-        })
-        .then(() => {
-          this.getList()
-          this.$modal.msgSuccess('删除成功')
-        })
-        .catch(() => {})
-    },
-    /** 导出按钮操作 */
-    handleExport() {
-      this.$modal
-        .confirm('是否确认导出所有用户数据项?')
-        .then(() => {
-          // 处理查询参数
-          let params = { ...this.queryParams }
-          params.pageNo = undefined
-          params.pageSize = undefined
-          this.exportLoading = true
-          return exportUser(params)
-        })
-        .then((response) => {
-          this.$download.excel(response, '用户数据.xls')
-          this.exportLoading = false
-        })
-        .catch(() => {})
-    },
-    /** 导入按钮操作 */
-    handleImport() {
-      this.upload.title = '用户导入'
-      this.upload.open = true
-    },
-    /** 下载模板操作 */
-    importTemplate() {
-      importTemplate().then((response) => {
-        this.$download.excel(response, '用户导入模板.xls')
-      })
-    },
-    // 文件上传中处理
-    handleFileUploadProgress(event, file, fileList) {
-      this.upload.isUploading = true
-    },
-    // 文件上传成功处理
-    handleFileSuccess(response, file, fileList) {
-      if (response.code !== 0) {
-        this.$modal.msgError(response.msg)
-        return
-      }
-      this.upload.open = false
-      this.upload.isUploading = false
-      this.$refs.upload.clearFiles()
-      // 拼接提示语
-      let data = response.data
-      let text = '创建成功数量:' + data.createUsernames.length
-      for (const username of data.createUsernames) {
-        text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username
-      }
-      text += '<br />更新成功数量:' + data.updateUsernames.length
-      for (const username of data.updateUsernames) {
-        text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username
-      }
-      text += '<br />更新失败数量:' + Object.keys(data.failureUsernames).length
-      for (const username in data.failureUsernames) {
-        text += '<br />&nbsp;&nbsp;&nbsp;&nbsp;' + username + ':' + data.failureUsernames[username]
-      }
-      this.$alert(text, '导入结果', { dangerouslyUseHTMLString: true })
-      this.getList()
-    },
-    // 提交上传文件
-    submitFileForm() {
-      this.$refs.upload.submit()
-    },
-    // 格式化部门的下拉框
-    normalizer(node) {
-      return {
-        id: node.id,
-        label: node.name,
-        children: node.children
-      }
+    if (typeof time === 'number' && time.toString().length === 10) {
+      time = time * 1000
     }
+    date = new Date(time)
+  }
+  const formatObj = {
+    y: date.getFullYear(),
+    m: date.getMonth() + 1,
+    d: date.getDate(),
+    h: date.getHours(),
+    i: date.getMinutes(),
+    s: date.getSeconds(),
+    a: date.getDay()
   }
+  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+    let value = formatObj[key]
+    // Note: getDay() returns 0 on Sunday
+    if (key === 'a') {
+      return ['日', '一', '二', '三', '四', '五', '六'][value]
+    }
+    if (result.length > 0 && value < 10) {
+      value = '0' + value
+    }
+    return value || 0
+  })
+  return time_str
 }
 </script>