代码随记 SpringBoot Ruoyi 01
系列 - 代码随记
目录
1 须知
因本人已有Ruoyi基础,因此本笔记只是跟着黑马的教程重新过一次Ruoyi,梳理下知识点。
2 代码生成
基本信息 实体类名称改成
TbCourse--->Course一般不需要前面。字段信息
id:因为是自增的,所以不需要勾选create_time和update_time因为我们是数据库自动填充的,因此不需要勾选
编辑一般跟插入保持一致
列表:有哪些字段需要显示出来 查询:有哪些是可以查询的

- 生成信息

第一步先在数据库中执行SQL,然后复制对应文件,直接复制就可以了!
3 定时任务
定时任务必须放在 com.ruoyi.quartz.task 里面
package com.ruoyi.quartz.task;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyTask {
public void showTime(){
System.out.println("定时任务开始执行:" + new Date());
}
}
4 二次开发
添加模块三步走
- 第一步:添加模块
sky-merchant - 第二步:在新模块下
pom.xml添加核心模块依赖
<dependencies>
<!--核心模块-->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-framework</artifactId>
</dependency>
</dependencies>- 第三步:在父
pom.xml中锁定版本
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
...
<!-- 商家管理-->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-merchant</artifactId>
<version>${sky.version}</version>
</dependency>
</dependencies>
</dependencyManagement>- 第四步:在
sky-admin中引入新模块
<dependencies>
<!-- 商家管理-->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-merchant</artifactId>
<version>${sky.version}</version>
</dependency>
</dependencies>菜品管理-代码生成
上来第一步基本信息改一下,实体类名称=tbDish=Dish,去掉前缀,改下作者名
- 字段信息
- 这一步我们需要根据需求去做
插入:ID是自增的所以去掉、创建和更新时间之后是自动填充的。编辑:和插入保持一致列表:不需要展示描述信息查询:只需要根据name和status查询- 需要添加 售卖状态
dish_status的字典。
- 接下来要配置主子表
- 主要看关联信息,其实很简单

- 子表
tb_dish_flavor- 只需要修改基本信息的实体类名称就可以了
接下来直接下载代码,覆盖即可使用
4.1 前端优化
- 需要说明下
handleUpdate和submitForm,因为el-select选中是数据是[[无糖], [半糖]],这种形式的,因此我们需要将转化为字符串。 - 还有个坑是
row.value = [],因为口味列表的el-select是绑定scope.row.value,而不是checkValueList,要注意v-model。

<el-table-column label="口味名称" prop="name" width="150">
<template #default="scope">
<!-- <el-input v-model="scope.row.name" placeholder="请输入口味名称" /> -->
<el-select
v-model="scope.row.name"
placeholder="请输入口味名称"
@change="changeFlavorName(scope.row)"
>
<el-option
v-for="item in dishFlavorListSelect"
:key="item.name"
:label="item.name"
:value="item.name"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="口味列表" prop="value" width="300">
<template #default="scope">
<el-select
v-model="scope.row.value"
placeholder="请输入口味列表"
@focus="focusFlavorName(scope.row)"
multiple
style="width: 90%;"
>
<el-option
v-for="item in checkValueList"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</template>
</el-table-column>/** 定义口味名称和口味列表静态数据 */
const dishFlavorListSelect = ref([
{ name: "辣度", value: ["不辣", "微辣", "中辣", "重辣"] },
{ name: "忌口", value: ["不要葱", "不要蒜", "不要香菜", "不要辣"] },
{ name: "甜味", value: ["无糖", "少糖", "半糖"] },
]);
// 口味列表
const checkValueList = ref([]);
// 修改口味列表
function changeFlavorName(row) {
// 清空之前列表
row.value = [];
dishFlavorListSelect.value.forEach((item) => {
if (item.name == row.name) {
checkValueList.value = item.value;
}
});
}
// 口味列表获取焦点时, 更新当前选中数据
function focusFlavorName(row) {
dishFlavorListSelect.value.forEach((item) => {
if (item.name == row.name) {
checkValueList.value = item.value;
}
});
}
/** 修改按钮操作 */
function handleUpdate(row) {
...
// 将口味列表 value 字符串转换为 JSON 数组
// "['无糖', '半糖']" >>> ['无糖', '半糖']
dishFlavorList.value.forEach((item) => {
item.value = JSON.parse(item.value);
});
...
}
/** 提交按钮 */
function submitForm() {
...
// 将 value 转化为字符串
// [[无糖], [半糖]]>>>["无糖", "半糖"]
form.value.dishFlavorList.forEach((item) => {
item.value = JSON.stringify(item.value);
});
...
}5 项目实战
https://ksg50j5gph.feishu.cn/docx/NxIqdCZVzo2tRfxNL6Nc1BD1nnf
CREATE TABLE `tb_region` (
`id` INT AUTO_INCREMENT COMMENT '主键id' PRIMARY KEY,
`region_name` VARCHAR(255) NOT NULL COMMENT '区域名称',
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`create_by` VARCHAR(64) COMMENT '创建人',
`update_by` VARCHAR(64) COMMENT '修改人',
`remark` TEXT COMMENT '备注'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='区域表';
-- 插入测试数据
INSERT INTO `tb_region` (`region_name`,`remark`) VALUES ('北京市朝阳区','北京市朝阳区'), ('北京市海淀区','北京市海淀区'), ('北京市东城区','北京市东城区');
CREATE TABLE `tb_partner` (
`id` INT AUTO_INCREMENT COMMENT '主键id' PRIMARY KEY,
`partner_name` VARCHAR(255) NOT NULL COMMENT '合作商名称',
`contact_person` VARCHAR(64) COMMENT '联系人',
`contact_phone` VARCHAR(15) COMMENT '联系电话',
`profit_ratio` INT COMMENT '分成比例',
`account` VARCHAR(64) COMMENT '账号',
`password` VARCHAR(64) COMMENT '密码',
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`create_by` VARCHAR(64) COMMENT '创建人',
`update_by` VARCHAR(64) COMMENT '修改人',
`remark` TEXT COMMENT '备注'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='合作商表';
-- 插入测试数据
INSERT INTO `tb_partner` (`partner_name`, `contact_person`, `contact_phone`, `profit_ratio`, `account`, `password`) VALUES
('合作商A', '张三', '13800138000', 30, 'a001', 'pwdA'),
('合作商B', '李四', '13912345678', 25, 'b002', 'pwdB');
CREATE TABLE `tb_node` (
`id` INT AUTO_INCREMENT COMMENT '主键id' PRIMARY KEY,
`node_name` VARCHAR(255) NOT NULL COMMENT '点位名称',
`address` VARCHAR(255) NOT NULL COMMENT '详细地址',
`business_type` INT COMMENT '商圈类型',
`region_id` INT COMMENT '区域ID',
`partner_id` INT COMMENT '合作商ID',
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`create_by` VARCHAR(64) COMMENT '创建人',
`update_by` VARCHAR(64) COMMENT '修改人',
`remark` TEXT COMMENT '备注',
FOREIGN KEY (`region_id`) REFERENCES `tb_region`(`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`partner_id`) REFERENCES `tb_partner`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='点位表';
-- 插入测试数据
-- 假设区域ID为1对应'北京市朝阳区',合作商ID为1对应'合作商A'
INSERT INTO `tb_node` (`node_name`, `address`, `business_type`, `region_id`, `partner_id`) VALUES
('三里屯点位', '北京市朝阳区三里屯路', 1, 1, 1),
('五道口点位', '北京市海淀区五道口', 2, 2, 2);
- 小结
- 一个区域可以有多个点位
- 一个合作商可以有多个点位
若依默认会关掉驼峰命名转换字段,在xml里面。下面案例中是使用 node_count,而在VO实体中是叫 nodeCount。
<select id="selectRegionVoList" resultType="com.dkd.manage.domain.vo.RegionVo">
SELECT r.*, COUNT(n.id) AS node_count FROM tb_region r LEFT JOIN tb_node n ON r.id = n.region_id
<where>
<if test="regionName != null and regionName != ''"> and r.region_name like concat('%', #{regionName}, '%')</if>
</where>
GROUP BY r.id
</select>resources/mybatis/mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>5.1 密码加密
合作商的密码加密
@Override
public int insertPartner(Partner partner)
{
// 使用SecurityUtil工具类,对密码加密
partner.setPassword(SecurityUtils.encryptPassword(partner.getPassword()));
partner.setCreateTime(DateUtils.getNowDate());
return partnerMapper.insertPartner(partner);
}5.2 映射关系
来重温下映射关系
associationproperty:对应 NodeVo 的属性javaType:返回的实体类column:关键字(使用id去查询)
<resultMap type="NodeVo" id="NodeVoResult">
<result property="id" column="id"/>
<result property="nodeName" column="node_name"/>
<result property="address" column="address"/>
<result property="businessType" column="business_type"/>
<result property="regionId" column="region_id"/>
<result property="partnerId" column="partner_id"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="remark" column="remark"/>
<result property="vmCount" column="vm_count"/>
<association property="region" javaType="Region" column="region_id"
select="com.dkd.manage.mapper.RegionMapper.selectRegionById"/>
<association property="partner" javaType="Partner" column="partner_id"
select="com.dkd.manage.mapper.PartnerMapper.selectPartnerById"/>
</resultMap>
<select id="selectNodeVoList" resultMap="NodeVoResult">
SELECT
n.id,
n.node_name,
n.address,
n.business_type,
n.region_id,
n.partner_id,
n.create_time,
n.update_time,
n.create_by,
n.update_by,
n.remark,
COUNT(v.id) AS vm_count
FROM
tb_node n
LEFT JOIN
tb_vending_machine v ON n.id = v.node_id
<where>
<if test="nodeName != null and nodeName != ''">and n.node_name like concat('%', #{nodeName}, '%')</if>
<if test="regionId != null ">and n.region_id = #{regionId}</if>
<if test="partnerId != null ">and n.partner_id = #{partnerId}</if>
</where>
GROUP BY
n.id
</select>