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>