024-从零搭建微服务-系统服务(六)

2023-10-26

写在最前

如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。

源码地址(后端):https://gitee.com/csps/mingyue

源码地址(前端):https://gitee.com/csps/mingyue-ui

文档地址:https://gitee.com/csps/mingyue/wikis

本节概要

mingyue-ui 目前与后端交互只有登录登出接口,本节从用户入手,完成用户前后端交互增删改查

分页查询用户

分页查询通用类

@Data
@Schema(description = "分页查询通用类")
public class PageCommon implements Serializable {

	private static final long serialVersionUID = 1L;

	@Schema(description = "分页大小")
	private Integer pageSize;

	@Schema(description = "当前页数")
	private Integer pageNum;

	@Schema(description = "排序列")
	private String orderByColumn;

	@Schema(description = "排序的方向 desc 或者 asc")
	private String isAsc;

	/**
	 * 当前记录起始索引 默认值
	 */
	public static final int DEFAULT_PAGE_NUM = 1;

	/**
	 * 每页显示记录数 默认值 默认查全部
	 */
	public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;

	public <T> Page<T> build() {
		Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM);
		Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE);
		if (pageNum <= 0) {
			pageNum = DEFAULT_PAGE_NUM;
		}
		Page<T> page = new Page<>(pageNum, pageSize);
		List<OrderItem> orderItems = buildOrderItem();
		if (CollUtil.isNotEmpty(orderItems)) {
			page.addOrder(orderItems);
		}
		return page;
	}

	/**
	 * 构建排序
	 *
	 * 支持的用法如下: {isAsc:"asc",orderByColumn:"id"} order by id asc
	 * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
	 * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc
	 * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc
	 */
	private List<OrderItem> buildOrderItem() {
		if (StrUtil.isBlank(orderByColumn) || StrUtil.isBlank(isAsc)) {
			return null;
		}
		String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
		orderBy = StrUtil.toUnderlineCase(orderBy);

		String[] orderByArr = orderBy.split(StrUtil.COMMA);
		String[] isAscArr = isAsc.split(StrUtil.COMMA);
		if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) {
			throw new ServiceException("排序参数有误");
		}

		List<OrderItem> list = new ArrayList<>();
		// 每个字段各自排序
		for (int i = 0; i < orderByArr.length; i++) {
			String orderByStr = orderByArr[i];
			String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i];
			if ("asc".equals(isAscStr)) {
				list.add(OrderItem.asc(orderByStr));
			}
			else if ("desc".equals(isAscStr)) {
				list.add(OrderItem.desc(orderByStr));
			}
			else {
				throw new ServiceException("排序参数有误");
			}
		}

		return list;
	}

}

接口层

@GetMapping("list")
@SaCheckPermission("system:user:list")
@Operation(summary = "获取所有用户信息")
public R<IPage<SysUserVo>> getSysUsers(PageCommon page, UserQueryDto dto) {
  return R.ok(sysUserService.getSysUsers(page, dto));
}

逻辑层

@Override
public IPage<SysUserVo> getSysUsers(PageCommon page, UserQueryDto dto) {
  return sysUserMapper.getUserVosPage(page.build(), dto);
}

数据层

<select id="getUserVosPage" resultType="com.csp.mingyue.system.api.vo.SysUserVo">
      SELECT su.*,sr.role_name, sr.role_code
      FROM sys_user su
      LEFT JOIN sys_user_role sur ON sur.user_id = su.user_id
      LEFT JOIN sys_role sr ON sur.role_id = sr.role_id
      <where>
          su.is_deleted = '0'
          <if test="query.username != null and query.username != ''">
              <bind name="usernameLike" value="'%' + query.username + '%'" />
              and su.username LIKE #{usernameLike}
          </if>
      </where>
      ORDER BY su.create_time DESC
  </select>

接口测试

非排序入参

curl -X 'GET' \
  'http://mingyue-gateway:9100/system/sysUser/list?pageSize=10&pageNum=1&username=' \
  -H 'accept: */*' \
  -H 'Authorization: vhiqUYS3NtT5zpvyzwudffAhyu3vswAV'

排序入参

curl -X 'GET' \
  'http://mingyue-gateway:9100/system/sysUser/list?pageSize=10&pageNum=2&orderByColumn=userId&isAsc=desc&username=' \
  -H 'accept: */*' \
  -H 'Authorization: vhiqUYS3NtT5zpvyzwudffAhyu3vswAV'

添加或编辑用户

接口层

@PostMapping("addOrEdit")
@Operation(summary = "添加或编辑用户")
public R<Boolean> addOrEdit(@Valid @RequestBody UserAddOrEditDto dto) {
  return R.ok(sysUserService.addOrEdit(dto));
}

逻辑层

@Override
@Transactional(rollbackFor = Exception.class)
public boolean addOrEdit(UserAddOrEditDto dto) {
  SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);

  // 添加用户
  if (Objects.isNull(sysUser.getUserId())) {
    // 密码加密
    sysUser.setPassword(BCrypt.hashpw(sysUser.getPassword(), userPasswordProperties.getSalt()));
  }

  boolean flag = this.saveOrUpdate(sysUser);
  if (!flag) {
    throw new UserException("用户信息保存异常");
  }

  // 保存角色关系
  flag = sysRoleService.addUserRole(sysUser.getUserId(), dto.getRoleCode());
  if (!flag) {
    throw new UserException("用户角色信息保存异常");
  }

  return true;
}

删除用户

接口层

@DeleteMapping("{userId}")
@Operation(summary = "删除用户", parameters = { @Parameter(name = "userId", description = "用户ID", required = true) })
public R<Boolean> delUser(@PathVariable Long userId) {
  return R.ok(sysUserService.delUser(userId));
}

逻辑层

@Override
public boolean delUser(Long userId) {
  return sysUserMapper.deleteByIdLogic(userId) > 0;
}

数据层

<delete id="deleteByIdLogic">
    UPDATE sys_user su SET su.is_deleted = '1' WHERE su.user_id = #{userId}
</delete>

mingyue-ui 接口交互

接口定义

list: (page: object) => {
    return request({
        url: '/api/system/sysUser/list',
        method: 'get',
        params: page
    });
},
addOrEdit: (data: object) => {
    return request({
        url: '/api/system/sysUser/addOrEdit',
        method: 'post',
        data: data
    });
},
del: (userId: number) => {
    return request({
        url: '/api/system/sysUser/' + userId,
        method: 'delete'
    });
}

分页查询

src/views/system/user/index.vue

const getTableData = async () => {
  state.tableData.loading = true;

  const res = await getUserList();
  state.tableData.data = res.data.records;
  state.tableData.total = res.data.total;

  state.tableData.loading = false;
};

添加或编辑用户

src/views/system/user/dialog.vue

const onSubmit = () => {
  userApi().addOrEdit(state.ruleForm).then(res => {
    if (res.data) {
      closeDialog();
      emit('refresh');
      state.dialog.type === 'add' ? ElMessage.success('添加成功') : ElMessage.success('修改成功');
    } else {
      state.dialog.type === 'add' ? ElMessage.error('添加失败') : ElMessage.error('修改失败');
    }
  })
};

删除用户

src/views/system/user/index.vue

const onRowDel = (row: RowUserType) => {
	ElMessageBox.confirm(`此操作将永久删除账户名称:“${row.username}”,是否继续?`, '提示', {
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
      userApi().del(row.userId).then(() => {
        getTableData();
        ElMessage.success('删除成功');
      });
		})
		.catch(() => {});
};

小结

用户管理已经可以交互接口完成真实的增删改查了。

目前 mingyue 已经包含了 统一网关服务统一认证服务统一系统服务统一推送服务,距离目标还差

统一文件服务统一定时服务统一搜索服务 等等。接下来搞一搞 统一文件服务 吧!

本人后端一枚,前端粗通,等后续后端服务基本完成后,再去抽时间完善前端代码哈~~ 见谅《 - 。- 》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

024-从零搭建微服务-系统服务(六) 的相关文章

  • Android10.0 Binder通信原理(七)-Framework binder示例

    Android取经之路 的源码都基于Android Q 10 0 进行分析 Android取经之路 系列文章 系统启动篇 Android系统架构Android是怎么启动的Android 10 0系统启动之init进程Android10 0系
  • 幸有一事,生死可许

    已然到了岁末 2014就要结束 迎来崭新的2015 颇多感慨 颇多难忘 与其说是2014年是我职业生涯中至关重要的一年 倒不如说是我人生道路上极为重要的一步来的更为贴切 这一年忙忙碌碌 一刻不得清闲 却是极为充实 没有迷茫 没有挣扎 有的只

随机推荐

  • httpclient发送Get请求和Post请求

    创建HttpClient发送请求 接收响应 Get请求简介 get无参数 get有参数 Post请求简介 post携带JSON参数 post携带表单参数 postman自动生成OKhttp代码 Get请求简介 1 创建HttpClient对
  • 华为交换机日常用巡检命令

    display version 查看设备允许版本 display startup 检查软件包 display licence 检查Licence信息 display patch information 检查补丁信息 display cloc
  • nrm安装后报错的解决办法(windows环境)

    安装 nrm npm install g nrm 运行nrm ls报错 配置系统环境变量 查询npm所在的路径 执行以下命令 其中prefix就是所需路径 npm config ls 新建系统环境变量 变量名 自己可定 只要与下一步添加时一
  • git解决冲突方法

    多人协作代码 若修改区域不是同一块很容易解决 场景描述 初始master上代码版本号为A 他人在本地修改后提交到master 版本号变为B 但此时我本地版本号仍是A 本地修改之后变为B 无法进行推送 解决方案 1 查看并创建分支 git b
  • Scala如何使用元组?用法代码实例

    Tuple是元素的集合 元组是异构的数据结构 也就是说 它们可以存储不同数据类型的元素 元组是不可变的 不像scala中的数组是可变的 存储整数 字符串和布尔值的元组的示例 val name 15 Chandan true 元组的类型由其所
  • pytorch函数详解

    pytorch函数详解 在typora这里写之后复制到简书上 1 torchvision 1 1 transforms Compose transforms 把几个转换组合 example from PIL import Image t t
  • k-均值(k-means)及Matlab动态实现

    k 均值 k means 及Matlab实现 注 1 仅适合于数值属性的数据 2 对正态分布 高斯分布 数据聚类效果最佳 1 算法思想 k means算法 也称k 均值算法 它把N个对象划分成k个簇 用簇中对象的均值表示每个簇的中心点 质心
  • 红黑树与平衡二叉树_奈学:红黑树(RedBlackTree)的概述

    1 AVL树与红黑树 AVL树是一种自平衡的二叉查找树 又称平衡二叉树 AVL用平衡因子判断是否平衡并通过旋转来实现平衡 它的平衡的要求是 所有节点的左右子树高度差不超过1 AVL树是一种高平衡度的二叉树 执行插入或者删除操作之后 只要不满
  • IAR EW for STM8 3.11.1汉化包汉化教程

    IAR EW for STM8 3 11 1汉化包汉化教程 汉化包下载地址 https me csdn net download u010210711 汉化教程直接将汉化包解压后复制到安装目录的bin文件夹 如 C Program File
  • C++ cstdlib – 概览

    什么是 C cstdlib C 标准库头文件 cstdlib in C 是 C 程序员使用最广泛的库头文件 它定义了一系列函数和宏 以实现跨团队 跨平台的高效且具有卓越表现的标准化 C 代码 C 是一种广受欢迎的程序语言 它能崛起的最初原因
  • HIMA F3330 984333002 伺服驱动模块

    运动控制 HIMA F3330 984333002 伺服驱动模块通常用于精确的运动控制应用 可以控制电机以特定速度和位置进行运动 位置反馈 HIMA F3330 984333002 伺服驱动模块可能支持位置反馈功能 以确保电机运动的准确性和
  • 你不得不知的几个互联网ID生成器方案

    服务化 分布式已成为当下系统开发的首选 高并发操作在数据存储时 需要一套id生成器服务 来保证分布式情况下全局唯一性 以确保系统的订单创建 交易支付等场景下数据的唯一性 否则将造成不可估量的损失 基于时间戳 比如流水号规则如下 XX YYY
  • C语言编程获取PE文件File_Header内容

    include
  • Js逆向练习制造Token与Id

    前言 闲来无聊 把 Pyhton3网络爬虫开发实战 第二版 看完了Js逆向部分 最后的实战部分感觉挺有挑战性的 正好崔佬也有详细的教程 平时的逆向都是野路子 刚好快回学校了有时间 那为什么不自己动手下呢 下面记录下过程 只会更加详细 观察页
  • [从零开始学习FPGA编程-33]:进阶篇 - 基本时序电路-寄存器(Verilog语言)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 前言 第1章 寄存器介绍 1 1 时序电路的两大特征
  • Qt 常用设计模式-单例模式(Singleton)

    单例 顾名思义 为了保证一个类仅有一个实例 并提供一个可以访问它的全局访问点 避免一个全局使用的类频繁的创建和销毁 节省系统资源 提高程序效率 如何创建唯一的实例 如果是A a new A 但是这么做的话就会有多个实例 所以我们需要把构造函
  • 记一个好用的xshell替代工具-mobaxterm

    https zhuanlan zhihu com p 56341917 现今软件市场上有很多终端工具 比如 secureCRT Putty telnet 等等 secureCRT其实也是一款很强大的终端工具 良许也使用过它很长时间 但是 它
  • 合法三角形数量

    题目1 给定一个n个正整数的数组a 问在其中取三个数 同时满足以下两个条件的取法有多少个 1 这三个数能构成三角形 即任意两数之和大于第三数 2 这三个数构成的三角形既不是等边三角形 也不是直角三角形 数据范围 3 lt n lt 2000
  • 通过 kubectl 查看 K8s 内节点、Pod 资源使用情况

    一 kubectl describe node 可通过该命令查看 Pod 在节点上的资源分配情况 Request Limits 如下 product 表示生产环境 kubectl describe node l env product 执行
  • 024-从零搭建微服务-系统服务(六)

    写在最前 如果这个项目让你有所收获 记得 Star 关注哦 这对我是非常不错的鼓励与支持 源码地址 后端 https gitee com csps mingyue 源码地址 前端 https gitee com csps mingyue u