花店商城+后台管理
网站简介
本网站后端使用SpringBoot+MyBatis-Plus框架,前端使用Vue+Thymeleaf+layui框架。
本网站包含前台和后台,前台主要包含:登录/注册页、首页、商城页、商品详情页、联系我们页、购物车导航页、购物车页、个人中心页和订单页。后台主要包含:登录页、首页、用户管理页、订单管理页、销量排行页。
前台登录注册页
前台首页
商城页
商品详情页
联系我们页
购物车导航页
购物册页
个人中心页
订单页
后台登录页
后台首页
用户管理页
订单管理页
销量排行页
门店分布页
门店管理页
代码片段
Bean
package cn.flower.bean;
import java.math.BigDecimal;
import lombok.Data;
public class OrderBean {
private String id;
private String userId;
private String flowerId;
private int count;
private BigDecimal total;
private int status;
private String createTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getFlowerId() {
return flowerId;
}
public void setFlowerId(String flowerId) {
this.flowerId = flowerId;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public BigDecimal getTotal() {
return total;
}
public void setTotal(BigDecimal total) {
this.total = total;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
}
Controller
package cn.flower.controller;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import cn.flower.bean.OrderBean;
import cn.flower.bean.UserBean;
import cn.flower.service.OrderService;
import cn.flower.service.UserService;
@Controller
public class DistController {
@Autowired
private UserService userService;
@Autowired
private OrderService orderService;
@RequestMapping("/dist/")
public String distIndex() {
return "dist/main";
}
@RequestMapping("/dist/login")
public String login() {
return "dist/login";
}
@RequestMapping("/dist/out")
public String out() {
return "dist/login";
}
@RequestMapping("/dist/mainfunction")
public String mainfunction() {
return "dist/mainfunction";
}
@ResponseBody
@RequestMapping("/dist/userList")
public Map<String, Object> userList(HttpServletRequest req){
Integer size = Integer.valueOf(req.getParameter("size"));
int page = Integer.valueOf(req.getParameter("page"));
int limit = Integer.valueOf(req.getParameter("limit"));
String account = req.getParameter("account");
String id = req.getParameter("id");
List<UserBean> data = null;
if(null != size && size != 0) {
data = userService.userList(id, account, 0, size);
} else {
data = userService.userList(id, account, (page - 1) * limit, limit);
}
Map<String, Object> result = new HashMap<>();
result.put("code", 0);
result.put("msg", "success");
result.put("count", data.size());
result.put("data", data);
return result;
}
@RequestMapping("/dist/user")
public String user() {
return "dist/user";
}
@RequestMapping("/dist/salesVolume")
@ResponseBody
public List<Integer> salesVolume(){
List<Integer> result = new ArrayList<>();
int year = Calendar.getInstance().get(Calendar.YEAR);
int month = Calendar.getInstance().get(Calendar.MONTH) + 1;
if(month != 12) {
for(int i = month + 1; i <= 12; i++) {
if(i < 10) {
Integer count = orderService.getCountByTime((year - 1) + "-0" + i);
result.add(count);
}else {
Integer count = orderService.getCountByTime((year - 1) + "-" + i);
result.add(count);
}
}
for(int i = 1; i <= month; i++) {
if(i < 10) {
Integer count = orderService.getCountByTime(year + "-0" + i);
result.add(count);
}else {
Integer count = orderService.getCountByTime(year + "-" + i);
result.add(count);
}
}
}else {
for(int i = 1; i <= 12; i++) {
if(i < 10) {
Integer count = orderService.getCountByTime(year + "-0" + i);
result.add(count);
}else {
Integer count = orderService.getCountByTime(year + "-" + i);
result.add(count);
}
}
}
return result;
}
@RequestMapping("/dist/delUser")
@ResponseBody
public int delUser(@RequestBody JSONObject data) {
String ids = "";
@SuppressWarnings("unchecked")
List<String> list = (ArrayList<String>) data.get("userIds");
for(String id : list) {
ids += "'" + id + "',";
}
return userService.delUser(ids.substring(0, ids.length() - 1));
}
@RequestMapping("/dist/userAdd")
public String userAdd() {
return "/dist/userAdd";
}
@RequestMapping("/dist/userEdit")
public String userEdit() {
return "/dist/userEdit";
}
@RequestMapping("/dist/orderStatic")
public String orderStatic() {
return "/dist/orderStatic";
}
@RequestMapping("/dist/register")
public String register(@RequestParam("account") String account, @RequestParam("password") String password, ModelMap map) {
UserBean user = userService.getUserByInfo(account, null);
if(null != user) {
map.addAttribute("msg","用户已存在!");
} else {
int row = userService.registerUser(account, password);
if(row == 0) {
map.addAttribute("msg","注册失败,请联系管理员!");
}else {
map.addAttribute("msg","注册成功!");
}
}
return "/dist/user";
}
@RequestMapping("/dist/updateUser")
public String updateUser(@RequestParam("userId") String userId, @RequestParam("account") String account, @RequestParam("password") String password, ModelMap map) {
List<UserBean> user = userService.userList(userId, null, 0, 0);
if(null == user || user.size() == 0) {
map.addAttribute("msg","用户不存在!");
} else {
int row = userService.updateUser(userId, account, password);
if(row == 0) {
map.addAttribute("msg","修改失败,请联系管理员!");
}else {
map.addAttribute("msg","修改成功!");
}
}
return "/dist/user";
}
@RequestMapping("/dist/order")
public String order() {
return "/dist/order";
}
@ResponseBody
@RequestMapping("/dist/orderList")
public Map<String, Object> orderList(HttpServletRequest req){
int page = Integer.valueOf(req.getParameter("page"));
int limit = Integer.valueOf(req.getParameter("limit"));
String id = req.getParameter("id");
String userId = req.getParameter("userId");
Integer status = null == req.getParameter("status") || "".equals(req.getParameter("status")) ? null : Integer.parseInt(req.getParameter("status"));
String createTime = req.getParameter("createTime");
List<OrderBean> data = orderService.orderList(id, userId, status, createTime, (page - 1) * limit, limit);
Map<String, Object> result = new HashMap<>();
result.put("code", 0);
result.put("msg", "success");
result.put("count", data.size());
result.put("data", data);
return result;
}
@ResponseBody
@RequestMapping("/dist/flowerTop")
public List<Map<String, Object>> flowerTop(){
return orderService.flowerTop();
}
@ResponseBody
@RequestMapping("/dist/updateOrderStatus")
public int updateOrderStatus(@RequestBody JSONObject data){
return orderService.updateOrderStatus(data.get("orderId").toString(), data.getIntValue("status"));
}
}
Dao
package cn.flower.dao;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Component;
import cn.flower.bean.OrderBean;
@Component
public interface OrderDao {
@Insert("insert into `order` values(#{id}, #{userId}, #{flowerId}, #{count}, #{total}, #{status}, #{createTime})")
Integer insertOrder(@Param("id") String id, @Param("userId") String userId,
@Param("flowerId") String flowerId, @Param("count") int count, @Param("total") BigDecimal total,
@Param("status") int status, @Param("createTime") String createTime);
@Select("<script>select id, userId, flowerId, count, total, status, createTime "
+ "from `order` where 1 = 1 "
+ "<if test='id != null and id != \"\"'> and id = #{id} </if>"
+ "<if test='userId != null and userId != \"\"'> and userId = #{userId} </if>"
+ "</script>")
List<OrderBean> getOrderList(@Param("id") String id, @Param("userId") String userId);
@Select("select count(1) from `order` where LEFT(createTime,7) = #{time}")
Integer getCountByTime(@Param("time") String time);
@Select("<script>select id, userId, flowerId, count, total, status, createTime "
+ "from `order` where 1 = 1 "
+ "<if test='id != null and id != \"\"'> and id = #{id} </if>"
+ "<if test='userId != null and userId != \"\"'> and userId = #{userId} </if>"
+ "<if test='status != null and status != \"\"'> and status = #{status} </if>"
+ "<if test='createTime != null and createTime != \"\"'> and left(createTime,10) = #{createTime} </if>"
+ "<if test='i != null and i != \"\" and limit != null and limit != \"\" and limit != 0'>limit ${i}, ${limit}</if>"
+ "</script>")
List<OrderBean> orderList(@Param("id") String id, @Param("userId") String userId, @Param("status") Integer status,
@Param("createTime") String createTime, @Param("i") int i, @Param("limit") int limit);
@Select("select flowerId,sum(count) as count,(select name from flower where id = flowerId) as name "
+ "from `order` group by flowerId order by count DESC limit 0,6")
List<Map<String, Object>> flowerTop();
@Update("update `order` set status = #{status} where id = #{id}")
int updateOrderStatus(String id, int status);
}
Service实现
package cn.flower.service.impl;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.flower.bean.FlowerBean;
import cn.flower.bean.OrderBean;
import cn.flower.dao.FlowerDao;
import cn.flower.dao.OrderDao;
import cn.flower.dao.ShopCartDao;
import cn.flower.service.OrderService;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
ShopCartDao shopCartDao;
@Autowired
FlowerDao flowerDao;
@Autowired
OrderDao orderDao;
@Transactional
@Override
public void takeOrder(String userId, List<String> orderList) {
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
for(String item : orderList) {
Map<String, Object> map = shopCartDao.getCartItemById(item);
FlowerBean bean = flowerDao.getFlowerByid(map.get("flowerId").toString());
BigDecimal total = bean.getPrice();
BigDecimal count = new BigDecimal((int) map.get("count"));
String id = UUID.randomUUID().toString();
orderDao.insertOrder(id, userId, map.get("flowerId").toString(), Integer.parseInt(map.get("count").toString()), total.multiply(count), 1, sdf.format(new Date()));
shopCartDao.deleteCartItem(item);
}
}
@Override
public List<OrderBean> getOrderList(String id, String userId) {
return orderDao.getOrderList(id, userId);
}
@Override
public Integer getCountByTime(String time) {
return orderDao.getCountByTime(time);
}
@Override
public List<OrderBean> orderList(String id, String userId, Integer status, String createTime, int i, int limit) {
return orderDao.orderList(id, userId, status, createTime, i, limit);
}
@Override
public List<Map<String, Object>> flowerTop() {
return orderDao.flowerTop();
}
@Override
public int updateOrderStatus(String id, int status) {
return orderDao.updateOrderStatus(id, status);
}
}
html
<!DOCTYPE html>
<html class="no-js" lang="zxx">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="meta description">
<title>FlowerShop</title>
<!--=== Favicon ===-->
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
<!-- Google fonts include -->
<link href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,500,500i,700,900%7CYesteryear" rel="stylesheet">
<!-- All Vendor & plugins CSS include -->
<link href="assets/css/vendor.css" rel="stylesheet">
<!-- Main Style CSS -->
<link href="assets/css/style.css" rel="stylesheet">
<link href="assets/css/pagination.css" rel="stylesheet">
<script src="assets/js/jquery-3.3.1.min.js" ></script>
<script src="assets/js/vue.min.js"></script>
<script src="assets/js/bootstrap.min.js" ></script>
<!-- Active Js -->
<script src="assets/js/active.js"></script>
<!--[if lt IE 9]>
<script src="//oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div id="shop">
<div class="headerCart"></div>
<!-- main wrapper start -->
<main style="margin-top:70px">
<!-- page main wrapper start -->
<div class="shop-main-wrapper section-space pb-0">
<div class="container">
<div class="row">
<!-- shop main wrapper start -->
<div class="col-lg-12">
<div class="shop-product-wrapper">
<!-- shop product top wrap start -->
<div class="shop-top-bar">
<div class="row align-items-center">
<div class="col-lg-7 col-md-6 order-2 order-md-1">
<div class="top-bar-left">
<div class="product-view-mode">
<a class="active" href="#" data-target="grid-view" data-toggle="tooltip" title="Grid View"><i class="fa fa-th"></i></a>
</div>
</div>
</div>
</div>
</div>
<!-- shop product top wrap start -->
<!-- product item list wrapper start -->
<div class="shop-product-wrap grid-view row mbn-40">
<template v-for="(item, index) in flowerList" :key="index">
<!-- product single item start -->
<div class="col-md-4 col-sm-6">
<!-- product grid start -->
<div class="product-item">
<figure class="product-thumb">
<a :href=`/flower/product?id=${item.id}`>
<img class="pri-img" :src=`assets/img/product/${item.priimg}` alt="product">
<img class="sec-img" :src=`assets/img/product/${item.secimg}` alt="product">
</a>
<div class="product-badge">
<div class="product-label new" v-if="item.isNew === '1'">
<span>new</span>
</div>
<div class="product-label discount" v-if="item.discount != 0">
<span>{{item.discount}}%</span>
</div>
</div>
<div class="button-group">
<a @click="addToCart(item.id)" style="cursor:pointer" data-placement="left" title="添加至购物车"><i class="lnr lnr-cart"></i></a>
</div>
</figure>
<div class="product-caption">
<p class="product-name">
<a href="product-details.html">{{item.name}}</a>
</p>
<div class="price-box">
<span class="price-regular">¥{{(item.price).toFixed(2)}}</span>
<span class="price-old" v-if="item.discount != 0"><del>¥{{(item.price * (item.discount / 100 + 1)).toFixed(2)}}</del></span>
</div>
</div>
</div>
<!-- product grid end -->
</div>
<!-- product single item end -->
</template>
</div>
<!-- product item list wrapper end -->
<!-- start pagination area -->
<div style="text-align:center">
<div class="page paginatoin-area" v-show="show">
<div class="pagelist">
<span style="margin-left:0px" class="jump" :class="{disabled:starts}" @click="{current_page--}"><i class="lnr lnr-chevron-left"></i></span>
<span v-show="current_page>5" class="jump" @click="jumpPage(1)">1</span>
<span class="ellipsis" v-show="efont">...</span>
<span class="jump" v-for="num in indexs" :class="{bgprimary:current_page==num}"
@click="jumpPage(num)">{{num}}</span>
<span class="ellipsis" v-show="ebehind">...</span>
<span v-show="current_page<pages-4" class="jump" @click="jumpPage(pages)">{{pages}}</span>
<span :class="{disabled:ends}" class="jump" @click="{current_page++}"><i class="lnr lnr-chevron-right"></i></span>
</div>
</div>
</div>
<!-- end pagination area -->
</div>
</div>
<!-- shop main wrapper end -->
</div>
</div>
</div>
<!-- page main wrapper end -->
</main>
<!-- main wrapper end -->
<!-- Start Footer Area Wrapper -->
<footer class="footer-wrapper">
<!-- footer widget area start -->
<div class="footer-widget-area">
<div class="container">
<div class="footer-widget-inner section-space">
<div class="row mbn-30">
<!-- footer widget item start -->
<div class="col-lg-5 col-md-6 col-sm-8">
<div class="footer-widget-item mb-30">
<div class="footer-widget-title">
<h5>联系 我们</h5>
</div>
<ul class="footer-widget-body accout-widget">
<li class="address">
<em><i class="lnr lnr-map-marker"></i></em>
长沙师范学院
</li>
<li class="email">
<em><i class="lnr lnr-envelope"></i>邮件: </em>
<a href="mailto:594507903@qq.com">594507903@qq.com</a>
</li>
<li class="phone">
<em><i class="lnr lnr-phone-handset"></i> 电话: </em>
<a href="tel:123-456-789">123-456-789</a>
</li>
</ul>
<div class="payment-method">
<img src="assets/img/payment-pic.png" alt="payment method">
</div>
</div>
</div>
<!-- footer widget item end -->
<!-- footer widget item start -->
<div class="col-lg-2 col-md-6 col-sm-4">
<div class="footer-widget-item mb-30">
<div class="footer-widget-title">
<h5>categories</h5>
</div>
<ul class="footer-widget-body">
<li><a href="#">Ecommerce</a></li>
<li><a href="#">shopify</a></li>
<li><a href="#">Prestashop</a></li>
<li><a href="#">Opencart</a></li>
<li><a href="#">Magento</a></li>
</ul>
</div>
</div>
<!-- footer widget item end -->
<!-- footer widget item start -->
<div class="col-lg-2 col-md-6 col-sm-6">
<div class="footer-widget-item mb-30">
<div class="footer-widget-title">
<h5>information</h5>
</div>
<ul class="footer-widget-body">
<li><a href="#">Home</a></li>
<li><a href="#">About Us</a></li>
<li><a href="#">Contact Us</a></li>
<li><a href="#">Exchanges</a></li>
<li><a href="#">Shipping</a></li>
</ul>
</div>
</div>
<!-- footer widget item end -->
<!-- footer widget item start -->
<div class="col-lg-2 offset-lg-1 col-md-6 col-sm-6">
<div class="footer-widget-item mb-30">
<div class="footer-widget-title">
<h5>Quick Links</h5>
</div>
<ul class="footer-widget-body">
<li><a href="#">Store Location</a></li>
<li><a href="#">My Account</a></li>
<li><a href="#">Orders Tracking</a></li>
<li><a href="#">Size Guide</a></li>
<li><a href="#">Contact Us</a></li>
</ul>
</div>
</div>
<!-- footer widget item end -->
</div>
</div>
</div>
</div>
<!-- footer widget area end -->
<!-- footer bottom area start -->
<div class="footer-bottom-area">
<div class="container">
<div class="row align-items-center">
<div class="col-md-6 order-2 order-md-1">
<div class="copyright-text">
<p>Copyright ©彬彬.</p>
</div>
</div>
<div class="col-md-6 order-1 order-md-2">
<div class="footer-social-link">
<a href="#"><i class="fa fa-twitter"></i></a>
<a href="#"><i class="fa fa-facebook"></i></a>
<a href="#"><i class="fa fa-linkedin"></i></a>
<a href="#"><i class="fa fa-instagram"></i></a>
</div>
</div>
</div>
</div>
</div>
<!-- footer bottom area end -->
</footer>
<!-- End Footer Area Wrapper -->
<!-- offcanvas search form start -->
<div class="offcanvas-search-wrapper">
<div class="offcanvas-search-inner">
<div class="offcanvas-close">
<i class="lnr lnr-cross"></i>
</div>
<div class="container">
<div class="offcanvas-search-box">
<form class="d-flex bdr-bottom w-100">
<input type="text" placeholder="Search entire storage here...">
<button class="search-btn"><i class="lnr lnr-magnifier"></i>search</button>
</form>
</div>
</div>
</div>
</div>
<!-- offcanvas search form end -->
<!-- Scroll to top start -->
<div class="scroll-top not-visible">
<i class="fa fa-angle-up"></i>
</div>
<script type="text/javascript">
$(document).ready(function(){
$(".headerCart").load("/flower/headerCart");
});
</script>
<!-- vue -->
<script type="text/javascript">
const vue = new Vue({
el:'#shop',
data:{
flowerList:[],
current_page: 1, //当前页
pages: 0, //总页数
size: 6 //每页个数
},
methods:{
jumpPage: function (id) {
this.current_page = id;
$.ajax({
url: "/flower/flowerList",
// data: null,
type: "POST",
data: {start: (vue.current_page - 1) * vue.size, size: vue.size},
dataType: "json",
success: function(data) {
vue.flowerList = data.flowerList;
}
});
scrollTo(0,0);
},
addToCart(id){
$.ajax({
url: "/flower/insertCartItem",
data: {userId: window.localStorage.getItem("userId"), flowerId: id},
type: "POST",
dataType: "json",
success: function(data) {
window.location.href="/flower/cart"
}
});
}
},
computed: {
// ...是否禁用上一页
show: function () {
return this.pages && this.pages != 1
},
// 开始
starts: function () {
return this.current_page == 1;
},
ends: function () {
return this.current_page == this.pages;
},
// ...
efont: function () {
if (this.pages <= 7) return false;
return this.current_page > 5
},
// 是否大于7
ebehind: function () {
if (this.pages <= 7) return false;
var nowAy = this.indexs;
return nowAy[nowAy.length - 1] != this.pages;
},
indexs: function () {
var left = 1,
right = this.pages,
ar = [];
if (this.pages >= 7) {
if (this.current_page > 5 && this.current_page < this.pages - 4) {
left = Number(this.current_page) - 2;
right = Number(this.current_page) + 2;
} else {
if (this.current_page <= 5) {
left = 1;
right = 7;
} else {
right = this.pages;
left = this.pages - 6;
}
}
}
while (left <= right) {
ar.push(left);
left++;
}
return ar;
},
},
watch:{
current_page(){
this.jumpPage(this.current_page);
}
},
created(){
let that = this;
$.ajax({
url: "/flower/flowerList",
data: {start: 0, size: this.size},
type: "POST",
dataType: "json",
success: function(data) {
vue.flowerList = data.flowerList;
vue.pages = data.total / vue.size;
}
})
}
})
</script>
<!--All Vendor Js -->
<script src="assets/js/vendor.js"></script>
</div>
</body>
</html>