IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 美年旅游_套餐管理_新增套餐 -> 正文阅读

[Java知识库]美年旅游_套餐管理_新增套餐

需求分析

2:前台代码

(1)弹出新增窗口
(2)动态展示跟团游列表
(3)图片上传并预览
? 使用七牛云存储图片
(4)提交请求
? 使用数据库存储图片名称
? 使用springmvc的文件上传技术

3:后台代码

业务:
? 新增套餐
(1)SetmealController.java(Controller)
(2)SetmealService.java(服务接口)
(3)SetmealServiceImpl.java(服务实现类)
(4)SetmealDao.java(Dao接口)
(5)SetmealDao.xml(Mapper映射文件)
4:完善文件上传,Redis存储图片名称(一会说)

创建表

DROP TABLE IF EXISTS `t_setmeal`;
CREATE TABLE `t_setmeal` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(1000) DEFAULT NULL,
  `code` varchar(8) DEFAULT NULL,
  `helpCode` varchar(16) DEFAULT NULL,
  `sex` char(1) DEFAULT NULL,
  `age` varchar(32) DEFAULT NULL,
  `price` float DEFAULT NULL,
  `remark` varchar(3000) DEFAULT NULL,
  `attention` varchar(128) DEFAULT NULL,
  `img` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `t_setmeal_travelgroup`;
CREATE TABLE `t_setmeal_travelgroup` (
  `setmeal_id` int(11) NOT NULL DEFAULT '0',
  `travelgroup_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`setmeal_id`,`travelgroup_id`),
  KEY `travelgroup_key` (`travelgroup_id`),
  CONSTRAINT `travelgroup_key` FOREIGN KEY (`travelgroup_id`) REFERENCES `t_travelgroup` (`id`),
  CONSTRAINT `setmeal_key` FOREIGN KEY (`setmeal_id`) REFERENCES `t_setmeal` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

需求分析

套餐其实就是跟团游的集合,例如有一个套餐为“北京深圳双飞套餐”,这个套餐可以包括多个跟团游。
所以在添加套餐时需要选择这个套餐包括的跟团游。
套餐对应的实体类为Setmeal,

public class Setmeal implements Serializable {
    private Integer id;//套餐ID
    private String name;//套餐名称
    private String code;//编号
    private String helpCode;//助记码
    private String sex;//套餐适用性别:0不限 1男 2女
    private String age;//套餐适用年龄
    private Float price;//套餐价格
    private String remark;//备注
    private String attention;//注意事项
    private String img;//套餐对应图片存储路径(用于存放七牛云上的图片名称)
    private List<TravelGroup> travelGroups;//体检套餐对应的跟团游,多对多关系
}

其中img字段表示套餐对应图片存储路径(用于存放七牛云上的图片名称)
对应的数据表为 t_setmeal。套餐和跟团游为多对多关系,所以需要中间表 t_setmeal_travelgroup 进行关联。

前台代码

套餐管理页面对应的是 setmeal.html 页面,根据产品设计的原型已经完成了页面基本结构的编写,现在需要完善页面动态效果

弹出新增窗口

页面中已经提供了新增窗口,只是出于隐藏状态。只需要将控制展示状态的属性 dialogFormVisible 改为true接口显示出新增窗口。点击新建按钮时绑定的方法为 handleCreate ,所以在 handleCreate 方法中修改dialogFormVisible 属性的值为true即可。同时为了增加用户体验度,需要每次点击新建按钮时清空表单输入项。
由于新增套餐时还需要选择此套餐包含的跟团游,所以新增套餐窗口分为两部分信息:基本信息和跟团游信息,如下图:

(1):新建按钮绑定单击事件,对应的处理函数为handleCreate

<el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>

(2):handleCreate()方法:

// 重置表单
resetForm() {
    // 清空套餐基本信息
    this.formData = {};
    // 选项卡设置成第一个
    this.activeName='first';
    // 重置跟团游的复选框
    this.travelgroupIds = [];
    // 重置上传的图片路径
    this.imageUrl = null;
},
// 弹出添加窗口
handleCreate() {
    this.dialogFormVisible = true;
    this.resetForm();
},

动态展示跟团游列表

现在虽然已经完成了新增窗口的弹出,但是在跟团游信息标签页中需要动态展示所有的跟团游信息列表数据,并且可以进行勾选。具体操作步骤如下:
(1)定义模型数据

tableData:[],//添加表单窗口中跟团游列表数据
travelgroupIds:[],//添加表单窗口中跟团游复选框对应id

(2)动态展示跟团游列表数据,数据来源于上面定义的tableData模型数据

<el-tab-pane label="跟团游信息" name="second">
<div class="checkScrol">
   <table class="datatable">
      <thead>
      <tr>
         <th>选择</th>
         <th>项目编码</th>
         <th>项目名称</th>
         <th>项目说明</th>
      </tr>
      </thead>
      <tbody>
      <!--循环遍历tableData-->
      <tr v-for="c in tableData">
         <td>
            <!--复选框绑定travelgroupIds,存放到值是id-->
            <input :id="c.id" v-model="travelgroupIds" type="checkbox" :value="c.id">
         </td>
         <td><label :for="c.id">{{c.code}}</label></td>
         <td><label :for="c.id">{{c.name}}</label></td>
         <td><label :for="c.id">{{c.remark}}</label></td>
      </tr>
      </tbody>
   </table>
</div>
</el-tab-pane>

其中:v-model=“travelgroupIds”,用于回显复选框。

(3)完善 handleCreate 方法,发送ajax请求查询所有跟团游数据并将结果赋值给tableData模型数据用于页面表格展示

// 弹出添加窗口
handleCreate() {
    this.dialogFormVisible = true;
    this.resetForm();
    axios.get("/travelgroup/findAll.do").then((res)=> {
        if(res.data.flag){
            this.tableData = res.data.data;
        }else{
            this.$message.error(res.data.message);
        }
    });
},

(4)分别在 TravelGroupController 、TravelGroupService 、TravelGroupServiceImpl 、TravelGroupDao 、TravelGroupDao.xml 中扩展方法查询所有跟团游数据
1:TravelGroupController:

package com.atguigu.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.atguigu.constant.MessageConstant;
import com.atguigu.entity.PageResult;
import com.atguigu.entity.QueryPageBean;
import com.atguigu.entity.Result;
import com.atguigu.pojo.TravelGroup;
import com.atguigu.pojo.TravelItem;
import com.atguigu.service.TravelGroupService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RequestMapping("/travelgroup")
@RestController
public class TravelGroupController {

    @Reference
    private TravelGroupService travelGroupService;

    //查询所有
    @RequestMapping("/findAll")
    public Result findAll(){
        // 查询所有的跟团游
        List<TravelGroup> travelGroupList = travelGroupService.findAll();
        if(travelGroupList != null && travelGroupList.size() > 0){
        //查询成功返回数据
            Result result = new Result(true, MessageConstant.QUERY_SETMEAL_SUCCESS,travelGroupList);
            return result;
        }
        return new Result(false,MessageConstant.QUERY_SETMEAL_FAIL);
    }

2:TravelGroupService:

package com.atguigu.service;

import com.atguigu.entity.PageResult;
import com.atguigu.pojo.TravelGroup;
import com.atguigu.pojo.TravelItem;
import java.util.List;

public interface TravelGroupService {
    List<TravelGroup> findAll();

3:TravelGroupServiceImpl:

package com.atguigu.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.atguigu.dao.TravelGroupDao;
import com.atguigu.entity.PageResult;
import com.atguigu.pojo.TravelGroup;
import com.atguigu.pojo.TravelItem;
import com.atguigu.service.TravelGroupService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = TravelGroupService.class)
@Transactional
public class TravelGroupServiceImpl implements TravelGroupService {

    @Autowired
    private TravelGroupDao travelGroupDao;

    @Override
    public List<TravelGroup> findAll() {
        return travelGroupDao.findAll();
    }

4:TravelGroupDao:

package com.atguigu.dao;

import com.atguigu.pojo.TravelGroup;
import com.atguigu.pojo.TravelItem;
import com.github.pagehelper.Page;
import java.util.List;
import java.util.Map;

public interface TravelGroupDao {
    List<TravelGroup> findAll();

5:TravelGroupDao.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.atguigu.dao.TravelGroupDao">
    <select id="findAll" resultType="travelGroup">
       select * from t_travelgroup
    </select>
</mapper>    

图片上传并预览

此处使用的是ElementUI提供的上传组件el-upload,提供了多种不同的上传效果,上传成功后可以进行预览。
实现步骤:
(1)定义模型数据,用于后面上传文件的图片预览:

imageUrl:null,//模型数据,用于上传图片完成后图片预览

(2)定义上传组件:

<!--
  el-upload:上传组件
  action:上传的提交地址(七牛云服务器)
  auto-upload:选中文件后是否自动上传
  name:上传文件的名称,服务端可以根据名称获得上传的文件对象
  show-file-list:是否显示已上传文件列表
  on-success:文件上传成功时的执行的钩子函数
  before-upload:上传文件之前执行的钩子函数
-->
<el-upload
         class="avatar-uploader"
         action="/setmeal/upload.do"
         :auto-upload="autoUpload"
         name="imgFile"
         :show-file-list="false"
         :on-success="handleAvatarSuccess"
         :before-upload="beforeAvatarUpload">
     <!--用于上传图片预览-->
     <img v-if="imageUrl" :src="imageUrl" class="avatar">
     <!--用于展示上传图标-->
     <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

(3)定义对应的钩子函数:

// 注意axios执行url的时候,响应是通过response.data实现
// 注意elementUI执行url的时候,响应是通过response实现
//文件上传成功后的钩子,response为服务端返回的值,file为当前上传的文件封装成的js对象
handleAvatarSuccess(response, file) {
    // 对imageUrl赋值,将图片显示到文件上传的框中,进行浏览
    this.imageUrl = "http://q2t6dfukt.bkt.clouddn.com/"+response.data; // 用于显示
    this.$message({
         message: response.message,
         type: response.flag ? 'success' : 'error'
    });
    //设置模型数据(图片名称),后续提交ajax请求时会提交到后台最终保存到数据库
    this.formData.img = response.data; // 用于保存
},
//上传图片之前执行,const声明常量;var声明变量
beforeAvatarUpload(file) {
    const isJPG = file.type === 'image/jpeg';
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isJPG) {
        this.$message.error('上传套餐图片只能是 JPG 格式!');
    }
    if (!isLt2M) {
        this.$message.error('上传套餐图片大小不能超过 2MB!');
    }
    return isJPG && isLt2M;
},

(4)创建SetmealController,接收上传的文件

package com.atguigu.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.atguigu.constant.MessageConstant;
import com.atguigu.entity.Result;
import com.atguigu.service.SetmealService;
import com.atguigu.utils.QiniuUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;

@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Reference
private SetmealService setmealService;

    // imgFile:需要跟页面el-upload里面的name保持一致
    @RequestMapping("/upload")
    //name="imgFile"是在el-upload标签中的imgFile 也可以用
    public Result upload(MultipartFile imgFile) {
        try {
            //获取原始文件名
            String originalFilename = imgFile.getOriginalFilename();
            // 找到.最后出现的位置
            int lastIndexOf = originalFilename.lastIndexOf(".");
            //获取文件后缀
            String suffix = originalFilename.substring(lastIndexOf);
            //使用UUID随机产生文件名称,防止同名文件覆盖
            String fileName = UUID.randomUUID().toString() + suffix;
            QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName);
            //图片上传成功 传回fileName用于回显那个图片上传成功
            Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS, fileName);
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Result(false,MessageConstant.PIC_UPLOAD_FAIL);
    }
}

!!!注意 :报错找不到http://localhost:82/setmeal/upload可能是 七牛的三个属性账号 密码 文件夹配置错了

 String accessKey = "9_AiA8.....";
        String secretKey = "Sem9.....";
        String bucket = "shengdameinian";

注意:别忘了在spring配置文件中配置文件上传组件
已在springmvc.xml中配置

<!--文件上传组件-->
<bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="104857600" /><!--最大上传文件大小-->
    <property name="maxInMemorySize" value="4096" />
    <property name="defaultEncoding" value="UTF-8"/>
</bean>

错误
在这里插入图片描述
解决方案

// Zone.zone2():表示华南,设置对应的地区 
Configuration cfg = new Configuration(Zone.zone2());

提交请求

当用户点击新增窗口中的确定按钮时发送 ajax请求将数据提交到后台进行数据库操作。提交到后台的数据分为两部分:套餐基本信息(对应的模型数据为 formData)和跟团游 id数组(对应的模型数据为travelgroupIds)。
(1)为确定按钮绑定单击事件,对应的处理函数为handleAdd

<div slot="footer" class="dialog-footer">
    <el-button @click="dialogFormVisible = false">取消</el-button>
    <el-button type="primary" @click="handleAdd()">确定</el-button>
</div>

(2)完善handleAdd方法

//添加
handleAdd () {
    axios.post("/setmeal/add.do?travelgroupIds=" + this.travelgroupIds,this.formData).then((response)=> {
        this.dialogFormVisible = false;
        if(response.data.flag){
            this.$message({
                message: response.data.message,
                type: 'success'
            });
        }else{
            this.$message.error(response.data.message);
        }
    }).finally(()=> {
        this.findPage();
    });
},

后台代码

Controller

在SetmealController中增加方法

package com.atguigu.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.atguigu.constant.MessageConstant;
import com.atguigu.entity.Result;
import com.atguigu.pojo.Setmeal;
import com.atguigu.service.SetmealService;
import com.atguigu.utils.QiniuUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;

@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Reference
    private SetmealService setmealService;

    //新增
    @RequestMapping("/add")
    public Result add(@RequestBody Setmeal setmeal, Integer[] travelgroupIds){
       try {
           setmealService.add(setmeal,travelgroupIds);
       }catch (Exception e){
           //新增套餐失败
           return new Result(false,MessageConstant.ADD_SETMEAL_FAIL);
       }
       //新增套餐成功
       return new Result(true,MessageConstant.ADD_SETMEAL_SUCCESS);
    }

服务接口

创建 SetmealService 接口并提供新增方法

package com.atguigu.service;

import com.atguigu.pojo.Setmeal;

public interface SetmealService {
    public void add(Setmeal setmeal, Integer[] travelgroupIds);
}

服务实现类

创建 SetmealServiceImpl 服务实现类并实现新增方法

package com.atguigu.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.atguigu.dao.SetmealDao;
import com.atguigu.pojo.Setmeal;
import com.atguigu.service.SetmealService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.Map;

@Service(interfaceClass = SetmealService.class)
@Transactional
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealDao setmealDao;

    @Override
    public void add(Setmeal setmeal,Integer[] travelgroupId) {
        // 新增套餐
        setmealDao.add(setmeal);
        // 2:向套餐和跟团游的中间表中插入数据
        if(travelgroupId != null && travelgroupId.length > 0){
            //绑定套餐和跟团游的多对多关系
            setSetmealAndTravelGroup(setmeal.getId(),travelgroupId);
        }
    }
    //绑定套餐和跟团游的多对多关系
     private void setSetmealAndTravelGroup(Integer id, Integer[] travelgroupId) {
       
        //一个套餐id 对应多个跟团游
        for (Integer checkgroupId  : travelgroupIds) {
            //用map每次都存入 套餐id 和 其中一个对应的跟团游id
            Map<String,Integer> map = new HashMap<>();
            map.put("checkgroup_id",checkgroupId);
            map.put("setmeal_id",id);
            //传入map里有刚刚put的对应关系
            setmealDao.setSetmealAndTravelGroup(map);

        }
    }
}

Dao接口

创建 SetmealDao 接口并提供相关方法

package com.atguigu.dao;

import com.atguigu.pojo.Setmeal;
import java.util.Map;

public interface SetmealDao {
    void add(Setmeal setmeal);
    void setSetmealAndTravelGroup(Map<String, Integer> map);
}

Mapper映射文件

创建 SetmealDao.xml 文件并定义相关SQL语句

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.atguigu.dao.SetmealDao">

    <!--新增-->
    <insert id="add" parameterType="setmeal">
        <selectKey resultType="int" order="AFTER" keyProperty="id">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into t_setmeal(name,code,helpCode,sex,age,price,remark,attention,img) values (#{name},#{code},#{helpCode},#{sex},#{age},#{price},#{remark},#{attention},#{img})
    </insert>

    <!--绑定套餐和跟团游多对多关系-->
     <insert id="setSetmealAndTravelGroup" parameterType="map">
        insert into t_setmeal_travelgroup(setmeal_id,travelgroup_id) values (#{setmeal_id},#{travelgroup_id})
    </insert>

</mapper>

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章           查看所有文章
加:2021-11-26 08:43:52  更:2021-11-26 08:46:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:48:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码