2.点位管理|前后端如何交互——帝可得后台管理系统

目录

前言

提示:本篇介绍点位管理模块,需求分析------建表设计------前后端代码生成------代码优化


点位管理菜单模块

1.需求说明

  • 业务场景: 首先,我们需要确定几个有潜力的区域,这些区域可能是人流量大、消费能力高的商业区或居民区。然后,我们要与这些区域内的潜在合作商进行洽谈,比如商场、写字楼、学校等地方的管理者或所有者。一旦我们与合作商达成协议,确定了合作的细节和点位,我们就可以安排工作人员去投放智能售货机了。这些点位将成为我们智能售货机的"家",为消费者提供便捷的购买服务。

  • 分析设计模块和业务流程:

点位管理主要涉及到三个功能模块,业务流程如下:

  1. 登录系统:后台管理人员登录后台系统
  2. 新增区域: 后台管理人员可以添加区域范围,区域范围与运维/运维人员挂钩,区域下可关联点位。
  3. 新增合作商: 管理人员可以添加合作商,合作商与点位进行关联。
  4. 新增区域点位 : 后台管理人员可以在特定区域内新增点位,这些点位是放置智能售货机的具体位置。

2.库表设计

表的设计涉及到页面原型,根据页面原型设计表结构;

完整的页面原型如下:页面原型,下图中只是截取了重要的而部分;

  • 区域管理页面原型:
  • 点位管理页面原型:
  • 合作商管理页面原型:
  • 根据上图进行分析:得到三个表;
bash 复制代码
1,区域表:字段有主键id、区域名称
2,合作商表:字段有主键id、合作商名称、联系人、联系电话、分成比例(int类型)、账号、密码
3,点位表:字段有主键id、点位名称、详细地址、商圈类型(int类型)
  • 根据表信息,使用AI进行表结构创建,提示词如下:
bash 复制代码
你是一位软件工程师,帮我生成MySQL的表结构
需求如下:
1,区域表,表名tb_region,字段有主键id、区域名称
2,合作商表,表名tb_partner,字段有主键id、合作商名称、联系人、联系电话、分成比例(int类型)、账号、密码
3,点位表,表名tb_node,字段有主键id、点位名称、详细地址、商圈类型(int类型)
其他要求:
1,每张表中都有创建时间(create_time)、修改时间(date_time)、创建人(create_by)、修改人(update_by)、备注(remark)这些字段
2,每张表的主键都是自增的
3,区域与点位是一对多的关系,合作商与点位是一对多的关系,请用字段表示出来,并建立外键约束
4,请为所有字段都添加上comment
5,帮我给生成的表中插入一些北京城市相关区域、点位、合作商的测试数据```
  • 生成内容 如下:
sql 复制代码
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);

3.生成基础代码

0 .使用若依代码生成器最终目标

1.创建点位管理

2.添加数据字典

先创建商圈的字典类型

再创建商圈的字典数据

3.配置代码生成信息

导入三张表

配置合作商表(参考原型)

配置区域表(参考原型)

配置点位表(参考原型)

4.下载代码并导入项目

选中三张表生成下载

解压ruoyi.zip得到前后端代码和动态菜单sql

代码导入

调整二级菜单显示顺序

4.优化菜单------点位管理

1.优化区域管理

修改主键id,删除操图案;

优化后:

2.增加点位数

  • 前端修改

  • 后端修改

  1. Mysql语句创建:
sql 复制代码
-- 传统模式
-- 1.先聚合统计每个区域下的点位数
-- 确定查询表 tb_node
-- 确定分组字段 region_id
select region_id,count(*) as node_count from tb_node group by region_id;
-- 2.然后与区域表进行关联查询
select r.id,r.region_name,r.remark,ifnull(n.node_count,0) as node_count from tb_region r
    left join (select region_id,count(*) as node_count from tb_node group by region_id) n on r.id=n.region_id;

-- AI辅助编程模式
-- 查询区域表所有的信息,需要显示每个区域的点位数
SELECT r.*, COUNT(n.id) AS node_count FROM tb_region r LEFT JOIN tb_node n ON r.id = n.region_id GROUP BY r.id;
  1. 创建实体类

  2. 创建RegionMapper以及RegionMapper.xml

java 复制代码
/**
 * 查询区域管理列表
 * @param region
 * @return RegionVo集合
 */
public List<RegionVo> selectRegionVoList(Region region);
java 复制代码
<select id="selectRegionVoList" resultType="com.dkd.manage.domain.vo.RegionVo">

	select r.id,r.region_name,r.remark,ifnull(n.node_count,0) as node_count from tb_region r
    left join (select region_id,count(*) as node_count from tb_node group by region_id) n on r.id=n.region_id
    
   		 <where>
	      	 <if test="regionName != null  and regionName != ''"> and r.region_name like concat('%', #{regionName}, '%')</if>
   		 </where>

</select>
  1. 修改IRegionService接口以及实现类
java 复制代码
/**
 * 查询区域管理列表
 * @param region
 * @return RegionVo集合
 */
public List<RegionVo> selectRegionVoList(Region region);
java 复制代码
/**
 * 查询区域管理列表
 * @param region
 * @return RegionVo集合
 */
@Override
public List<RegionVo> selectRegionVoList(Region region) {
    return regionMapper.selectRegionVoList(region);
}
  1. 修改RegionControlller类
java 复制代码
/**
 * 查询区域管理列表
 */
@PreAuthorize("@ss.hasPermi('manage:region:list')")
@GetMapping("/list")
public TableDataInfo list(Region region)
{
    startPage();
    List<RegionVo> voList = regionService.selectRegionVoList(region);
    return getDataTable(voList);
}

3. 合作商

  1. 调整字段顺序

  2. 分成比例展示为百分之形式

  3. 删除 操作中修改/删改前的图标

    1-3 操作如下图

  4. 新增时不展示明文密码

  5. 修改时显示创建时间字段

  6. 新增和删除时展示界面不同

    4-6操作如下图

  7. 数据库种的密码展示应为加密类型

    最终效果如下图:id=5 密码不展示明文

4.区域管理中添加查看详情功能

修改src\views\manage\partner\index.vue文件:

css 复制代码
         <el-button link type="primary" @click="getPartnerInfo(scope.row)"
            v-hasPermi="['manage:partner:query']">查看详情</el-button>
    <!-- 查看合作商详情 -->
    <el-dialog title="合作商详情" v-model="partnerInfoOpen" width="600px" append-to-body center>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="合作商名称">
          {{ form.partnerName }}
        </el-descriptions-item>
        <el-descriptions-item label="账号">
          {{ form.account }}
        </el-descriptions-item>
       
        <el-descriptions-item label="联系人">
          {{ form.contactPerson }}
        </el-descriptions-item>
        <el-descriptions-item label="联系电话">
          {{ form.contactPhone }}
        </el-descriptions-item>
        <el-descriptions-item label="分成比例">
          <el-tag type="success">{{ form.profitRatio }}%</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="创建时间">
          {{ form.createTime }}
        </el-descriptions-item>
      
        </el-descriptions>
    </el-dialog>
javascript 复制代码
/* 查看合作商详情 */
const partnerInfoOpen = ref(false);
function getPartnerInfo(row) {
  reset();
  const _id = row.id;
  getPartner(_id).then(response => {
    form.value = response.data;
    partnerInfoOpen.value = true;
  });
}

最终效果:

5.合作商添加点位数量

  1. MySQL语句分析
java 复制代码
-- AI辅助编程模式
-- 你是一个软件开发工程师,现在要根据数据库的sql脚本,查询并显示合作商表所有的字段信息,同时显示每个合作商的点位数,sql脚本如下
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                                 null comment '商圈类型',
    region_id     int                                 null comment '区域ID',
    partner_id    int                                 null comment '合作商ID',
    create_time   timestamp default CURRENT_TIMESTAMP null comment '创建时间',
    update_time   timestamp default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '修改时间',
    create_by     varchar(64)                         null comment '创建人',
    update_by     varchar(64)                         null comment '修改人',
    remark        text                                null comment '备注',
    constraint tb_node_ibfk_1
        foreign key (region_id) references tb_region (id)
            on update cascade on delete cascade,
    constraint tb_node_ibfk_2
        foreign key (partner_id) references tb_partner (id)
            on update cascade on delete cascade
)
    comment '点位表';
    
create table tb_partner
(
    id             int auto_increment comment '主键id'
        primary key,
    partner_name   varchar(255)                        not null comment '合作商名称',
    contact_person varchar(64)                         null comment '联系人',
    contact_phone  varchar(15)                         null comment '联系电话',
    profit_ratio   int                                 null comment '分成比例',
    account        varchar(64)                         null comment '账号',
    password       varchar(64)                         null comment '密码',
    create_time    timestamp default CURRENT_TIMESTAMP null comment '创建时间',
    update_time    timestamp default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '修改时间',
    create_by      varchar(64)                         null comment '创建人',
    update_by      varchar(64)                         null comment '修改人',
    remark         text                                null comment '备注'
)
    comment '合作商表';
  1. domain层
java 复制代码
package com.dkd.manage.domain.vo;

import com.dkd.manage.domain.Partner;
import lombok.Data;

@Data
public class PartnerVo extends Partner {
    //点位数量
    private Integer nodeCount;
}
  1. mapper层
java 复制代码
  /**
     * 查询合作商管理列表
     * @param partner
     * @return partnerVo集合
     */
    public List<PartnerVo> selectPartnerVoList(Partner partner);
java 复制代码
    <select id="selectPartnerVoList" resultType="com.dkd.manage.domain.vo.PartnerVo"
            parameterType="Partner">
        SELECT
            p.id,
            p.partner_name,
            p.contact_person,
            p.contact_phone,
            p.profit_ratio,
            p.account,
            COUNT(n.id) AS node_count
        FROM
            tb_partner p
        LEFT JOIN
            tb_node n ON p.id = n.partner_id
        <where>
            <if test="partnerName != null  and partnerName != ''">
                             and p.partner_name like concat('%', #{partnerName}, '%')</if>
        </where>
        GROUP BY
            p.id
    </select>
  1. service层
    IPartnerService
java 复制代码
  /**
     * 查询合作商列表
     *
     * @param partner 合作商
     * @return 合作商
     */
    public List<PartnerVo> selectPartnerVoList(Partner partner);

PartnerServiceImpl

java 复制代码
    /**
     * 查询合作商列表
     *
     * @param partner 合作商
     * @return 合作商
     */
    @Override
    public List<PartnerVo> selectPartnerVoList(Partner partner)
    {
        return partnerMapper.selectPartnerVoList(partner);
    }
  1. controller层

修改PartnerController

java 复制代码
    /**
     * 查询合作商列表
     */
    @PreAuthorize("@ss.hasPermi('manage:partner:list')")
    @GetMapping("/list")
    public TableDataInfo list(Partner partner)
    {
        startPage();
        List<PartnerVo> listVo = partnerService.selectPartnerVoList(partner);
        return getDataTable(listVo);
    }
  1. 最终效果:

6.重置合作商密码

  1. 查看API文档

    请求路径: /manage/partner/resetPwd/:id

  2. 编写controller

powershell 复制代码
    /*
     * 重置合作商密码
     * /manage/partner/resetPwd/:id
     * */
    @PreAuthorize("@ss.hasPermi('manage:partner:edit')")
    @Log(title = "重置合作商密码", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd/{id}")
    public AjaxResult resetpwd(@PathVariable Long id) {//1. 接收参数
        //2. 创建合作商对象
        Partner partner = new Partner();
        partner.setId(id);// 设置id
        partner.setPassword(SecurityUtils.encryptPassword("123456"));// 设置加密后的初始密码
        //3. 调用service更新密码
        return toAjax(partnerService.updatePartner(partner));
    }
  1. 修改前端
    在partner/index.vue视图组件中
html 复制代码
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="300px">
    <template #default="scope">
        <el-button link type="primary" @click="resetPwd(scope.row)" v-hasPermi="['manage:partner:edit']">重置密码</el-button>

    </template>

</el-table-column>

<script>
    import { listPartner, getPartner, delPartner, addPartner, updatePartner,resetPartnerPwd } from "@/api/manage/partner";
    /* 重置合作商密码 */
    function resetPwd(row) {
        proxy.$modal.confirm('你确定要重置该合作商密码吗?').then(function () {
            return resetPartnerPwd(row.id);
        }).then(() => {
            proxy.$modal.msgSuccess("重置成功");
        }).catch(() => { });
    }
</script>

在manage/partner.js请求api中

javascript 复制代码
// 重置合作商密码
export function resetPartnerPwd(id){
  return request({
    url: '/manage/partner/resetPwd/' + id,
    method: 'put'
  })
}

整体执行流程:

  • 当用户点击重置密码时,会触发@click="resetPwd(scope.row)"函数;
  • 该代码会弹出窗口,你是否重置合作商密码;
  • 后端向前端的响应为:{"msg":"操作成功","code":200}
  • 无论响应结果如何(不管code是200|500),都会接着执行then后的 proxy.$modal.msgSuccess("重置成功");
powershell 复制代码
   /* 重置合作商密码 */
    function resetPwd(row) {
        proxy.$modal.confirm('你确定要重置该合作商密码吗?').then(function () {
            return resetPartnerPwd(row.id);
        }).then(() => {
            proxy.$modal.msgSuccess("重置成功");
        }).catch(() => { });
    }
</script>
javascript 复制代码
// 重置合作商密码
export function resetPartnerPwd(id){
  return request({
    url: '/manage/partner/resetPwd/' + id,
    method: 'put'
  })
}

7. 补充后端和前端是如何交互的?

我们以修改合作商为例:

当前端点击重置密码时,请求地址是:http://localhost/dev-api/manage/partner/resetPwd/1

在前端.env.development中,有如下代码:

javascript 复制代码
  // vite 相关配置
    server: {
      port: 80,
      host: true,
      open: true,
      proxy: {
        // https://cn.vitejs.dev/config/#server-proxy
        '/dev-api': {
          target: 'http://127.0.0.1:8080',
          // target: 'https://api.wzs.pub/mock/13',
          changeOrigin: true,
          rewrite: (p) => p.replace(/^\/dev-api/, '')
        }
      }
    },

该代码的意思是将 http://localhost/dev-api/ 替换为 空字符串

并将其转发到 **http://127.0.0.1:8080/manage/partner/resetPwd/{id}**;

那么后端是如何知道自己该调用那个方法去修改密码呢?

在后端application.yml中,有如下代码:

powershell 复制代码
# 开发环境配置
server:
  # 服务器的HTTP端口,默认为 8080
  port: 8080
  servlet:
    # 应用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # 连接数满后的排队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100

该段代码确定了Spring的配置环境,配置的环境就是前端提到的 http://127.0.0.1:8080

在PartnerController.java文件中

在 Spring Boot 的控制器类上会有一个类级别的 @RequestMapping 注解/manage/partner,然后在具体的方法上,会有方法级别的映射,如你所见的 @PutMapping("/resetPwd/{id}");

最后后端地址就可以拼接为:http://127.0.0.1:8080/manage/partner/resetPwd/{id},也就是前端转发的请求地址;

这个时候后端就知道调用resetPwd()方法;

相关推荐
wellc13 分钟前
SpringBoot集成Flowable
java·spring boot·后端
洛菡夕1 小时前
NoSQL之Redis配置与优化
redis·git·nosql
Hui Baby1 小时前
springAi+MCP三种
java
hsjcjh1 小时前
【MySQL】C# 连接MySQL
java
敖正炀1 小时前
LinkedBlockingDeque详解
java
wangyadong3171 小时前
datagrip 链接mysql 报错
java
untE EADO1 小时前
Tomcat的server.xml配置详解
xml·java·tomcat
ictI CABL1 小时前
Tomcat 乱码问题彻底解决
java·tomcat
敖正炀1 小时前
DelayQueue 详解
java
wohehe1 小时前
Android项目工程化-Github Actions
linux·github