目录

代码随记 SpringBoot Ruoyi 01

因本人已有Ruoyi基础,因此本笔记只是跟着黑马的教程重新过一次Ruoyi,梳理下知识点。

  • 基本信息 实体类名称改成 TbCourse--->Course 一般不需要前面。

  • 字段信息 id:因为是自增的,所以不需要勾选 create_timeupdate_time 因为我们是数据库自动填充的,因此不需要勾选

编辑一般跟插入保持一致

列表:有哪些字段需要显示出来 查询:有哪些是可以查询的

  • 生成信息

第一步先在数据库中执行SQL,然后复制对应文件,直接复制就可以了!

定时任务必须放在 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());  
    }  
}

添加模块三步走

  • 第一步:添加模块 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是自增的所以去掉、创建和更新时间之后是自动填充的。
    • 编辑:和插入保持一致
    • 列表:不需要展示描述信息
    • 查询:只需要根据 namestatus 查询
    • 需要添加 售卖状态 dish_status 的字典。
  • 接下来要配置主子表
    • 主要看关联信息,其实很简单

  • 子表 tb_dish_flavor
    • 只需要修改基本信息的实体类名称就可以了

接下来直接下载代码,覆盖即可使用

  • 需要说明下 handleUpdatesubmitForm,因为 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);
  });
  ...
}

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>

合作商的密码加密

@Override
public int insertPartner(Partner partner)
{
    // 使用SecurityUtil工具类,对密码加密
    partner.setPassword(SecurityUtils.encryptPassword(partner.getPassword()));
    partner.setCreateTime(DateUtils.getNowDate());
    return partnerMapper.insertPartner(partner);
}

来重温下映射关系

  • association
    • property:对应 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>