文章目录
- 前言
- 一、工器具管理
- 二、入库功能
-
- [1. 前端](#1. 前端)
-
- [1.1 界面展示](#1.1 界面展示)
- [1.2 具体操作实现](#1.2 具体操作实现)
- [1.3 js文件](#1.3 js文件)
- [2. 后端](#2. 后端)
-
- [2.1 工器具信息回显](#2.1 工器具信息回显)
- [2.2 工器具入库](#2.2 工器具入库)
- 三、领用功能
-
- [1. 前端](#1. 前端)
-
- [1.1 界面展示](#1.1 界面展示)
- [1.2 具体实现操作](#1.2 具体实现操作)
- [1.3 js文件](#1.3 js文件)
- [2. 后端](#2. 后端)
-
- [2.1 工器具信息回显](#2.1 工器具信息回显)
- [2.2 工器具领用](#2.2 工器具领用)
- 遇到的问题
-
- [1. 同一页面展示不同弹框](#1. 同一页面展示不同弹框)
- [2. 动态获取数据下拉框信息回显](#2. 动态获取数据下拉框信息回显)
- [3. 循环依赖](#3. 循环依赖)
- [4. 数据库查询结果为空](#4. 数据库查询结果为空)
前言
增删改查相关操作代码由若依框架生成,这部分主要介绍入库和领用功能,可能业务逻辑没那么清晰,主要是实现相关代码,以及在学习的过程中,自己遇到一些问题。(仅个人学习记录)
一、工器具管理
项目总览
在这部分,目前主要编写了包括工器具信息展示,以及工器具的入库和领用功能。入库和领用两个按钮是对原来的修改和删除按钮进行了修改,完成入库和领用操作后,入库记录和领用记录部分也会发生变化(其实就是涉及到对入库表和领用表插入)。
二、入库功能
1. 前端
1.1 界面展示
1.1.1 首先是要定义"入库"这个按钮,代码如下:
html
<el-button
size="mini"
type="text"
@click="handleStorage(scope.row)"
v-hasPermi="['toolManagement:tool:storage']" <!--这个是访问权限,要和后端匹配-->
>入库</el-button>
1.1.2 点击按钮后,弹窗按钮展示。(因为这个页面有几个不同的弹窗--新增和修改、入库以及领用,所以还需要对参数:visible.sync="libraryDialogVisible进行设置)
html
<!-- 入库记录对话框 -->
<el-dialog :title="title" :visible.sync="libraryDialogVisible" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="工器型号" prop="toolModel">
<el-input v-model="form.toolModel" placeholder="请输入工器型号" />
</el-form-item>
<el-form-item label="工器类型" prop="toolType">
<el-input v-model="form.toolType" placeholder="请输入工器类型" />
</el-form-item>
<el-form-item label="工器名称" prop="toolName">
<el-input v-model="form.toolName" placeholder="请输入工器名称" />
</el-form-item>
<el-form-item label="入库数" prop="stockInQuantity">
<el-input-number :min="0" v-model="form.stockInQuantity" placeholder="请输入入库数" />
</el-form-item>
<el-form-item label="入库时间" prop="warehousingTime">
<el-date-picker clearable
v-model="form.warehousingTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择入库时间">
</el-date-picker>
</el-form-item>
<el-form-item label="备注信息" prop="remarkInformation">
<el-input v-model="form.remarkInformation" placeholder="请输入备注信息" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm2">确 定</el-button>
<el-button @click="cancel2">取 消</el-button>
</div>
</el-dialog>
1.2 具体操作实现
实现入库按钮操作handleStorage,并且导入js文件中的getRecord方法,在方法中提供访问url以及访问方式,在后端实现点击"入库"按钮后的弹窗中信息回显
实现入库提交按钮submitForm2,并且导入storage方法,在后端实现插入入库信息到入库记录表中
在前面两个方法中都需要把libraryDialogVisible设置为true,代表显示弹框
点击取消按钮,需要把libraryDialogVisible设置为false
html
data() {
return {
...
// 是否显示弹出层
open: false, //用于修改和新增的弹框
libraryDialogVisible:false, //用于入库弹框
requisitionVisible:false, //用于领用弹框
....
}
//入库按钮操作
handleStorage(row) {
this.reset();
this.libraryDialogVisible=true;
const toolManagementId = row.toolManagementId || this.ids
getRecord(toolManagementId).then(response => {
this.form = response.data;
this.libraryDialogVisible = true;
this.title = "入库";
});
}
/** 入库提交按钮 */
submitForm2() {
this.$refs["form"].validate(valid => {
if (valid) {
storage(this.form).then(response => {
this.$modal.msgSuccess("入库成功");
this.libraryDialogVisible = false;
this.getList();
});
}
});
},
// 取消按钮
cancel2() {
this.libraryDialogVisible = false;
this.reset();
},
1.3 js文件
在对应的js文件中写个getRecord方法和storage方法
js
//获取工器具记录信息
export function getRecord(toolManagementId) {
return request({
url: '/toolManagement/tool/storage/' + toolManagementId,
method: 'get'
})
}
//工器具入库
export function storage(data) {
return request({
url: '/toolManagement/tool/storage',
method: 'put',
data: data
})
}
2. 后端
2.1 工器具信息回显
2.1.1 Controller层编写getStorageInfo方法实现信息回显,根据工器具id查询相关工器具信息,设置访问方式GetMapping,url以及访问权限一定要和前端的一样。
java
/**
* 获取工器具信息(入库)
*/
@PreAuthorize("@ss.hasPermi('toolManagement:tool:queryId')")
@GetMapping(value = "/storage/{toolManagementId}")
public AjaxResult getStorageInfo(@PathVariable("toolManagementId") Long toolManagementId)
{
StorageVO storageVO = sysToolService.getStorageInfo(toolManagementId);
return success(storageVO);
}
2.2.2 具体的业务逻辑service-serviceImpl-mapper-mapper.xml,这部分用于信息回显,
java
/**service
* 根据id获得入库信息
* @param toolManagementId
* @return
*/
StorageVO getStorageInfo(Long toolManagementId);
//serviceImp:
@Override
public StorageVO getStorageInfo(Long toolManagementId) {
return sysToolMapper.getStorageInfo(toolManagementId);
}
//mapper
StorageVO getStorageInfo(Long id);
xml
<select id="getStorageInfo" parameterType="Long" resultMap="BaseResultMap">
select tool_model,tool_type,tool_name from sys_tool where tool_management_id=#{id}
</select>
2.2 工器具入库
2.2.1 前端填写好信息,点击提交按钮会有入库记录。在Controller层编写方法,StorageDTO根据前端页面展示的信息写的一个实体类
java
/**
* 工器具入库
* @param storageDTO
* @return
*/
@PreAuthorize("@ss.hasPermi('toolManagement:tool:storage')")
@Log(title = "工器具入库", businessType = BusinessType.UPDATE)
@PutMapping("/storage")
public AjaxResult storage(@RequestBody StorageDTO storageDTO) {
sysToolService.storage(storageDTO);
return success();
}
2.2.2 具体的业务逻辑service-serviceImpl-mapper-mapper.xml,主要业务逻辑包括工器具库存的增加,工器具入库表记录插入数据
java
/**service
* 工器具入库以及修改库存信息
* @param storageDTO
*/
void storage(StorageDTO storageDTO);
//serviceImpl
//在这里涉及到两张表的操作要加入事务处理
@Override
@Transactional
public void storage(StorageDTO storageDTO) {
int num = storageDTO.getStockInQuantity();
String toolModel = storageDTO.getToolModel();
//查询工器具已有库存数
int stock = sysToolMapper.selectSysToolNumById(toolModel);
stock = num+stock;
//根据工器具型号工器具表sys_tool修改库存
sysToolMapper.updateSysToolByMode(stock,toolModel);
//在sys_warehousing_record入库表中添加记录
WarehousingRecord warehousingRecord = new WarehousingRecord();
BeanUtils.copyProperties(storageDTO,warehousingRecord);
warehousingRecord.setStockInQuantity(Long.valueOf(num));
warehousingRecord.setRecommend(0L);
warehousingRecordService.insertWarehousingRecord(warehousingRecord);
}
mapper文件
java
/**
* 查询表中库存信息
* @param toolModel
* @return
*/
@Select("select stock from sys_tool where tool_model=#{toolModel}")
int selectSysToolNumById(String toolModel);
/**
* 根据工器具类型修改库存数量
* @param num
* @param toolModel
*/
@Update("update sys_tool set stock=#{num} where tool_model like #{toolModel}")
void updateSysToolByMode(@Param("num") int num, @Param("toolModel") String toolModel);
/**
* 新增入库记录(若依代码生成)
* @param warehousingRecord 入库记录
*/
public int insertWarehousingRecord(WarehousingRecord warehousingRecord);
三、领用功能
这部分和入库不同的点在于,领用人是一个下拉框,要展示的是一个列表信息,而且领用人的信息存于用户表中,所以要怎么在后端定义一个实体类用于返回给前端数据是我之前不知道怎么搞的,而且这个下拉框怎么去遍历列表,需要哪些信息也是要考虑的。在实现这个功能的时候,我还出现了循环依赖问题(这个最后给出解决办法)
1. 前端
1.1 界面展示
1.1.1 定义"领用"这个按钮,代码如下:
html
<el-button
size="mini"
type="text"
@click="handlerequisition(scope.row)"
v-hasPermi="['toolManagement:tool:requisition']"
>领用</el-button>
1.1.2 点击按钮后,弹窗按钮展示。(重新设置了:visible.sync="requisitionVisible,由于定义了一个"领用人"下拉框信息回显,在前端代码做了修改,后端响应给前端的数据也与之对应)
html
<!-- 领用记录对话框 -->
<el-dialog :title="title" :visible.sync="requisitionVisible" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="工器型号" prop="toolModel">
<el-input v-model="form.toolModel" placeholder="请输入工器型号" />
</el-form-item>
<el-form-item label="工器类型" prop="toolType">
<el-input v-model="form.toolType" placeholder="请输入工器类型" />
</el-form-item>
<el-form-item label="工器名称" prop="toolName">
<el-input v-model="form.toolName" placeholder="请输入工器名称" />
</el-form-item>
<el-form-item label="数量" prop="number">
<el-input-number :min="0" v-model="form.number" placeholder="请输入数量" />
</el-form-item>
<el-form-item label="领用时间" prop="collectionTime">
<el-date-picker clearable
v-model="form.collectionTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择领用时间">
</el-date-picker>
</el-form-item>
<el-form-item label="领用人" prop="receiver">
<el-select v-model="form.receiver" placeholder="请选择领用人" >
<el-option
v-for="item in form.users" <!--这个users对应的后端返回的RequisitionVO中List<UserDTO> users -->
:key="item.userId" <!--users.userId和users.userName是从用户表中查到的信息,用于信息回显 -->
:label="item.userName"
:value="item.userName"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注信息" prop="remarkInformation">
<el-input v-model="form.remarkInformation" placeholder="请输入备注信息" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm3">确 定</el-button>
<el-button @click="cancel3">取 消</el-button>
</div>
</el-dialog>
1.2 具体实现操作
实现领用按钮操作handlerequisition,并且导入js文件中的getrequisitionInfo方法,实现点击"领用"按钮后的弹窗中信息回显。
实现领用提交按钮操作,主要是把填入的信息插入到领用表中,在前端定义requisition方法提供接口。
领用取消按钮要把requisitionVisible置为false。
html
/** 领用按钮操作 */
handlerequisition(row) {
this.reset();
this.requisitionVisible=true;
const toolManagementId = row.toolManagementId || this.ids
getrequisitionInfo(toolManagementId).then(response => {
this.form = response.data;
this.requisitionVisible = true; //开启弹窗
this.title = "领用";
});
},
/** 领用提交按钮 */
submitForm3() {
this.$refs["form"].validate(valid => {
if (valid) {
requisition(this.form).then(response => {
this.$modal.msgSuccess("领用成功");
this.requisitionVisible = false; //点击提交按钮后关闭弹窗
this.getList();
});
}
});
},
// 领用取消按钮
cancel3() {
this.requisitionVisible = false; //点击取消按钮关闭弹窗
this.reset();
},
1.3 js文件
在对应的js文件中写个getrequisitionInfo方法和requisition方法
js
//获取工器具领用信息
export function getrequisitionInfo(toolManagementId) {
return request({
url: '/toolManagement/tool/requisition/' + toolManagementId,
method: 'get'
})
}
//工器具领用
export function requisition(data) {
return request({
url: '/toolManagement/tool/requisition',
method: 'put',
data: data
})
}
2. 后端
2.1 工器具信息回显
2.1.1 Controller层编写getrequisitionInfo方法实现信息回显,根据工器具id查询相关工器具信息,此外还要从用户表中查询所有用户信息,用于领用人下拉框列表的信息回显。
java
/**
* 获取工器具信息(领用)
*/
@PreAuthorize("@ss.hasPermi('toolManagement:tool:queryrequisition')")
@GetMapping(value = "/requisition/{toolManagementId}")
public AjaxResult getrequisitionInfo(@PathVariable("toolManagementId") Long toolManagementId)
{
RequisitionVO requisitionVO = sysToolService.getrequisitionInfo(toolManagementId);
return success(requisitionVO);
}
2.2.2 具体的业务逻辑service-serviceImpl-mapper-mapper.xml,这部分用于信息回显,
java
//获取领用信息
RequisitionVO getrequisitionInfo(Long toolManagementId);
//serviceImp:
/**
* 领用信息回显
* @param toolManagementId
* @return
*/
@Override
public RequisitionVO getrequisitionInfo(Long toolManagementId) {
//查询所有用户信息,定义了一个UserDTO用于保存返回给前端信息,包括用户id(主要是在前端遍历的时候使用)和用户账号
List<UserDTO> userDTOS = userService.selectUserName();
//获取工器具的详细信息,这和入库中信息回显是一样的
StorageVO storageInfo = sysToolMapper.getStorageInfo(toolManagementId);
//RequisitionVO用于返回给前端所需的数据
RequisitionVO requisitionVO = new RequisitionVO();
BeanUtils.copyProperties(storageInfo,requisitionVO);
requisitionVO.setUsers(userDTOS);
return requisitionVO;
}
//mapper
/**
* 查询所有用户名称
* @return
*/
List<UserDTO> selectUserName();
xml
<select id="selectUserName" resultMap="UserDTOResult">
select user_id, user_name from sys_user
</select>
2.2 工器具领用
1、 前端填写好信息,点击提交按钮会有入库记录。在Controller层编写requisition方法,RequisitionDTO根据前端页面展示的信息写的一个实体类
java
public class RequisitionDTO {
/** 工器型号 */
private String toolModel;
/** 工器类型 */
private String toolType;
/** 工器名称 */
private String toolName;
/** 数量 */
private Integer number;
/** 领用时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date collectionTime;
/** 领用人 */
private String receiver;
/** 备注信息 */
private String remarkInformation;
}
/**
* 工器具领用
* @param requisitionDTO
* @return
*/
@PreAuthorize("@ss.hasPermi('toolManagement:tool:requisition')")
@Log(title = "工器具领用", businessType = BusinessType.UPDATE)
@PutMapping("/requisition")
public AjaxResult requisition(@RequestBody RequisitionDTO requisitionDTO) {
//工器具领用
sysToolService.requisition(requisitionDTO);
return success();
}
2、具体的业务逻辑service-serviceImpl-mapper-mapper.xml,主要业务逻辑包括工器具库存的减少,工器具领用表记录插入数据
java
@Transactional
@Override
public void requisition(RequisitionDTO requisitionDTO) {
int num = requisitionDTO.getNumber();
String toolModel = requisitionDTO.getToolModel();
//查询工器具已有库存数
int stock = sysToolMapper.selectSysToolNumById(toolModel);
//判断库存数是否不足
if(stock<=0){
throw new RuntimeException("库存不足");
}
stock = stock-num;
//根据工器具型号工器具表sys_tool修改库存
sysToolMapper.updateSysToolByMode(stock,toolModel);
//在sys_requisition_record领用表中添加记录
RequisitionRecord requisitionRecord = new RequisitionRecord();
BeanUtils.copyProperties(requisitionDTO,requisitionRecord);
requisitionRecord.setNumber(Long.valueOf(num));
requisitionRecord.setRecommend(0L);
//若依框架代码生成
requisitionRecordService.insertRequisitionRecord(requisitionRecord);
}
遇到的问题
1. 同一页面展示不同弹框
因为没有接触过前端,所以一开始不知道怎么处理,这里简单的描述一下吧,前面的前端代码有展示。
1、首先就是定义不同的弹框,<el-dialog .../>,设置不同的:visible.sync=xxx
2、在export default {data(){xxx:false }}定义好数据
3、在具体的操作中设置,比如我点击入库按钮有弹窗,那么就要把xxx设置为true,点击取消按钮,弹框消失就要把它设置为false。
2. 动态获取数据下拉框信息回显
从后端数据库获取的信息全部用下拉框展示。在这部分,我需要回显的信息设置两个表的操作,所以我定义了一个VO实体类,具体如下:
java
public class RequisitionVO {
//工器型号
private String toolModel;
/** 工器类型 */
private String toolType;
/** 工器名称 */
private String toolName;
//领用人
//这部分是用于下拉框信息回显的数据,用的是一个列表
private List<UserDTO> users;
}
//用户信息
public class UserDTO {
//用户id
private Long userId;
//用户账号
private String userName;
}
虽然我只需要下拉框展示用户账号,但是在这里还需要有个id与之对应,用于前端代码v-for。
html
<el-form-item label="领用人" prop="receiver">
<el-select v-model="form.receiver" placeholder="请选择领用人" >
<el-option
v-for="item in form.users"
:key="item.userId"
:label="item.userName"
:value="item.userName">
</el-option>
</el-select>
</el-form-item>
3. 循环依赖
我用的若依系统,直接用的系统原有的用户表,因为领用需要获取领用人信息,刚开始操作的时候就直接在ruo-system中的文件夹中使用了,而我之前在自己的模块中导入了ruo-system依赖,又在ruo-system导入了ruoyi-toolManagement中的类,结果造成了循环依赖的问题,具体解决办法参考以下链接https://blog.csdn.net/m0_53979927/article/details/132954989
4. 数据库查询结果为空
Mapper接口方法传两个参数要加Param注解,以及返回多个结果要用resultMap。