1.项目概述
1.1.项目演示
- 运行 “饿了么项目” ,演示应用程序效果,演示 “点餐业务线” 整体流程。
- 本项目参照 “饿了么官网网页版”制作,演示饿了么官网效果。饿了么网页版:http://h5.ele.me/
本项目专注于完成点餐业务线功能, ”饿了么官网“中的其它功能暂不涉及 。
1.2.项目目标
本项目为课程级贯穿项目中的第三个项目(JDBC项目、前端项目、javaWeb项目)的服务器端升级版。
即数据库结构与前端Vue没有任何变化,而服务器端由Servlet升级为SpringBoot。- 本项目完成后,学员将能够使用VUE+SpringBoot+AJAX技术开发前后端分离的Web应用程序。
1.3.数据库设计
1.3.1.DB一览表
| No | 表名称 | 中文名 | 说明 | | :—- | :—- | :—- | :—- | | 1 | business | 商家表 | 存储所有商家信息 | | 2 | food | 食品表 | 存储每个商家所拥有的所有食品信息 | | 3 | cart | 购物车表 | 存储每个用户的购物车中的食品信息 | | 4 | deliveryaddress | 送货地址表 | 存储每个用户的所有送货地址信息 | | 5 | orders | 订单表 | 存储每个用户的所有订单信息 | | 6 | orderdetailet | 订单明细表 | 存储每个订单中所订购的所有食品信息 | | 7 | user | 用户表 | 存储所有用户信息 |
1.3.2.表结构
约束类型标识: PK:primary key 主键 FK:foreign key 外键 NN:not null 非空 UQ:unique 唯一索引 AI:auto increment 自增长列
1.3.2.1.business(商家表)
No | 字段名 | 数据类型 | size | 默认値 | 约束 | 说明 |
---|---|---|---|---|---|---|
1 | businessId | int | PK、AI、NN | 商家编号 | ||
2 | businessName | varchar | 40 | NN | 商家名称 | |
3 | businessAddress | varchar | 50 | 商家地址 | ||
4 | businessExplain | varchar | 40 | 商家介绍 | ||
5 | businessImg | mediumtext | NN | 商家图片 | ||
6 | orderTypeId | int | NN | 点餐分类: 1:美食、2:早餐、3:跑腿代购、4:汉堡披萨、5:甜品饮品、6:速食简餐、7:地方小吃、8:米粉面馆、9:包子粥铺、10:炸鸡炸串 | ||
7 | starPrice | decimal | (5,2) | 0.00 | 起送费 | |
8 | deliveryPrice | decimal | (5,2) | 0.00 | 配送费 | |
9 | remarks | varchar | 40 | 备注 |
1.3.2.2.food(食品表)
No | 字段名 | 数据类型 | size | 默认値 | 约束 | 说明 |
---|---|---|---|---|---|---|
1 | foodId | int | PK、AI、NN | 食品编号 | ||
2 | foodName | varchar | 30 | NN | 食品名称 | |
3 | foodExplain | varchar | 30 | NN | 食品介绍 | |
4 | foodImg | mediumtext | NN | 食品图片 | ||
5 | foodPrice | decimal | (5,2) | NN | 食品价格 | |
6 | businessId | int | FK、NN | 所属商家编号 | ||
7 | remarks | varchar | 40 | 备注 |
1.3.2.3.cart(购物车表)
No | 字段名 | 数据类型 | size | 默认値 | 约束 | 说明 |
---|---|---|---|---|---|---|
1 | cartId | int | PK、AI、NN | 无意义编号 | ||
2 | foodId | int | FK、NN | 食品编号 | ||
3 | businessId | int | FK、NN | 所属商家编号 | ||
4 | userId | varchar | 20 | FK、NN | 所属用户编号 | |
5 | quantity | int | NN | 同一类型食品的购买数量 |
1.3.2.4.deliveryaddress(送货地址表)
No | 字段名 | 数据类型 | size | 默认値 | 约束 | 说明 |
---|---|---|---|---|---|---|
1 | daId | int | PK、AI、NN | 送货地址编号 | ||
2 | contactName | varchar | 20 | NN | 联系人姓名 | |
3 | contactSex | int | NN | 联系人性别 | ||
4 | contactTel | varchar | 20 | NN | 联系人电话 | |
5 | address | varchar | 100 | NN | 送货地址 | |
6 | userId | varchar | 20 | FK、NN | 所属用户编号 |
1.3.2.5.orders(订单表)
No | 字段名 | 数据类型 | size | 默认値 | 约束 | 说明 |
---|---|---|---|---|---|---|
1 | orderId | int | PK、AI、NN | 订单编号 | ||
2 | userId | varchar | 20 | FK、NN | 所属用户编号 | |
3 | businessId | int | FK、NN | 所属商家编号 | ||
4 | orderDate | varchar | 20 | NN | 订购日期 | |
5 | orderTotal | decimal | (7,2) | 0.00 | NN | 订单总价 |
6 | daId | int | FK、NN | 所属送货地址编号 | ||
7 | orderState | int | 0 | NN | 订单状态(0:未支付; 1:已支付) |
1.3.2.6.orderdetailet(订单明细表)
No | 字段名 | 数据类型 | size | 默认値 | 约束 | 说明 |
---|---|---|---|---|---|---|
1 | odId | int | PK、AI、NN | 订单明细编号 | ||
2 | orderId | int | FK、NN | 所属订单编号 | ||
3 | foodId | int | FK、NN | 所属食品编号 | ||
4 | quantity | int | NN | 数量 |
1.3.2.7.user(用户表)
No | 字段名 | 数据类型 | size | 默认値 | 约束 | 说明 |
---|---|---|---|---|---|---|
1 | userId | varchar | 20 | PK、NN | 用户编号 | |
2 | password | varchar | 20 | NN | 密码 | |
3 | userName | varchar | 20 | NN | 用户名称 | |
4 | userSex | int | 1 | NN | 用户性别(1:男; 0:女) | |
5 | userImg | mediumtext | 用户头像 | |||
6 | delTag | int | 1 | NN | 删除标记(1:正常; 0:删除) |
1.4.业务流程
2.服务器端项目搭建
2.1.开发环境检查
- 开发工具:SpringToolSuite(STS)
- 检查开发工具的jdk配置:jdk8
- 检查maven构建工具的配置:maven3
-
2.2.搭建springboot工程总体架构
2.2.1.工程类型
2.2.2.pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.neusoft</groupId>
<artifactId>elmboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>elmboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2.3.工程目录结构
2.2.4.SpringBoot入口文件
package com.neusoft.elmboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ElmbootApplication { public static void main(String[] args) { SpringApplication.run(ElmbootApplication.class, args); } }
2.2.5.处理跨域的Cors配置文件
package com.neusoft.elmboot; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:8081") .allowCredentials(true) .allowedMethods("GET", "POST", "DELETE", "PUT","PATCH") .allowedHeaders("*") .maxAge(36000); } }; } }
2.2.6.application.properties配置文件
server.port=8080 server.servlet.context-path=/elm logging.level.org.springframework=debug logging.level.com.neusoft.elmboot.mapper=debug spring.datasource.username=root spring.datasource.password=123 spring.datasource.url=jdbc:mysql://localhost:3306/elm?characterEncoding=utf-8 spring.datasource.driver-class-name=com.mysql.jdbc.Driver mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.neusoft.elmboot.po
2.3.服务器接口API
2.3.1.business
BusinessController/listBusinessByOrderTypeId 参数:orderTypeId 返回值:business数组 功能:根据点餐分类编号查询所属商家信息
BusinessController/getBusinessById 参数:businessId 返回值:business对象 功能:根据商家编号查询商家信息
2.3.2.food
FoodController/listFoodByBusinessId 参数:businessId 返回值:food数组 功能:根据商家编号查询所属食品信息
2.3.3.cart
CartController/listCart 参数:userId、businessId(可选) 返回值:cart数组(多对一:所属商家信息、所属食品信息) 功能:根据用户编号查询此用户所有购物车信息 根据用户编号和商家编号,查询此用户购物车中某个商家的所有购物车信息
- CartController/saveCart 参数:userId、businessId、foodId 返回值:int(影响的行数) 功能:向购物车表中添加一条记录
- CartController/updateCart 参数:userId、businessId、foodId、quantity 返回值:int(影响的行数) 功能:根据用户编号、商家编号、食品编号更新数量
CartController/removeCart 参数:userId、businessId、foodId(可选) 返回值:int(影响的行数) 功能:根据用户编号、商家编号、食品编号删除购物车表中的一条食品记录 根据用户编号、商家编号删除购物车表中的多条条记录
2.3.4.deliveryAddress
DeliveryAddressController/listDeliveryAddressByUserId 参数:userId 返回值:deliveryAddress数组 功能:根据用户编号查询所属送货地址
- DeliveryAddressController/getDeliveryAddressById 参数:daId 返回值:deliveryAddress对象 功能:根据送货地址编号查询送货地址
- DeliveryAddressController/saveDeliveryAddress 参数:contactName、contactSex、contactTel、address、userId 返回值:int(影响的行数) 功能:向送货地址表中添加一条记录
- DeliveryAddressController/updateDeliveryAddress 参数:daId、contactName、contactSex、contactTel、address、userId 返回值:int(影响的行数) 功能:根据送货地址编号更新送货地址信息
DeliveryAddressController/removeDeliveryAddress 参数:daId 返回值:int(影响的行数) 功能:根据送货地址编号删除一条记录
2.3.5.orders
OrdersController/createOrders 参数:userId、businessId、daId、orderTotal 返回值:int(订单编号) 功能:根据用户编号、商家编号、订单总金额、送货地址编号向订单表中添加一条记录, 并获取自动生成的订单编号, 然后根据用户编号、商家编号从购物车表中查询所有数据,批量添加到订单明细表中, 然后根据用户编号、商家编号删除购物车表中的数据。
- OrdersController/getOrdersById 参数:orderId 返回值:orders对象(包括多对一:商家信息; 一对多:订单明细信息) 功能:根据订单编号查询订单信息,包括所属商家信息,和此订单的所有订单明细信息
OrdersController/listOrdersByUserId 参数:userId 返回值:orders数组(包括多对一:商家信息; 一对多:订单明细信息) 功能:根据用户编号查询此用户的所有订单信息
2.3.6.user
UserController/getUserByIdByPass 参数:userId、password 返回值:user对象 功能:根据用户编号与密码查询用户信息
- UserController/getUserById 参数:userId 返回值:int(返回行数) 功能:根据用户编号查询用户表返回的行数
UserController/saveUser 参数:userId、password、userName、userSex 返回值:int(影响的行数) 功能:向用户表中添加一条记录
3.前端项目搭建
3.1.开发环境检查
检查cnpm安装环境: 命令行下输入:cnpm -v
- 检查VueCli安装环境:命令行下输入:vue -V (注意:本工程使用VueCli4.0.0以上版本)
附录:
- 安装npm:直接安装node.js (输入 “npm -v” 测试是否安装成功; 输入 node –v 查看node版本)
- 安装cnpm:npm install -g cnpm —registry=https://registry.npm.taobao.org
- 全局安装vuecli:cnpm install -g @vue/cli (或:npm install -g @vue/cli@4.x.x)
- 查看当前安装的vue-cli版本:vue —version 或 vue –V
- 卸载旧版本的vue-cli:cnpm uninstall vue-cli -g
- 查看远程仓库中的版本号:cnpm view @vue/cli versions —json
3.2.搭建VueCli工程总体架构
3.2.1.搭建VueCli模板工程
- 命令行下进入工作空间目录中,输入: vue create elmclient (工程名必须小写)
- 选择预设模板:这里选择“Manually select features”(手动选择特征)
- 模块选取:Babel、Router
- 选择是否使用history 形式的路由:选择:Y
- 将依赖文件放在package.json中:选择:“in package.json”
- 是否将当前选择保存以备下次使用:选择:N
- 进入创建好的工程目录:cd elmclient
- 启动工程:npm run serve
在浏览器中测试:http://localhost:8080
3.2.2.添加其它依赖及配置文件
添加font-awesome与axios依赖: cnpm install font-awesome —save cnpm install axios —save cnpm install qs —save
- 添加图片到src的assets中。
在src目录下添加common.js文件
//获取当前时间(XXXX-XX-XX) export function getCurDate() { var now = new Date(); var year = now.getFullYear(); var month = now.getMonth() + 1; var day = now.getDate(); month = month < 10 ? "0" + month : month; day = day < 10 ? "0" + day : day; return year + "-" + month + "-" + day; } //向sessionStorage中存储一个JSON对象 export function setSessionStorage(keyStr, value) { sessionStorage.setItem(keyStr, JSON.stringify(value)); } //从sessionStorage中获取一个JSON对象(取不到时返回null) export function getSessionStorage(keyStr) { var str = sessionStorage.getItem(keyStr); if (str == '' || str == null || str == 'null' || str == undefined) { return null; } else { return JSON.parse(str); } } //从sessionStorage中移除一个JSON对象 export function removeSessionStorage(keyStr) { sessionStorage.removeItem(keyStr); } //向localStorage中存储一个JSON对象 export function setLocalStorage(keyStr, value) { localStorage.setItem(keyStr, JSON.stringify(value)); } //从localStorage中获取一个JSON对象(取不到时返回null) export function getLocalStorage(keyStr) { var str = localStorage.getItem(keyStr); if (str == '' || str == null || str == 'null' || str == undefined) { return null; } else { return JSON.parse(str); } } //从localStorage中移除一个JSON对象 export function removeLocalStorage(keyStr) { localStorage.removeItem(keyStr); }
在工程根目录下添加vue.config.js文件
module.exports = { devServer: { port: 8081 } }
3.2.3.main.js文件
import Vue from 'vue' import App from './App.vue' import router from './router' import 'font-awesome/css/font-awesome.min.css' import axios from 'axios' import qs from 'qs' import { getCurDate, setSessionStorage, getSessionStorage, removeSessionStorage, setLocalStorage, getLocalStorage, removeLocalStorage } from './common.js' Vue.config.productionTip = false //设置axios的基础url部分 axios.defaults.baseURL = 'http://localhost:8080/elm/'; //将axios挂载到vue实例上,使用时就可以 this.$axios 这样使用了 Vue.prototype.$axios = axios; Vue.prototype.$qs = qs; Vue.prototype.$getCurDate = getCurDate; Vue.prototype.$setSessionStorage = setSessionStorage; Vue.prototype.$getSessionStorage = getSessionStorage; Vue.prototype.$removeSessionStorage = removeSessionStorage; Vue.prototype.$setLocalStorage = setLocalStorage; Vue.prototype.$getLocalStorage = getLocalStorage; Vue.prototype.$removeLocalStorage = removeLocalStorage; router.beforeEach(function(to,from,next){ let user = sessionStorage.getItem('user'); //除了登录、注册、首页、商家列表、商家信息之外,都需要判断是否登录 if(!(to.path=='/'||to.path=='/index'||to.path=='/businessList'||to.path=='/businessInfo'||to.path=='/login'||to.path=='/register')){ if(user==null){ router.push('/login'); location.reload(); } } next(); }); new Vue({ router, render: h => h(App) }).$mount('#app')
3.2.4.App.vue文件
注意:在App.vue文件中,#app的高度也要设置为100%。
<template> <div id="app"> <router-view /> </div> </template> <!-- 这里是共通样式,适用于所有组件,所以不要加scoped --> <style> html,body,div,span,h1,h2,h3,h4,h5,h6,ul,ol,li,p { margin: 0; padding: 0; } html,body,#app { width: 100%; height: 100%; font-family: "微软雅黑"; } ul,ol { list-style: none; } a { text-decoration: none; } </style>
3.2.5.路由index.js文件
import Vue from 'vue' import VueRouter from 'vue-router' import Index from '../views/Index.vue' import BusinessList from '../views/BusinessList.vue' import BusinessInfo from '../views/BusinessInfo.vue' import Login from '../views/Login.vue' import Orders from '../views/Orders.vue' import UserAddress from '../views/UserAddress.vue' import Payment from '../views/Payment.vue' import OrderList from '../views/OrderList.vue' import AddUserAddress from '../views/AddUserAddress.vue' import EditUserAddress from '../views/EditUserAddress.vue' import Register from '../views/Register.vue' Vue.use(VueRouter) const routes = [{ path: '/', name: 'Home', component: Index }, { path: '/index', name: 'Index', component: Index }, { path: '/businessList', name: 'BusinessList', component: BusinessList }, { path: '/businessInfo', name: 'BusinessInfo', component: BusinessInfo }, { path: '/login', name: 'Login', component: Login }, { path: '/orders', name: 'Orders', component: Orders }, { path: '/userAddress', name: 'UserAddress', component: UserAddress }, { path: '/payment', name: 'Payment', component: Payment }, { path: '/orderList', name: 'OrderList', component: OrderList }, { path: '/addUserAddress', name: 'AddUserAddress', component: AddUserAddress }, { path: '/editUserAddress', name: 'EditUserAddress', component: EditUserAddress }, { path: '/register', name: 'Register', component: Register } ] //解决重复路由报异常问题 const originalPush = VueRouter.prototype.push; VueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch(err => err) } const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
4.项目代码
4.1.领域模型(PO)
4.1.1.Business
package com.neusoft.elm.po; public class Business { private Integer businessId; private String businessName; private String businessAddress; private String businessExplain; private String businessImg; private Integer orderTypeId; private double starPrice; //起送费 private double deliveryPrice; //配送费 private String remarks; //get、set ... ... }
4.1.2.Cart
public class Cart { private Integer cartId; private Integer foodId; private Integer businessId; private String userId; private Integer quantity; //多对一:所属食品 private Food food; //多对一:所属商家 private Business business; //get、set ... ... }
4.1.3.DeliveryAddress
public class DeliveryAddress { private Integer daId; private String contactName; private Integer contactSex; private String contactTel; private String address; private String userId; //get、set ... ... }
4.1.4.Food
public class Food { private Integer foodId; private String foodName; private String foodExplain; private String foodImg; private Double foodPrice; private Integer businessId; private String remarks; //get、set ... ... }
4.1.5.OrderDetailet
private Integer odId; private Integer odId; private Integer orderId; private Integer foodId; private Integer quantity; //多对一:所属食品 private Food food; //get、set ... ... }
4.1.6.Orders
public class Orders { private Integer orderId; private String userId; private Integer businessId; private String orderDate; private Double orderTotal; private Integer daId; //送货地址编号 private Integer orderState; //订单状态(0:未支付; 1:已支付) //多对一:所属商家 private Business business; //一对多:订单明细 private List<OrderDetailet> list; //get、set ... ... }
4.1.7.User
public class User { private String userId; private String password; private String userName; private Integer userSex; private String userImg; private Integer delTag; //get、set ... ... }
4.2.服务器端代码
4.2.1.Mapper层代码
4.2.1.1.Business
package com.neusoft.elmboot.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import com.neusoft.elmboot.po.Business; @Mapper public interface BusinessMapper { @Select("select * from business where orderTypeId=#{orderTypeId} order by businessId") public List<Business> listBusinessByOrderTypeId(Integer orderTypeId); @Select("select * from business where businessId=#{businessId}") public Business getBusinessById(Integer businessId); }
4.2.1.2.Cart
package com.neusoft.elmboot.mapper; import java.util.List; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Update; import com.neusoft.elmboot.po.Cart; @Mapper public interface CartMapper { public List<Cart> listCart(Cart cart); @Insert("insert into cart values(null,#{foodId},#{businessId},#{userId},1)") public int saveCart(Cart cart); @Update("update cart set quantity=#{quantity} where foodId=#{foodId} and businessId=#{businessId} and userId=#{userId}") public int updateCart(Cart cart); public int removeCart(Cart cart); }
<?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.neusoft.elmboot.mapper.CartMapper"> <resultMap type="Cart" id="cartResultMap"> <id column="cartId" property="cartId"/> <result column="foodId" property="foodId"/> <result column="businessId" property="businessId"/> <result column="userId" property="userId"/> <result column="quantity" property="quantity"/> <association property="food" javaType="Food" select="com.neusoft.elmboot.mapper.FoodMapper.getFoodById" column="foodId"/> <association property="business" javaType="Business" select="com.neusoft.elmboot.mapper.BusinessMapper.getBusinessById" column="businessId"/> </resultMap> <select id="listCart" parameterType="Cart" resultMap="cartResultMap"> select * from cart <where> userId=#{userId} <if test="businessId!=null and businessId!=''"> and businessId=#{businessId} </if> </where> order by cartId </select> <delete id="removeCart" parameterType="Cart"> delete from cart <where> userId=#{userId} and businessId=#{businessId} <if test="foodId!=null and foodId!=''"> and foodId=#{foodId} </if> </where> </delete> </mapper>
4.2.1.3.DeliveryAddress
package com.neusoft.elmboot.mapper; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import com.neusoft.elmboot.po.DeliveryAddress; @Mapper public interface DeliveryAddressMapper { @Select("select * from deliveryAddress where userId=#{userId} order by daId") public List<DeliveryAddress> listDeliveryAddressByUserId(String userId); @Select("select * from deliveryAddress where daId=#{daId}") public DeliveryAddress getDeliveryAddressById(Integer daId); @Insert("insert into deliveryAddress values(null,#{contactName},#{contactSex},#{contactTel},#{address},#{userId})") public int saveDeliveryAddress(DeliveryAddress deliveryAddress); @Update("update deliveryAddress set contactName=#{contactName},contactSex=#{contactSex},contactTel=#{contactTel},address=#{address} where daId=#{daId}") public int updateDeliveryAddress(DeliveryAddress deliveryAddress); @Delete("delete from deliveryAddress where daId=#{daId}") public int removeDeliveryAddress(Integer daId); }
4.2.1.4.Food
package com.neusoft.elmboot.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import com.neusoft.elmboot.po.Food; @Mapper public interface FoodMapper { @Select("select * from food where businessId=#{businessId} order by foodId") public List<Food> listFoodByBusinessId(Integer businessId); @Select("select * from food where foodId=#{foodId}") public Food getFoodById(Integer foodId); }
4.2.1.5.OrderDetailet
package com.neusoft.elmboot.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import com.neusoft.elmboot.po.OrderDetailet; @Mapper public interface OrderDetailetMapper { public int saveOrderDetailetBatch(List<OrderDetailet> list); public List<OrderDetailet> listOrderDetailetByOrderId(Integer orderOd); }
<?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.neusoft.elmboot.mapper.OrderDetailetMapper"> <insert id="saveOrderDetailetBatch" parameterType="OrderDetailet"> insert into orderDetailet(orderId,foodId,quantity) values <foreach collection="list" item="od" separator=","> (#{od.orderId},#{od.foodId},#{od.quantity}) </foreach> </insert> <resultMap type="OrderDetailet" id="orderDetailetResultMap"> <id column="odId" property="odId"/> <result column="orderId" property="orderId"/> <result column="foodId" property="foodId"/> <result column="quantity" property="quantity"/> <association property="food" javaType="Food" select="com.neusoft.elmboot.mapper.FoodMapper.getFoodById" column="foodId"/> </resultMap> <select id="listOrderDetailetByOrderId" parameterType="Integer" resultMap="orderDetailetResultMap"> select * from orderDetailet where orderId=#{orderId} </select> </mapper>
4.2.1.6.Orders
package com.neusoft.elmboot.mapper; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import com.neusoft.elmboot.po.User; @Mapper public interface UserMapper { @Select("select * from user where userId=#{userId} and password=#{password}") public User getUserByIdByPass(User user); @Select("select count(*) from user where userId=#{userId}") public int getUserById(String userId); @Insert("insert into user values(#{userId},#{password},#{userName},#{userSex},null,1)") public int saveUser(User user); }
<?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.neusoft.elmboot.mapper.OrdersMapper"> <resultMap type="Orders" id="ordersResultMap"> <id column="orderId" property="orderId"/> <result column="userId" property="userId"/> <result column="businessId" property="businessId"/> <result column="orderDate" property="orderDate"/> <result column="orderTotal" property="orderTotal"/> <result column="daId" property="daId"/> <result column="orderState" property="orderState"/> <association property="business" javaType="Business" select="com.neusoft.elmboot.mapper.BusinessMapper.getBusinessById" column="businessId"/> <collection property="list" ofType="OrderDetailet" select="com.neusoft.elmboot.mapper.OrderDetailetMapper.listOrderDetailetByOrderId" column="orderId"/> </resultMap> <select id="getOrdersById" parameterType="Integer" resultMap="ordersResultMap"> select * from orders where orderId=#{orderId} </select> <select id="listOrdersByUserId" parameterType="String" resultMap="ordersResultMap"> select * from orders where userId=#{userId} order by orderId </select> </mapper>
4.2.1.7.User
package com.neusoft.elmboot.mapper; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import com.neusoft.elmboot.po.User; @Mapper public interface UserMapper { @Select("select * from user where userId=#{userId} and password=#{password}") public User getUserByIdByPass(User user); @Select("select count(*) from user where userId=#{userId}") public int getUserById(String userId); @Insert("insert into user values(#{userId},#{password},#{userName},#{userSex},null,1)") public int saveUser(User user); }
4.2.2.Service层代码
4.2.2.1.Business
package com.neusoft.elmboot.service; import java.util.List; import com.neusoft.elmboot.po.Business; public interface BusinessService { public List<Business> listBusinessByOrderTypeId(Integer orderTypeId); public Business getBusinessById(Integer businessId); }
package com.neusoft.elmboot.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.neusoft.elmboot.mapper.BusinessMapper; import com.neusoft.elmboot.po.Business; import com.neusoft.elmboot.service.BusinessService; @Service public class BusinessServiceImpl implements BusinessService{ @Autowired private BusinessMapper businessMapper; @Override public List<Business> listBusinessByOrderTypeId(Integer orderTypeId) { return businessMapper.listBusinessByOrderTypeId(orderTypeId); } @Override public Business getBusinessById(Integer businessId) { return businessMapper.getBusinessById(businessId); } }
4.2.2.2.Cart
package com.neusoft.elmboot.service; import java.util.List; import com.neusoft.elmboot.po.Cart; public interface CartService { public List<Cart> listCart(Cart cart); public int saveCart(Cart cart); public int updateCart(Cart cart); public int removeCart(Cart cart); }
package com.neusoft.elmboot.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.neusoft.elmboot.mapper.CartMapper; import com.neusoft.elmboot.po.Cart; import com.neusoft.elmboot.service.CartService; @Service public class CartServiceImpl implements CartService{ @Autowired private CartMapper cartMapper; @Override public List<Cart> listCart(Cart cart) { return cartMapper.listCart(cart); } @Override public int saveCart(Cart cart) { return cartMapper.saveCart(cart); } @Override public int updateCart(Cart cart) { return cartMapper.updateCart(cart); } @Override public int removeCart(Cart cart) { return cartMapper.removeCart(cart); } }
4.2.2.3.DeliveryAddress
package com.neusoft.elmboot.service; import java.util.List; import com.neusoft.elmboot.po.DeliveryAddress; public interface DeliveryAddressService { public List<DeliveryAddress> listDeliveryAddressByUserId(String userId); public DeliveryAddress getDeliveryAddressById(Integer daId); public int saveDeliveryAddress(DeliveryAddress deliveryAddress); public int updateDeliveryAddress(DeliveryAddress deliveryAddress); public int removeDeliveryAddress(Integer daId); }
package com.neusoft.elmboot.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.neusoft.elmboot.mapper.DeliveryAddressMapper; import com.neusoft.elmboot.po.DeliveryAddress; import com.neusoft.elmboot.service.DeliveryAddressService; @Service public class DeliveryAddressServiceImpl implements DeliveryAddressService{ @Autowired private DeliveryAddressMapper deliveryAddressMapper; @Override public List<DeliveryAddress> listDeliveryAddressByUserId(String userId) { return deliveryAddressMapper.listDeliveryAddressByUserId(userId); } @Override public DeliveryAddress getDeliveryAddressById(Integer daId) { return deliveryAddressMapper.getDeliveryAddressById(daId); } @Override public int saveDeliveryAddress(DeliveryAddress deliveryAddress) { return deliveryAddressMapper.saveDeliveryAddress(deliveryAddress); } @Override public int updateDeliveryAddress(DeliveryAddress deliveryAddress) { return deliveryAddressMapper.updateDeliveryAddress(deliveryAddress); } @Override public int removeDeliveryAddress(Integer daId) { return deliveryAddressMapper.removeDeliveryAddress(daId); } }
4.2.2.4.Food
package com.neusoft.elmboot.service; import java.util.List; import com.neusoft.elmboot.po.Food; public interface FoodService { public List<Food> listFoodByBusinessId(Integer businessId); }
package com.neusoft.elmboot.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.neusoft.elmboot.mapper.FoodMapper; import com.neusoft.elmboot.po.Food; import com.neusoft.elmboot.service.FoodService; @Service public class FoodServiceImpl implements FoodService{ @Autowired private FoodMapper foodMapper; @Override public List<Food> listFoodByBusinessId(Integer businessId) { return foodMapper.listFoodByBusinessId(businessId); } }
4.2.2.5.Orders
package com.neusoft.elmboot.service; import java.util.List; import com.neusoft.elmboot.po.Orders; public interface OrdersService { public int createOrders(Orders orders); public Orders getOrdersById(Integer orderId); public List<Orders> listOrdersByUserId(String userId); }
package com.neusoft.elmboot.service.impl; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.neusoft.elmboot.mapper.CartMapper; import com.neusoft.elmboot.mapper.OrderDetailetMapper; import com.neusoft.elmboot.mapper.OrdersMapper; import com.neusoft.elmboot.po.Cart; import com.neusoft.elmboot.po.OrderDetailet; import com.neusoft.elmboot.po.Orders; import com.neusoft.elmboot.service.OrdersService; import com.neusoft.elmboot.util.CommonUtil; @Service public class OrdersServiceImpl implements OrdersService{ @Autowired private CartMapper cartMapper; @Autowired private OrdersMapper ordersMapper; @Autowired private OrderDetailetMapper orderDetailetMapper; @Override @Transactional public int createOrders(Orders orders) { //1、查询当前用户购物车中当前商家的所有食品 Cart cart = new Cart(); cart.setUserId(orders.getUserId()); cart.setBusinessId(orders.getBusinessId()); List<Cart> cartList = cartMapper.listCart(cart); //2、创建订单(返回生成的订单编号) orders.setOrderDate(CommonUtil.getCurrentDate()); ordersMapper.saveOrders(orders); int orderId = orders.getOrderId(); //3、批量添加订单明细 List<OrderDetailet> list = new ArrayList<>(); for(Cart c : cartList) { OrderDetailet od = new OrderDetailet(); od.setOrderId(orderId); od.setFoodId(c.getFoodId()); od.setQuantity(c.getQuantity()); list.add(od); } orderDetailetMapper.saveOrderDetailetBatch(list); //4、从购物车表中删除相关食品信息 cartMapper.removeCart(cart); return orderId; } @Override public Orders getOrdersById(Integer orderId) { return ordersMapper.getOrdersById(orderId); } @Override public List<Orders> listOrdersByUserId(String userId){ return ordersMapper.listOrdersByUserId(userId); } }
4.2.2.6.user
package com.neusoft.elmboot.service; import com.neusoft.elmboot.po.User; public interface UserService { public User getUserByIdByPass(User user); public int getUserById(String userId); public int saveUser(User user); }
package com.neusoft.elmboot.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.neusoft.elmboot.mapper.UserMapper; import com.neusoft.elmboot.po.User; import com.neusoft.elmboot.service.UserService; @Service public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override public User getUserByIdByPass(User user) { return userMapper.getUserByIdByPass(user); } @Override public int getUserById(String userId) { return userMapper.getUserById(userId); } @Override public int saveUser(User user) { return userMapper.saveUser(user); } }
4.2.3.Controller层代码
4.2.3.1.Business
package com.neusoft.elmboot.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.neusoft.elmboot.po.Business; import com.neusoft.elmboot.service.BusinessService; @RestController @RequestMapping("/BusinessController") public class BusinessController { @Autowired private BusinessService businessService; @RequestMapping("/listBusinessByOrderTypeId") public List<Business> listBusinessByOrderTypeId(Business business) throws Exception{ return businessService.listBusinessByOrderTypeId(business.getOrderTypeId()); } @RequestMapping("/getBusinessById") public Business getBusinessById(Business business) throws Exception{ return businessService.getBusinessById(business.getBusinessId()); } }
4.2.3.2.Cart
package com.neusoft.elmboot.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.neusoft.elmboot.po.Cart; import com.neusoft.elmboot.service.CartService; @RestController @RequestMapping("/CartController") public class CartController { @Autowired private CartService cartService; @RequestMapping("/listCart") public List<Cart> listCart(Cart cart) throws Exception{ return cartService.listCart(cart); } @RequestMapping("/saveCart") public int saveCart(Cart cart) throws Exception{ return cartService.saveCart(cart); } @RequestMapping("/updateCart") public int updateCart(Cart cart) throws Exception{ return cartService.updateCart(cart); } @RequestMapping("/removeCart") public int removeCart(Cart cart) throws Exception{ return cartService.removeCart(cart); } }
4.2.3.3.DeliveryAddress
package com.neusoft.elmboot.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.neusoft.elmboot.po.DeliveryAddress; import com.neusoft.elmboot.service.DeliveryAddressService; @RestController @RequestMapping("/DeliveryAddressController") public class DeliveryAddressController { @Autowired private DeliveryAddressService deliveryAddressService; @RequestMapping("/listDeliveryAddressByUserId") public List<DeliveryAddress> listDeliveryAddressByUserId(DeliveryAddress deliveryAddress) throws Exception{ return deliveryAddressService.listDeliveryAddressByUserId(deliveryAddress.getUserId()); } @RequestMapping("/getDeliveryAddressById") public DeliveryAddress getDeliveryAddressById(DeliveryAddress deliveryAddress) throws Exception{ return deliveryAddressService.getDeliveryAddressById(deliveryAddress.getDaId()); } @RequestMapping("/saveDeliveryAddress") public int saveDeliveryAddress(DeliveryAddress deliveryAddress) throws Exception{ return deliveryAddressService.saveDeliveryAddress(deliveryAddress); } @RequestMapping("/updateDeliveryAddress") public int updateDeliveryAddress(DeliveryAddress deliveryAddress) throws Exception{ return deliveryAddressService.updateDeliveryAddress(deliveryAddress); } @RequestMapping("/removeDeliveryAddress") public int removeDeliveryAddress(DeliveryAddress deliveryAddress) throws Exception{ return deliveryAddressService.removeDeliveryAddress(deliveryAddress.getDaId()); } }
4.2.3.4.Food
package com.neusoft.elmboot.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.neusoft.elmboot.po.Food; import com.neusoft.elmboot.service.FoodService; @RestController @RequestMapping("/FoodController") public class FoodController { @Autowired private FoodService foodService; @RequestMapping("/listFoodByBusinessId") public List<Food> listFoodByBusinessId(Food food) throws Exception{ return foodService.listFoodByBusinessId(food.getBusinessId()); } }
4.2.3.5.Orders
package com.neusoft.elmboot.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.neusoft.elmboot.po.Orders; import com.neusoft.elmboot.service.OrdersService; @RestController @RequestMapping("/OrdersController") public class OrdersController { @Autowired private OrdersService ordersService; @RequestMapping("/createOrders") public int createOrders(Orders orders) throws Exception{ return ordersService.createOrders(orders); } @RequestMapping("/getOrdersById") public Orders getOrdersById(Orders orders) throws Exception{ return ordersService.getOrdersById(orders.getOrderId()); } @RequestMapping("/listOrdersByUserId") public List<Orders> listOrdersByUserId(Orders orders) throws Exception{ return ordersService.listOrdersByUserId(orders.getUserId()); } }
4.2.3.7.user
package com.neusoft.elmboot.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.neusoft.elmboot.po.User; import com.neusoft.elmboot.service.UserService; @RestController @RequestMapping("/UserController") public class UserController { @Autowired private UserService userService; @RequestMapping("/getUserByIdByPass") public User getUserByIdByPass(User user) throws Exception{ return userService.getUserByIdByPass(user); } @RequestMapping("/getUserById") public int getUserById(User user) throws Exception{ return userService.getUserById(user.getUserId()); } @RequestMapping("/saveUser") public int saveUser(User user) throws Exception{ return userService.saveUser(user); } }
4.3.前端代码
代码地址: https://gitee.com/null_688_6639/elmproject
4.3.1.Index组件
注意点:
- 修改图片路径,包括css中背景图片路径。
- style中添加scoped。
- 将静态工程中的 icon.css内容添加到style中。
<template>
<div class="wrapper">
<!-- header部分 -->
<header>
<div class="icon-location-box">
<div class="icon-location"></div>
</div>
<div class="location-text">沈阳市规划大厦<i class="fa fa-caret-down"></i></div>
</header>
<!-- search部分 -->
<!--
搜索框部分(此块与search-fixed-top块宽度高度一致,用于当
search-fixed-top块固定后,挡住下面块不要窜上去)
-->
<div class="search">
<!-- 当滚动条超过上面的定位块时,search-fixed-top块变成固定在顶部。 -->
<div class="search-fixed-top" ref="fixedBox">
<!-- 搜索框部分中间的白框 -->
<div class="search-box">
<i class="fa fa-search"></i>搜索饿了么商家、商品名称
</div>
</div>
</div>
<!-- 点餐分类部分 -->
<ul class="foodtype">
<li @click="toBusinessList(1)">
<img src="../assets/dcfl01.png">
<p>美食</p>
</li>
<li @click="toBusinessList(2)">
<img src="../assets/dcfl02.png">
<p>早餐</p>
</li>
<li @click="toBusinessList(3)">
<img src="../assets/dcfl03.png">
<p>跑腿代购</p>
</li>
<li @click="toBusinessList(4)">
<img src="../assets/dcfl04.png">
<p>汉堡披萨</p>
</li>
<li @click="toBusinessList(5)">
<img src="../assets/dcfl05.png">
<p>甜品饮品</p>
</li>
<li @click="toBusinessList(6)">
<img src="../assets/dcfl06.png">
<p>速食简餐</p>
</li>
<li @click="toBusinessList(7)">
<img src="../assets/dcfl07.png">
<p>地方小吃</p>
</li>
<li @click="toBusinessList(8)">
<img src="../assets/dcfl08.png">
<p>米粉面馆</p>
</li>
<li @click="toBusinessList(9)">
<img src="../assets/dcfl09.png">
<p>包子粥铺</p>
</li>
<li @click="toBusinessList(10)">
<img src="../assets/dcfl10.png">
<p>炸鸡炸串</p>
</li>
</ul>
<!-- 横幅广告部分(注意:此处有背景图片) -->
<div class="banner">
<h3>品质套餐</h3>
<p>搭配齐全吃得好</p>
<a>立即抢购 ></a>
</div>
<!-- 超级会员部分 -->
<div class="supermember">
<div class="left">
<img src="../assets/super_member.png">
<h3>超级会员</h3>
<p>• 每月享超值权益</p>
</div>
<div class="right">
立即开通 >
</div>
</div>
<!-- 推荐商家部分 -->
<div class="recommend">
<div class="recommend-line"></div>
<p>推荐商家</p>
<div class="recommend-line"></div>
</div>
<!-- 推荐方式部分 -->
<ul class="recommendtype">
<li>综合排序<i class="fa fa-caret-down"></i></li>
<li>距离最近</li>
<li>销量最高</li>
<li>筛选<i class="fa fa-filter"></i></li>
</ul>
<!-- 推荐商家列表部分 -->
<ul class="business">
<li>
<img src="../assets/sj01.png">
<div class="business-info">
<div class="business-info-h">
<h3>万家饺子(软件园E18店)</h3>
<div class="business-info-like">•</div>
</div>
<div class="business-info-star">
<div class="business-info-star-left">
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<p>4.9 月售345单</p>
</div>
<div class="business-info-star-right">
蜂鸟专送
</div>
</div>
<div class="business-info-delivery">
<p>¥15起送 | ¥3配送</p>
<p>3.22km | 30分钟</p>
</div>
<div class="business-info-explain">
<div>各种饺子</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">新</div>
<p>饿了么新用户首单立减9元</p>
</div>
<div class="business-info-promotion-right">
<p>2个活动</p>
<i class="fa fa-caret-down"></i>
</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon" style="background-color: #F1884F;">特</div>
<p>特价商品5元起</p>
</div>
</div>
</div>
</li>
<li>
<img src="../assets/sj02.png">
<div class="business-info">
<div class="business-info-h">
<h3>小锅饭豆腐馆(全运店)</h3>
<div class="business-info-like">•</div>
</div>
<div class="business-info-star">
<div class="business-info-star-left">
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<p>4.9 月售345单</p>
</div>
<div class="business-info-star-right">
蜂鸟专送
</div>
</div>
<div class="business-info-delivery">
<p>¥15起送 | ¥3配送</p>
<p>3.22km | 30分钟</p>
</div>
<div class="business-info-explain">
<div>各种饺子</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">新</div>
<p>饿了么新用户首单立减9元</p>
</div>
<div class="business-info-promotion-right">
<p>2个活动</p>
<i class="fa fa-caret-down"></i>
</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">特</div>
<p>特价商品5元起</p>
</div>
</div>
</div>
</li>
<li>
<img src="../assets/sj03.png">
<div class="business-info">
<div class="business-info-h">
<h3>麦当劳麦乐送(全运路店)</h3>
<div class="business-info-like">•</div>
</div>
<div class="business-info-star">
<div class="business-info-star-left">
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<p>4.9 月售345单</p>
</div>
<div class="business-info-star-right">
蜂鸟专送
</div>
</div>
<div class="business-info-delivery">
<p>¥15起送 | ¥3配送</p>
<p>3.22km | 30分钟</p>
</div>
<div class="business-info-explain">
<div>各种饺子</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">新</div>
<p>饿了么新用户首单立减9元</p>
</div>
<div class="business-info-promotion-right">
<p>2个活动</p>
<i class="fa fa-caret-down"></i>
</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">特</div>
<p>特价商品5元起</p>
</div>
</div>
</div>
</li>
<li>
<img src="../assets/sj04.png">
<div class="business-info">
<div class="business-info-h">
<h3>米村拌饭(浑南店)</h3>
<div class="business-info-like">•</div>
</div>
<div class="business-info-star">
<div class="business-info-star-left">
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<p>4.9 月售345单</p>
</div>
<div class="business-info-star-right">
蜂鸟专送
</div>
</div>
<div class="business-info-delivery">
<p>¥15起送 | ¥3配送</p>
<p>3.22km | 30分钟</p>
</div>
<div class="business-info-explain">
<div>各种饺子</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">新</div>
<p>饿了么新用户首单立减9元</p>
</div>
<div class="business-info-promotion-right">
<p>2个活动</p>
<i class="fa fa-caret-down"></i>
</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">特</div>
<p>特价商品5元起</p>
</div>
</div>
</div>
</li>
<li>
<img src="../assets/sj05.png">
<div class="business-info">
<div class="business-info-h">
<h3>申记串道(中海康城店)</h3>
<div class="business-info-like">•</div>
</div>
<div class="business-info-star">
<div class="business-info-star-left">
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<i class="fa fa-star"></i>
<p>4.9 月售345单</p>
</div>
<div class="business-info-star-right">
蜂鸟专送
</div>
</div>
<div class="business-info-delivery">
<p>¥15起送 | ¥3配送</p>
<p>3.22km | 30分钟</p>
</div>
<div class="business-info-explain">
<div>各种饺子</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">新</div>
<p>饿了么新用户首单立减9元</p>
</div>
<div class="business-info-promotion-right">
<p>2个活动</p>
<i class="fa fa-caret-down"></i>
</div>
</div>
<div class="business-info-promotion">
<div class="business-info-promotion-left">
<div class="business-info-promotion-left-incon">特</div>
<p>特价商品5元起</p>
</div>
</div>
</div>
</li>
</ul>
<!-- 底部菜单部分 -->
<Footer></Footer>
</div>
</template>
<script>
//导入共通组件
import Footer from '../components/Footer.vue';
export default {
name: 'Index',
mounted() {
document.onscroll = ()=> {
//获取滚动条位置
let s1 = document.documentElement.scrollTop;
let s2 = document.body.scrollTop;
let scroll = s1 == 0 ? s2 : s1;
//获取视口宽度
let width = document.documentElement.clientWidth;
//获取顶部固定块
let search = this.$refs.fixedBox;
//判断滚动条超过视口宽度的12%时,搜索块变固定定位
if (scroll > width * 0.12) {
search.style.position = 'fixed';
search.style.left = '0';
search.style.top = '0';
} else {
search.style.position = 'static';
}
}
},
destroyed() {
//当切换到其他组件时,就不需要document滚动条事件,所以将此事件去掉
document.onscroll = null;
},
components:{
Footer
},
methods:{
toBusinessList(orderTypeId){
this.$router.push({path:'/businessList',query:{orderTypeId:orderTypeId}});
}
}
}
</script>
<style scoped>
/****************** 总容器 ******************/
.wrapper {
width: 100%;
height: 100%;
}
/****************** header ******************/
.wrapper header {
width: 100%;
height: 12vw;
background-color: #0097FF;
display: flex;
align-items: center;
}
.wrapper header .icon-location-box {
width: 3.5vw;
height: 3.5vw;
margin: 0 1vw 0 3vw;
}
.wrapper header .location-text {
font-size: 4.5vw;
font-weight: 700;
color: #fff;
}
.wrapper header .location-text .fa-caret-down {
margin-left: 1vw;
}
/****************** search ******************/
.wrapper .search {
width: 100%;
height: 13vw;
}
.wrapper .search .search-fixed-top {
width: 100%;
height: 13vw;
background-color: #0097FF;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper .search .search-fixed-top .search-box {
width: 90%;
height: 9vw;
background-color: #fff;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
font-size: 3.5vw;
color: #AEAEAE;
font-family: "宋体";
/*此样式是让文本选中状态无效*/
user-select: none;
}
.wrapper .search .search-fixed-top .search-box .fa-search {
margin-right: 1vw;
}
/****************** 点餐分类部分 ******************/
.wrapper .foodtype {
width: 100%;
height: 48vw;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
/*要使用align-content。10个子元素将自动换行为两行,而且两行作为一个整体垂直居中*/
align-content: center;
}
.wrapper .foodtype li {
/*一共10个子元素,通过计算,子元素宽度在16.7 ~ 20 之间,才能保证换两行*/
width: 18vw;
height: 20vw;
display: flex;
/*弹性盒子主轴方向设为column,然后仍然是垂直水平方向居中*/
flex-direction: column;
justify-content: center;
align-items: center;
user-select: none;
cursor: pointer;
}
.wrapper .foodtype li img {
width: 12vw;
/*视频讲解时高度设置为12vw,实际上设置为10.3vw更佳*/
height: 10.3vw;
}
.wrapper .foodtype li p {
font-size: 3.2vw;
color: #666;
}
/****************** 横幅广告部分 ******************/
.wrapper .banner {
/**
* 设置容器宽度95%,然后水平居中,这样两边留白;
* 这里不能用padding,因为背景图片也会覆盖padding
*/
width: 95%;
margin: 0 auto;
height: 29vw;
/*此三个样式组合,可以保证背景图片充满整个容器*/
background-image: url(../assets/index_banner.png);
background-repeat: no-repeat;
background-size: cover;
box-sizing: border-box;
padding: 2vw 6vw;
}
.wrapper .banner h3 {
font-size: 4.2vw;
margin-bottom: 1.2vw;
}
.wrapper .banner p {
font-size: 3.4vw;
color: #666;
margin-bottom: 2.4vw;
}
.wrapper .banner a {
font-size: 3vw;
color: #C79060;
font-weight: 700;
}
/****************** 超级会员部分 ******************/
.wrapper .supermember {
/*这里也设置容器宽度95%,不能用padding,因为背景色也会充满padding*/
width: 95%;
margin: 0 auto;
height: 11.5vw;
background-color: #FEEDC1;
margin-top: 1.3vw;
border-radius: 2px;
color: #644F1B;
display: flex;
justify-content: space-between;
align-items: center;
}
.wrapper .supermember .left {
display: flex;
align-items: center;
margin-left: 4vw;
user-select: none;
}
.wrapper .supermember .left img {
width: 6vw;
height: 6vw;
margin-right: 2vw;
}
.wrapper .supermember .left h3 {
font-size: 4vw;
margin-right: 2vw;
}
.wrapper .supermember .left p {
font-size: 3vw;
}
.wrapper .supermember .right {
font-size: 3vw;
margin-right: 4vw;
cursor: pointer;
}
/****************** 推荐商家部分 ******************/
.wrapper .recommend {
width: 100%;
height: 14vw;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper .recommend .recommend-line {
width: 6vw;
height: 0.2vw;
background-color: #888;
}
.wrapper .recommend p {
font-size: 4vw;
margin: 0 4vw;
}
/****************** 推荐方式部分 ******************/
.wrapper .recommendtype {
width: 100%;
height: 5vw;
margin-bottom: 5vw;
display: flex;
justify-content: space-around;
align-items: center;
}
.wrapper .recommendtype li {
font-size: 3.5vw;
color: #555;
}
/****************** 推荐商家列表部分 ******************/
.wrapper .business {
width: 100%;
margin-bottom: 14vw;
}
.wrapper .business li {
width: 100%;
box-sizing: border-box;
padding: 2.5vw;
user-select: none;
border-bottom: solid 1px #DDD;
display: flex;
}
.wrapper .business li img {
width: 18vw;
height: 18vw;
}
.wrapper .business li .business-info {
width: 100%;
box-sizing: border-box;
padding-left: 3vw;
}
.wrapper .business li .business-info .business-info-h {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2vw;
}
.wrapper .business li .business-info .business-info-h h3 {
font-size: 4vw;
color: #333;
}
.wrapper .business li .business-info .business-info-h .business-info-like {
width: 1.6vw;
height: 3.4vw;
background-color: #666;
color: #fff;
font-size: 4vw;
margin-right: 4vw;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper .business li .business-info .business-info-star {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2vw;
font-size: 3.1vw;
}
.wrapper .business li .business-info .business-info-star .business-info-star-left {
display: flex;
align-items: center;
}
.wrapper .business li .business-info .business-info-star .business-info-star-left .fa-star {
color: #FEC80E;
margin-right: 0.5vw;
}
.wrapper .business li .business-info .business-info-star .business-info-star-left p {
color: #666;
margin-left: 1vw;
}
.wrapper .business li .business-info .business-info-star .business-info-star-right {
background-color: #0097FF;
color: #fff;
font-size: 2.4vw;
border-radius: 2px;
padding: 0 0.6vw;
}
.wrapper .business li .business-info .business-info-delivery {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2vw;
color: #666;
font-size: 3.1vw;
}
.wrapper .business li .business-info .business-info-explain {
display: flex;
align-items: center;
margin-bottom: 3vw;
}
.wrapper .business li .business-info .business-info-explain div {
border: solid 1px #DDD;
font-size: 2.8vw;
color: #666;
border-radius: 3px;
padding: 0 0.1vw;
}
.wrapper .business li .business-info .business-info-promotion {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.8vw;
}
.wrapper .business li .business-info .business-info-promotion .business-info-promotion-left {
display: flex;
align-items: center;
}
.wrapper .business li .business-info .business-info-promotion .business-info-promotion-left .business-info-promotion-left-incon {
width: 4vw;
height: 4vw;
background-color: #70BC46;
border-radius: 3px;
font-size: 3vw;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper .business li .business-info .business-info-promotion .business-info-promotion-left p {
color: #666;
font-size: 3vw;
margin-left: 2vw;
}
.wrapper .business li .business-info .business-info-promotion .business-info-promotion-right {
display: flex;
align-items: center;
font-size: 2.5vw;
color: #999;
}
.wrapper .business li .business-info .business-info-promotion .business-info-promotion-right p {
margin-right: 2vw;
}
</style>