项目一系列-第5章 前后端快速开发
第5章 前后端快速开发
学习目标
- 能够使用Element Plus组件改造项目的列表展示效果
- 能够使用若依框架的字典功能配合Element Plus组件展示状态数据
- 能够使用Element Plus组件改造项目的新增和修改的弹窗
- 能够独立集成OSS到项目中
- 能够独立完成功能的接口方法改造
数据字典
数据字典的价值:为企业提供了常量的统一管理。
应用场景:在如下拉框、单选按钮、复选框、树选择中的数据中,方便系统管理员维护。
- 状态的启用、禁用;
- 性别的男、女;
- 订单的已下单、支付中、已完成;
若依框架的字典管理
主要功能包括:字典分类管理、字典数据管理
点击字典类型进行字典详情编辑。
详细的操作步骤如下:
1、添加新的数据字典
2、添加字典数据
数据字典的表关系
在前端项目中引用数据字典
1、在Script标签中引用定义好的数据字典
//引用数据字典
const { nursing_project_status } = proxy.useDict("nursing_project_status");
2、在组件template标签中添加状态下拉框并使用字典数据
<el-form-item label="状态" prop="name"><el-select v-model="queryParams.status" placeholder="请选择" clearable><el-option v-for="item in nursing_project_status" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-form-item>
文件上传到阿里云OSS
如何实现在若依框架中也将文件上传到阿里云OSS中呢?
目前使用的是若依提供的方案,对应的代码如下:
位置:zzyl-admin模块下,com.zzyl.web.controller.common.CommonController.uploadFile
/*** 通用上传请求(单个)*/
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception
{try{// 上传文件路径String filePath = RuoYiConfig.getUploadPath();// 上传并返回新文件名称,保存到本地的目录中String fileName = FileUploadUtils.upload(filePath, file);String url = nursingrConfig.getUrl() + fileName;AjaxResult ajax = AjaxResult.success();ajax.put("url", url);ajax.put("fileName", fileName);ajax.put("newFileName", FileUtils.getName(fileName));ajax.put("originalFilename", file.getOriginalFilename());return ajax;}catch (Exception e){return AjaxResult.error(e.getMessage());}
}
集成OSS模块
推荐:单独创建一个模块,专门来管理OSS。
- 在父工程中创建子模块为:zzyl-oss,如下图所示:
- 在父工程的pom文件中进行版本管理
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zzyl</groupId><artifactId>zzyl</artifactId><version>3.8.8</version><name>zzyl</name><url>http://www.ruoyi.vip</url><description>中州养老后台管理系统</description><properties><aliyun.sdk.oss>3.17.4</aliyun.sdk.oss></properties><!-- 依赖声明 --><dependencyManagement><dependencies><!-- 阿里云OSS --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>${aliyun.sdk.oss}</version></dependency></dependencies></dependencyManagement>
</project>
在zzyl-oss模块中引入aliyun-sdk-oss依赖和zzyl-common依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.zzyl</groupId><artifactId>zzyl</artifactId><version>3.8.8</version></parent><artifactId>zzyl-oss</artifactId><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId></dependency><dependency><groupId>com.zzyl</groupId><artifactId>zzyl-common</artifactId></dependency></dependencies></project>
- 创建oss配置类及客户端
上面的两个类如下:
-
AliyunOSSProperties:配置类,读取aliyun.oss为前缀的属性值(桶名称bucketName,域名站点endpoint)
package com.zzyl.oss;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;@Data @Component @ConfigurationProperties(prefix = "aliyun.oss") public class AliyunOSSProperties {private String endpoint;private String bucketName; }
-
AliyunOSSOperator:通过OSSClient对oss进行交互,提供了上传和删除两个方法
package com.zzyl.oss;import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.model.DeleteObjectsRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.io.ByteArrayInputStream; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.UUID;@Component public class AliyunOSSOperator {@Autowiredprivate AliyunOSSProperties ossProperties;/*** 文件上传** @param content 文件内容* @param originalFilename 文件名* @return 文件访问路径url* @throws Exception*/public String upload(byte[] content, String originalFilename) throws Exception {String endpoint = ossProperties.getEndpoint();String bucketName = ossProperties.getBucketName();// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();// 填写Object完整路径,例如202406/1.png。Object完整路径中不能包含Bucket名称。// 获取当前系统日期的字符串,格式为 yyyy/MMString dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));// 根据原始文件名originalFilename, 生成一个新的不重复的文件名String newFileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));String objectName = dir + "/" + newFileName;// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);// 文件上传try {ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));} finally {if (ossClient != null) {ossClient.shutdown();}}return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName;} }
注意:确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
- zzyl-admin模块引入并配置
先把zzyl-oss模块在父工程中声明:
<!-- 依赖声明 -->
<dependencyManagement><dependencies><!-- 其他依赖配置省略...--><!-- OSS模块 --><dependency><groupId>com.zzyl</groupId><artifactId>zzyl-oss</artifactId><version>${zzyl.version}</version></dependency></dependencies>
</dependencyManagement>
在zzyl-admin模块中引入zzyl-oss依赖
<dependency><groupId>com.zzyl</groupId><artifactId>zzyl-oss</artifactId>
</dependency>
在application.yml文件中添加对oss的配置
# 阿里云OSS相关配置
aliyun:oss:endpoint: https://oss-cn-beijing.aliyuncs.combucketName: zznursing
注意:需要将bucketName改成自己的。
- 修改上传的接口
找到zzyl-admin模块中的com.zzyl.web.controller.common.CommonController类,修改单个文件上传的方法
// 先导入阿里云OSS工具
@Autowired
private AliyunOSSOperator aliyunOSSOperator;/*** 通用上传请求(单个)*/
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception
{try{// 上传文件路径String filePath = RuoYiConfig.getUploadPath();// 上传并返回新文件名称
// String fileName = FileUploadUtils.upload(filePath, file);String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());// String url = serverConfig.getUrl() + fileName;AjaxResult ajax = AjaxResult.success();ajax.put("url", url);ajax.put("fileName", url);ajax.put("newFileName", FileUtils.getName(url));ajax.put("originalFilename", file.getOriginalFilename());return ajax;}catch (Exception e){return AjaxResult.error(e.getMessage());}
}
前端代码能自适应文件上传
为什么文件上传只需要修改后端代码?因为在前端代码中有识别url是否是本地文件存储的判断逻辑。
- 文件位置:src/components/imageUpload/index.vue
watch(() => props.modelValue, val => {if (val) {// 首先将值转为数组const list = Array.isArray(val) ? val : props.modelValue.split(",")// 然后将数组转为对象数组fileList.value = list.map(item => {if (typeof item === "string") {if (item.indexOf(baseUrl) === -1 && !isExternal(item)) {item = { name: baseUrl + item, url: baseUrl + item }} else {item = { name: item, url: item }}}return item})} else {fileList.value = []return []}
},{ deep: true, immediate: true })
baseUrl的定义:
const baseUrl = import.meta.env.VITE_APP_BASE_API
在测试环境下:
# 若依管理系统/开发环境
VITE_APP_BASE_API = '/dev-api'
测试是否能上传图片并展示
护理项目页面改造
-
跟据需求和页面原型进行前端页面改造
-
将模板生成的前端页面与原型进行比较,列出问题。
-
将不需要的部分删除(注释)掉,例如:删除无关按钮及其关联函数。
-
手动加上页面 Form 表单中缺少的 Select 选择器和Dialog 对话框中缺少的 Select 选择器
- 参考链接:https://element-plus.org/zh-CN/component/select.html
-
将页面 Table 表格的状态数字改为 Tag 标签包裹的状态显示
<el-table-column label="状态" align="center" ><template #default="scope"><el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">{{ scope.row.status === 1 ? '启用' : '禁用' }}</el-tag></template></el-table-column>
-
<template #default=“scope”> 这是一个Vue模板插槽的语法。
#default
表示默认插槽,scope
是作用域参数,通过scope
可以访问到父组件传递给插槽的任何数据 -
scope.row 代表的是这一行数据
-
:type=success | danger 表示显示不同的样式 success:成功 danger:危险
-
-
更改页面 Table 表格的序号type、时间显示
{y}-{m}-{d} {h}:{i}:{s}
-
添加禁用和启用按钮(包含图标)
- 图标组件链接:https://element-plus.org/zh-CN/component/icon.html
-
固定操作列和调整列宽width
- 参考链接:https://element-plus.org/zh-CN/component/table.html
-
-
状态管理用数据字典
- 添加数据字典并编辑字典数据
- 修改数据状态不回显问题
- 把返回的状态字段的数据类型改为字符串类型,数据字典是字符串类型的。
护理计划功能开发
第5章-前后端快速开发 - 飞书云文档
护理等级功能开发
数据传输对象DTO
DTO即Data Transfer Object 数据传输对象。
用于封装前端给后端传递的数据。
是一种开发规范,有利于团队开发。
值对象Vo
Vo即Value Object 值对象。
用于封装后端给前端传递的数据。
是一种开发规范,有利于团队开发。
属性拷贝工具BeanUtils
用于拷贝数据到相同属性和相同类型的对象中。
例如:BeanUtils.copyProperties(dto, nursingPlan);
功能开发分几步(CRUD)?
- 需求+原型分析
- 相应表结构关系分析
- 接口文档分析
- 功能实现(对模板生成代码进行改造)
- 如果是单表页面开发,则只需要在模板生成代码的基础上改造前端页面
- 如果是多表页面开发,要在模板生成代码的基础上再开发下面5个接口:
- 查询所有关联信息(手动添加接口代码)
- 新增信息(能够关联多表信息)
- 删除信息(能够关联多表信息)
- 跟据id查询信息(能够关联多表信息)
- 修改信息(能够关联多表信息)
后端接口开发分几步
- 整理实现思路
- 跟据思路编码