在前面随笔介绍了ABP+Vue前后端的整合处理,包括介绍了ABP的后端设计,以及前端对ABP接口API的ES6的封装,通过JS的继承类处理,极大减少了重复臃肿的代码,可以简化对后端API接口的封装,而且前端使用Element组件,很好展示API获得的数据,通过在界面中展示树状列表,以及表格列表数据,可以构建一个很好的列表展示界面,而常规的界面,通过也包括了新增、编辑、查看等展示场景,一般我们通过对话框的方式进行展示处理。本篇随笔以权限管理模块中的用户管理为媒介,进行相关功能的介绍和界面设计的处理。

1、权限管理模块的设计

我们知道,权限管理一般都会涉及到用户、组织机构、角色,以及权限功能等方面的内容,ABP框架的基础内容也是涉及到这几方面的内容,其中它们之间的关系基本上是多对多的关系,它们的关系如下所示。

权限模块里面包含的一些主对象表和中间表,中间表主要用来存储两个对象之间的多对多关系,如角色包含多个用户,用户属于多个机构,机构包含多个角色等等。

结合ABP后端提供的接口,Vue前端我们要实现基础的用户、组织机构、角色、功能权限等内容的管理,以及维护它们之间的关系。Vue前端对于权限管理模块的菜单列表如下所示。

上图权限管理模块中,包括用户管理、机构管理、角色管理、菜单管理、功能管理、审计日志、登录日志等内容模块的管理。

其中用户管理模块,主要用来展示用户信息列表,以及查看对应用户权限、维护密码等处理。

用户列表界面如下所示,包括对应条件的查询和列表展示、以及查看、添加、编辑、删除、重置密码等功能入口。

用户信息查看界面如下所示

主要展示用户基础信息,和所属的关系信息,其中权限部分列出对应用户包含的功能点,用于界面按钮等方面的控制处理。

用户添加界面,则主要用来处理录入用户基础信息部分即可,如下界面所示。

用户信息录入,对用户基础表单数据进行校验,符合格式要求才能录入。

用户编辑界面,基本上和上面的类似了,不在赘述。

另外,删除用户或者重置密码,一般需对确认后再行操作,弹出一个对话框用户确认再继续。

ABP+Vue的框架参考的是已完成的ABP+Winform的功能界面进行开发,具体也可以了解下Winform版本框架《
ABP开发框架前后端开发系列---(14)基于Winform的ABP快速开发框架

2、用户管理界面功能

以上我们介绍了权限管理模块涉及的内容和关系,并着重介绍了用户管理界面中的内容展示,下面介绍在Element中如何实现对上面界面的处理的。

首先我们需要根据ABP后端的接口进行前端JS端的类的封装处理,其中前面说过,常规的Get/GetAll/Create/Update/Delete/Count等接口,我们放在BaseApi基类里面定义,其他子类继承它即可。

权限模块我们涉及到的用户管理、机构管理、角色管理、菜单管理、功能管理、审计日志、登录日志等业务类,那么这些类继承BaseApi,就会具有相关的接口了,如下所示继承关系。

我们这里以UserAPI的JS类定义介绍,如下所示。

我们以其中一个接口为例进行介绍实现代码,可以看到主要就是简单封装的调用即可。

  GetGrantedFunctionsByUser(id) { //获取用户权限列表
    returnrequest({
url:
this.baseurl + 'GetGrantedFunctionsByUser',
method:
'get',
params: { id }
})
}

有了这些业务类的准备,那么我们和后端ABP的API接口对接,就很容易了,如下图所示。

剩下的就是对Vue + Element前端的界面处理事情了。

我们先来看看查询的处理,常规的查询涉及日期区间的查询处理,这里我们用一个一个查询日期的处理操作,如下图所示。

表单的界面代码如下所示

    <el-formref="searchForm":model="searchForm"label-width="80":inline="true">
      <el-form-itemlabel="创建时间">
        <el-date-pickerv-model="searchForm.creationTime"type="daterange"align="right"unlink-panels
range-separator
="至"start-placeholder="开始日期"end-placeholder="结束日期":picker-options="pickerOptions" /> </el-form-item> <el-form-itemlabel="用户名"prop="UserName"> <el-inputv-model="searchForm.UserName" /> </el-form-item> <el-form-itemlabel="手机"prop="PhoneNumber"> <el-inputv-model="searchForm.PhoneNumber" /> </el-form-item> </el-form>

其中定义了一个pickerOptions 属性,用于快速选择日期的,在data里面增加一个这样的属性即可。

pickerOptions: {
shortcuts: [{
text:
'最近一周',
onClick(picker) {
const end
= newDate();
const start
= newDate();
start.setTime(start.getTime()
- 3600 * 1000 * 24 * 7);
picker.$emit(
'pick', [start, end]);
}
}, {
text:
'最近一个月',
onClick(picker) {
const end
= newDate();
const start
= newDate();
start.setTime(start.getTime()
- 3600 * 1000 * 24 * 30);
picker.$emit(
'pick', [start, end]);
}
}, {
text:
'最近三个月',
onClick(picker) {
const end
= newDate();
const start
= newDate();
start.setTime(start.getTime()
- 3600 * 1000 * 24 * 90);
picker.$emit(
'pick', [start, end]);
}
}]
},

在页面里面,我们定义了一些分页查询的处理条件和对象,如下所示。

查询表单则定义一个单独的表单对象,如下代码所示

      searchForm: { //查询表单
        UserName: '',
PhoneNumber:
'',
creationTime:
''},

页面加载准备好,我们就调用获取列表的数据即可。

  created() { //页面加载后,加载列表数据
    this.getlist()
},

获取列表的处理操作如下代码所示,主要就是准备构建好对应的查询参数,然后调用UserApi类的接口查询列表即可。

    getlist() { //列表数据获取
      var CreationTimeStart = ''
      if (this.searchForm.creationTime && this.searchForm.creationTime.length > 0) {
CreationTimeStart
= this.parseTime(this.searchForm.creationTime[0], '{y}-{m}-{d}')
}
var CreationTimeEnd = '' if (this.searchForm.creationTime && this.searchForm.creationTime.length > 1) {
CreationTimeEnd
= this.parseTime(this.searchForm.creationTime[1], '{y}-{m}-{d}')
}
var param = { //构造常规的分页查询条件 SkipCount: (this.pageinfo.pageindex - 1) * this.pageinfo.pagesize,
MaxResultCount:
this.pageinfo.pagesize,//过滤条件 UserName: this.searchForm.UserName,
PhoneNumber:
this.searchForm.PhoneNumber,
CreationTimeStart: CreationTimeStart,
CreationTimeEnd: CreationTimeEnd
};
//获取列表,绑定到模型上,并修改分页数量 this.listLoading = trueuser.GetAll(param).then(data=>{this.list =data.result.itemsthis.pageinfo.total =data.result.totalCountthis.listLoading = false})
},
search() {
//查询列表处理 this.pageinfo.pageindex = 1;//重置为第一页= this.getlist()
},

通过列表的查询操作,我们就可以把数据获取到,界面就会得到及时的更新显示了

      //获取列表,绑定到模型上,并修改分页数量
      this.listLoading = trueuser.GetAll(param).then(data=>{this.list =data.result.itemsthis.pageinfo.total =data.result.totalCountthis.listLoading = false})

而列表主要就是在界面使用el-table组件进行展示的了,如下图所示代码。

el-table绑定了对应的数据,并设置好显示的格式以及选择操作事件、行双击事件等操作。

而el-table里面的显示的列,需要根据我们返回数据的属性名称进行显示,如下代码所示。

而如果我们需要对属性进行特殊的展示,我们就需要使用v-if条件或者过滤器进行处理了。如下是根据不同内容,构建标签显示内容。

      <el-table-columnalign="center"label="账号激活"width="80">
        <templateslot-scope="scope">
          <el-tagv-if="scope.row.isActive === true"type="success"effect="dark">已激活</el-tag>
          <el-tagv-else type="danger"effect="dark">未激活</el-tag>
        </template>
      </el-table-column>

而对于时间,我们则可以使用格式化函数或者过滤器规范显示的格式内容。

<el-table-columnalign="center"label="创建时间"width="120"prop="creationTime":formatter="dateFormat" />

其中 :formatter="dateFormat"  指定了对应的格式化处理函数。

dateFormat(row, column, cellValue) {//this.parseTime是在main.js中的全局挂载函数
      return cellValue ? this.parseTime(cellValue, '{y}-{m}-{d}') : '' //完整格式:{y}-{m}-{d} {h}-{i}-{s}
},
timeFormat(row, column, cellValue) {
//this.parseTime是在main.js中的全局挂载函数 return cellValue ? this.parseTime(cellValue, '{y}-{m}-{d} {h}:{i}:{s}') : '' //完整格式:{y}-{m}-{d} {h}-{i}-{s} }

另外,操作列的代码,主要就是构建一些方法操作的入口,并传递对应的变量,如ID值即可。

      <el-table-columnalign="center"label="操作"width="190">
        <templatescope="scope">
          <el-row>
            <el-tooltipeffect="light"content="查看"placement="top-start">
              <el-buttonicon="el-icon-search"type="success"circle size="mini"@click="showView(scope.row.id)" />
            </el-tooltip>
            <el-tooltipeffect="light"content="编辑"placement="top-start">
              <el-buttonicon="el-icon-edit"type="primary"circle size="mini"@click="showEdit(scope.row.id)" />
            </el-tooltip>
            <el-tooltipeffect="light"content="删除"placement="top-start">
              <el-buttonicon="el-icon-delete"type="danger"circle size="mini"@click="showDelete(scope.row.id)" />
            </el-tooltip>
            <el-tooltipeffect="light"content="重置密码"placement="top-start">
              <el-buttonicon="el-icon-setting"type="warning"circle size="mini"@click="showSetPass(scope.row.id)" />
            </el-tooltip>
          </el-row>
        </template>
      </el-table-column>

列表的底部分页处理,也是利用对应的属性进行显示即可,并处理分页变化的事件。

    <divclass="block"style="height:70px;">
      <el-pagination:current-page="pageinfo.pageindex":page-size="pageinfo.pagesize":total="pageinfo.total":page-sizes="[10,20,30,40]"layout="total, sizes, prev, pager, next"@size-change="sizeChange"@current-change="currentChange"
      />
    </div>

最后完成列表界面代码,显示列表界面如下所示。

而对于查看、编辑、新增等对话框,一般我们需要创建对应的表单属性,用来承载对应的信息的,如我们为了查看信息的需要,创建一个viewForm的对象,如下所示。

      viewForm: { //查看表单
        id: '',
userName:
'',
surname:
'',
name:
'',
emailAddress:
'',
phoneNumber:
'',
ouNames:
''},

在查看信息对话框里面,我们展示对应的用户信息,包括基础信息和相关的关系,如下界面代码所示。

界面组件通过v-modal进行绑定对应的ViewForm属性对象即可。

最后,我们在触发showView函数里面,获取对应的用户信息,然后展示在界面上即可,showView函数代码如下所示。

    showView(id) { //显示查看对话框处理
      var param ={ id: id }
user.Get(param).then(data
=>{//console.log(data.result) Object.assign(this.viewForm, data.result);this.getOuName(id).then(result =>{this.viewForm.ouNames =result
})
})
this.getFunctionsByUser(id)this.isView = true},

查看界面效果如下所示。

在新增或者编辑处理界面中,我们修改了数据,都会提交到ABP后端进行录入或者更新,因此就涉及到数据的回写处理,然后提示客户端状态即可。

下面是保存编辑界面的内容操作。

    saveEdit() { //保存数据处理
      this.$refs['editForm'].validate(valid =>{if(valid) {//保存数据
          const form = this.editForm
user.Update(form).then(data
=>{//console.log(data) if(data.success) {//提示信息 this.msgSuccess('更新成功!')//刷新数据 this.getlist()
}
else{this.msgError('更新失败:' +data.error)
}
this.$refs['editForm'].resetFields()//重置窗口状态 this.closeDialog()
})
}
})
},

其中msgSuccess、msgError 是全局挂载的提示信息函数,在入口main.js里面统一处理,封装的函数方便在各个界面中统一处理。

以上就是关于用户管理界面的内容介绍,其中涉及到前端API类的封装处理,界面组件的使用,以及一些常规操作,希望能够带给大家一些vue+element开发界面的参考。

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理


循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用


循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用


循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理


循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

VUE+Element 前端应用开发框架功能介绍

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

电商商品数据库的设计和功能界面的处理

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志

循序渐进VUE+Element 前端应用开发(32)--- 手机短信动态码登陆处理

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

使用代码生成工具快速开发ABP框架项目

使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理

使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题

标签: none

添加新评论