基于springboot高校闲置物品交易系统微信小程序源码和论文

本系统是一款基于SpringBoot的二手物品交易应用,支持微信小程序端操作,包括商品发布、购买及在线交流等功能。

基于springboot二手物品交易系统微信小程序

  互联网的兴起从本质上改变了整个社会的商品交易方式,国内各大企业从上个世纪 90 年代互联网兴起之时,就产生了通过网络进行销售经营商品的想法。但是由于在互网上企业的信誉难以认证、网络的法规政策不健全、物流不发达等一系列的原因,限制 了网上交易发展的步伐。进入 21 世纪以后,随着整个社会的发展、进步,制约网上交易的各个瓶颈问题逐一被击破,各企业也纷纷的加入到电子商务的洪潮之中。 根据会员企业艾瑞咨询集团的预测,2008年我国网络购物交易将同比增长125.1%, 交易总量将达 1263 亿,形成了中国网络购物的快速增长浪潮 据 CNNIC, 2012 年中国网络购物市场研究发现,近 50%的中国网购用户每周至少网 购一次,网购频率领先于全球平均水平。业界领先的网络效果营销公司爱点击 iClick 今年 8 月重磅发布了《2013 中国网络 购物市场分析报告》,该报告指出 2012 年中国网购用户人均年消费金额达人民币 5,203 元,同比增长 25%,不仅与美国的差距正逐年缩小,并预计于 2015 年超过美国成为全球 第一。对任何品牌商和零售商而言,谁先了解中国网购用户需求,率先在中国网购市场下 手,谁就拥有了胜算。中国互联网协会网络营销工作委员会调查显示,随着国内产业环 境和消费市场的成熟,网络购物将在今年实现更大发展。
  根据以上的各种数据可以看出,网购已经渐渐成为人们的一种生活习惯,甚至已经
发展成人们生活中不可或缺的一部分。网络购物这一消费方式给人们生活带来的变化,
除了购物场所的改变以外,更重要的是大大改变了传统的消费行为习惯,无论是否在网
上购物,上网查看产品的相关信息,已经成为购物决策环节的重要组成部分,这一环节
对购物行为的实际发生起到了至关重要的指导作用。   

演示视频:

【java毕业设计】基于springboot高校闲置物品交易系统微信小程序java二手商城小程序

 

 

 

随着经济的不断发展,随着人们生活水平的不断提高,每天都产生大量的旧的、闲
置的生活用品、学习用品、数码产品以及各种户外用品等。此校园二手交易网站,就是
为了让这些闲置物品得到更有效的利用,为欲售商品者节省了摆摊所需要的时间,为欲
售商品而填小广告者扩展了信息量,为拥有小量商品用户提供了平台。同时,也响应了
党的十八大提出的“低碳节能”生活。

 

 

package com.oyhp.esyu.web;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.oyhp.esyu.pojo.*;
import com.oyhp.esyu.service.*;
import com.oyhp.esyu.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@RestController
public class DiscussController {
    @Autowired
    OrderItemService orderItemService;
    @Autowired
    DiscussService discussService;
    @Autowired
    DiscussItemService discussItemService;
    @Autowired
    OrderService orderService;
    @Autowired
    UserService userService;

    /**创建聊天窗口*/
    @PutMapping("/wx/discuss/create/{oid}")
    public Object onCreate(@PathVariable("oid")int oid,@RequestBody String type){
        System.out.println("type-"+type);
        JSONObject typeObj = JSONUtil.parseObj(type);
        //根据订单id获取订单项
        OrderItem orderItem = orderItemService.getByOrderId(oid);
        Discuss discuss = new Discuss();
        //买家、卖家、订单号、类型
        discuss.setBuser(orderItem.getUser());
        discuss.setSuser(orderItem.getProduct().getUser());
        discuss.setOrder(orderItem.getOrder());
        discuss.setType((String) typeObj.get("type"));
        //创建聊天窗口
        discussService.add(discuss);
        System.out.println(orderItem);

        return Result.success(discuss.getId());
    }
    /**添加聊天项*/
    @GetMapping("/wx/discuss/{id}/user/{uid}")
    public Object addDiscussItem(@PathVariable("id")int id, @PathVariable("uid")int uid,
                                 @RequestParam("content")String content){
        User user = userService.getById(uid);
        Discuss discuss = discussService.get(id);

        DiscussItem discussItem = new DiscussItem();
        discussItem.setDiscuss(discuss);
        discussItem.setContent(content);
        discussItem.setCreateDate(new Date());
        discussItem.setUser(user);

        discussItemService.add(discussItem);
        return Result.success("发送成功");
    }
    /**根据窗口id获取聊天窗口*/
    @GetMapping("/wx/discuss/{id}")
    public Object getDiscuss(@PathVariable("id")int id){
        Discuss discuss = discussService.get(id);
        //填充订单的订单项 -- 考虑要不要
        orderItemService.wxFill(discuss.getOrder());
        orderService.removeOrderFromOrderItem(discuss.getOrder());

        List<DiscussItem> discussItems = discussItemService.listByDiscuss(discuss);
        for (DiscussItem discussItem: discussItems) {
            discussItem.setDiscuss(null);
        }
        discuss.setDiscussItemList(discussItems);

        return Result.success(discuss);
    }
    /**
     * 判断是否存在聊天窗口
     */
    @GetMapping("/wx/discuss/order/{oid}/buser/{buid}/suser/{suid}")
    public Object isHasDicuss(@PathVariable("oid")int oid,
                                                    @PathVariable("buid")int buid,
                                                    @PathVariable("suid")int suid){
        Order order = orderService.get(oid);
        User buser = userService.getById(buid);
        User suser = userService.getById(suid);
        Discuss discuss = discussService.getDiscussByOrderAndBuserAndSuser(order,buser,suser);
        //不存在聊天项
        if(discuss == null){
            return Result.fail("不存在聊天窗");
        }else{
            return Result.success(discuss);
        }
    }
    /**获取用户的聊天窗口和系统信息*/
    @GetMapping("/wx/discuss/user/{uid}")
    public Object getDiscussByUser(@PathVariable("uid")int uid){
        User user = userService.getById(uid);
        //聊天信息
        List<Discuss> discusses = discussService.listByUser(user);
        //系统信息
        Discuss systemDiscuss = discussService.get(1);
        List<DiscussItem> systemNews = discussItemService.listByDiscuss(systemDiscuss);
        for (DiscussItem d:systemNews) {
            d.setDiscuss(null);
        }
        //填充聊天窗中聊天项
        discussItemService.fill(discusses);
        //移除聊天项中的聊天
        discussItemService.removeDiscussFromDiscussItems(discusses);
        //产品名称和交易方式
        ArrayList<String> productName = new ArrayList<>();
//        ArrayList<String> tradeWays = new ArrayList<>();
        for (Discuss d:discusses) {
            orderItemService.wxFill(d.getOrder());
            orderService.removeOrderFromOrderItem(d.getOrder());
            productName.add(d.getOrder().getOrderItems().get(0).getProduct().getName());
//            tradeWays.add(d.getOrder().getTradeWay());
        }
        //移除discuss中的order
        discussService.removeOrderFromDiscuss(discusses);

        HashMap<Object,Object> maps = new HashMap<>();
        maps.put("discusses",discusses);
        maps.put("productName",productName);
        maps.put("systemNews",systemNews);
//        maps.put("tradeWays",tradeWays);
        return Result.success(maps);
    }
}

 

 

 

MySql 是一个关系型数据库管理系统,使用 C 和 C++编写,并使用了多种编译器进
行测试,保证源代码的可移植性;支持
AIX、FreeBSD、HP-UX、Linux、Mac OS 、
NovellNetware、OpenBSD、OS/2 Wrap、Solaris、Windows 等多种操作系统;为多种编
程语言提供了 API;支持多线程,充分利用 CPU 资源;提供 TCP/IP、ODBC 和 JDBC 等多
种数据库连接途径;可以处理拥有上千万条记录的大型数据库。对于一般的个人使用者
和中小型企业来说,MySql 提供的功能已经绰绰有余,而且由于 MySql 是开放源码软件,
因此可以大大降低总体拥有成本。
package com.oyhp.esyu.web;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import com.oyhp.esyu.pojo.Product;
import com.oyhp.esyu.pojo.ProductImage;
import com.oyhp.esyu.service.CategoryService;
import com.oyhp.esyu.service.ProductImageService;
import com.oyhp.esyu.service.ProductService;
import com.oyhp.esyu.util.ImageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
  
@RestController
public class ProductImageController {
    @Autowired
    ProductService productService;
    @Autowired
    ProductImageService productImageService;
    @Autowired
    CategoryService categoryService;

    /**
     * 1. 首先访问路径,admin_productImage_list?pid=2, 通过AdminPageController 中的映射,返回 listProductImage.html
     * 2. 在listProductImage.html 加载后就获取了参数上的 pid
     * 3. 然后自动调用 listSingles 函数
     * 4. listSingles 函数用过 axios.js 调用 products/2/productImages?type=single 这个地址
     * 5. 步骤4的地址,导致 ProductImageController 的 list 方法被调用
     * 6. list 方法里根据参数调用 ProductService的 listSingleProductImages 方法,返回当前产品的单个图片集合
     * 7. 这个图片集合返回 json数组
     * 8. axios拿到这个json数组就放在 vue的singleProductImages对象上
     * 9. vue 把 singleProductImages 通过v-for 遍历在视图上
     * 以上就是单个图片的查询,详情图片的查询同理可得就是参数不一样。
     */
    @GetMapping("/products/{pid}/productImages")
    public List<ProductImage> list(@RequestParam("type") String type, @PathVariable("pid") int pid) throws Exception {
        Product product = productService.get(pid);
 
        if(ProductImageService.type_single.equals(type)) {
            List<ProductImage> singles =  productImageService.listSingleProductImages(product);
            return singles;
        }
        else if(ProductImageService.type_detail.equals(type)) {
            List<ProductImage> details =  productImageService.listDetailProductImages(product);
            return details;
        }
        else {
            return new ArrayList<>();
        }
    }

    /**
     * 增加产品图片分单个和详情两种,其区别在于增加所提交的type类型不一样。
     * 这里就对单个的进行讲解,详情图片的处理同理。
     * 1. 选中图片后,会导致 getSingleFile 函数被调用,vue就拿到了文件
     * 2. 点击提交按钮会导致addSingle函数被调用
     * 3. 与分类上传图片类似, axios,js 上传图片要用 FormData 的方式
     * 4. 上传到路径 productImages,并带上type和pid参数
     * 5. ProductImageController 的add方法被调用
     * 6. 首先根据pid 和 type 创建 ProductImage 对象,并插入数据库
     * 7. 然后根据类型指定保存文件的路径:productSingle
     * 8. 接着根据产品图片对象的id,作为文件名,把图片保存到对应的位置
     * 9. 像分类上传图片一样,要通过 ImageUtil.change2jpg进行类型强制转换,以确保一定是jpg图片
     * 10. 如果是单个图片,还要创建 small 和 middle 两种不同大小的图片,用的是 ImageUtil.resizeImage 函数
     * 以上就是单个图片的处理。
     */
    @PostMapping("/productImages")
    public Object add(@RequestParam("pid") int pid, @RequestParam("type") String type, MultipartFile image, HttpServletRequest request) throws Exception {
        ProductImage bean = new ProductImage();
        Product product = productService.get(pid);
        bean.setProduct(product);
        bean.setType(type);
         
        productImageService.add(bean);
        String folder = "img/";
        if(ProductImageService.type_single.equals(bean.getType())){
            folder +="productSingle";
        }
        else{
            folder +="productDetail";
        }
        File  imageFolder= new File(request.getServletContext().getRealPath(folder));
        File file = new File(imageFolder,bean.getId()+".jpg");
        String fileName = file.getName();
        if(!file.getParentFile().exists())
            file.getParentFile().mkdirs();
        try {
            image.transferTo(file);
            BufferedImage img = ImageUtil.change2jpg(file);
            ImageIO.write(img, "jpg", file);           
        } catch (IOException e) {
            e.printStackTrace();
        }
         
        if(ProductImageService.type_single.equals(bean.getType())){
            String imageFolder_small= request.getServletContext().getRealPath("img/productSingle_small");
            String imageFolder_middle= request.getServletContext().getRealPath("img/productSingle_middle");    
            File f_small = new File(imageFolder_small, fileName);
            File f_middle = new File(imageFolder_middle, fileName);
            f_small.getParentFile().mkdirs();
            f_middle.getParentFile().mkdirs();
            ImageUtil.resizeImage(file, 56, 56, f_small);
            ImageUtil.resizeImage(file, 217, 190, f_middle);
        }      
         
        return bean;
    }

    /**
     * 1. 点击删除超链
     * 2. vue 上的 deleteBean 函数被调用,访问 productImages/id 路径
     * 3. ProductImageController的delete方法被调用
     * 4. 根据id获取ProductImage 对象
     * 5. 借助productImageService,删除数据
     * 6. 如果是单个图片,那么删除3张正常,中等,小号图片
     * 7. 如果是详情图片,那么删除一张图片
     */
    @DeleteMapping("/productImages/{id}")
    public String delete(@PathVariable("id") int id, HttpServletRequest request)  throws Exception {
        ProductImage bean = productImageService.get(id);
        productImageService.delete(id);
 
        String folder = "img/";
        if(ProductImageService.type_single.equals(bean.getType()))
            folder +="productSingle";
        else
            folder +="productDetail";
 
        File  imageFolder= new File(request.getServletContext().getRealPath(folder));
        File file = new File(imageFolder,bean.getId()+".jpg");
        String fileName = file.getName();
        file.delete();
        if(ProductImageService.type_single.equals(bean.getType())){
            String imageFolder_small= request.getServletContext().getRealPath("img/productSingle_small");
            String imageFolder_middle= request.getServletContext().getRealPath("img/productSingle_middle");
            File f_small = new File(imageFolder_small, fileName);
            File f_middle = new File(imageFolder_middle, fileName);
            f_small.delete();
            f_middle.delete();
        }
 
        return null;
    }
     
}

 

 

 

 

package com.oyhp.esyu.web;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.oyhp.esyu.comparator.*;
import com.oyhp.esyu.pojo.*;
import com.oyhp.esyu.quartz.manager.QuartzJobManager;
import com.oyhp.esyu.quartz.service.QuartzJobService;
import com.oyhp.esyu.service.*;
import com.oyhp.esyu.util.Result;
import com.oyhp.esyu.util.WXProduct;
import com.oyhp.esyu.util.WXUtil;
import org.apache.commons.lang.math.RandomUtils;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 微信小程序控制器
 */
@RestController
public class WXForeController {
    @Autowired
    UserService userService;
    @Autowired
    SchoolService schoolService;
    @Autowired
    ThemeService themeService;
    @Autowired
    CategoryService categoryService;
    @Autowired
    ProductService productService;
    @Autowired
    ProductImageService productImageService;
    @Autowired
    ReviewService reviewService;
    @Autowired
    PropertyValueService propertyValueService;
    @Autowired
    PropertyService propertyService;
    @Autowired
    AddressService addressService;
    @Autowired
    OrderItemService orderItemService;
    @Autowired
    OrderService orderService;
    @Autowired
    SecondaryCategoryService secondaryCategoryService;
    @Autowired
    EvaluationService evaluationService;
    @Resource
    private QuartzJobService quartzJobService;

    /**
     * 微信小程序登录
     * 需要判断用户是否是新用户,根据用户的openid去查是否有这个用户
     * 1、有,不做任何动作
     * 2、没有,新建用户
     * @param userInfo  用户信息,微信传过来的code country province name gender city
     * @return 登录成功,返回openid
     */
    @PostMapping("/wxlogin")
    public Object wx_login(@RequestBody User userInfo,HttpServletRequest request){
        Map<String,Object> userKeyMap =  WXUtil.getOpenidSessionKeyAndToken(userInfo.getCode());
        String openid = (String)userKeyMap.get("openid");
        //获取了openid保存到userInfo中
        userInfo.setOpenid(openid);
        System.out.println(userInfo);
        //判断拿到数据是否正确
        if(openid==null)
            return Result.fail("error");
        //微信小程序用户是否为第一次登录
        if(userService.isLoginFirst(userInfo)){
            //随便设置一下院校,默认城市学院
            School school = schoolService.get(1);
            userInfo.setSchool(school);
            userInfo.setCreateDate(new Date());
            userInfo.setUpdateDate(new Date());
            userService.add(userInfo);
            //保存用户头像到服务器,以后不再保存到数据库
            String localUrl = request.getServletContext().getRealPath("img/user/")+userInfo.getId()+".jpg";
            WXUtil.downloadPicture(userInfo.getAvatarUrl(),localUrl);
        }
        //返回openid要求小程序端加入到缓存,用户小程序的其它业务,比如发布
        return Result.success(openid);
    }

    /**
     * 根据openid获取User信息
     * @param user
     * @return
     */
    @PostMapping("/wxUser")
    public Object wx_user(@RequestBody User user){
        String openid = user.getOpenid();
        //判断openid是否有效
        if(openid != null){
            User my = userService.getUserByOpenid(openid);
            //在售商品
            my.setOnSellProduct(productService.onSellProduct(my));
            //累计交易,我卖出的
            List<Product> products = productService.getProductsByUser(my);
            my.setOnOrderProduct(orderItemService.onOrderTraded(products));
            //我买到的
            my.setOnMyBought(orderService.OnOrderProduct(my));

            return Result.success(my);
        }
        else
            return Result.fail("用户未登录");
    }
    /**
     * 获取Token访问
     * @return
     */
    @GetMapping("wxAccessToken")
    public Object getAccessToken(){
        return Result.success(WXUtil.getAccessToken());
    }
    /**
     * wx小程序首页
     * 7个分类,一个全部
     * 所有分类下的产品
     */
    @GetMapping("/wx/home")
    public Object home(School school){
        /**
         * 1、获取所有一级分类
         * 2、填充一级分类中的所有产品
         * 4、移除产品中的分类,因为在fill(cs)中,根据分类查找产品,将product中的category属性填充
         * 导致json死循环,即category实例中有product,而product实例有category
         */
        List<Category> cs = categoryService.list();
        productService.wxFillBySchool(cs,school);
        categoryService.removeCategoryFromProduct(cs);
        categoryService.removeCategoryFromSC(cs);
        for (Category c: cs) {
            c.setSecondaryCategories(null);
        }
        return cs;
    }
    /**
     * 首页
     * 获取所有主题,并将产品放入到首页中
     */
    @GetMapping("/wx/themes")
    public Object wxThemes(School school){
        System.out.println(school);
        //获取所有主题
        List<Theme> themes = themeService.list();
        //设置主题中产品
        themeService.wxFill(themes,school);
        return themes;
    }
    /**
     * 1. 获取参数pid
     * 2. 根据pid获取Product 对象product
     * 3. 判断改产品是否下架或这库存不足 isOfflineOrLackStock
     * 4. 根据对象product,获取这个产品对应的详情图片集合
     * 5. 获取产品的所有属性值
     * 6. 获取产品对应的所有的评价
     * 8. 把上述取值放在 map 中
     * 9. 通过 Result 把这个 map 返回到浏览器去
     * 为什么要用Map呢? 因为返回出去的数据是多个集合,而非一个集合,所以通过 map返回给浏览器,浏览器更容易识别
     * @param pid
     * @return
     */
    @GetMapping("/wx/product/{pid}")
    public Object product(@PathVariable("pid") int pid) {
        Product product = productService.get(pid);
        //在售商品
        product.getUser().setOnSellProduct(productService.onSellProduct(product.getUser()));
        //累计交易,我卖出的
        List<Product> products = productService.getProductsByUser(product.getUser());
        product.getUser().setOnOrderProduct(orderItemService.onOrderTraded(products));
        //我买到的
//        product.getUser().setOnOrderProduct(orderService.OnOrderProduct(product.getUser()));

        List<ProductImage> productDetailImages = productImageService.listDetailProductImages(product);

        List<PropertyValue> pvs = propertyValueService.list(product);

        for (PropertyValue p:
             pvs) {
            p.setProduct(null);
        }
        Map<String,Object> map= new HashMap<>();
        map.put("onSellProduct",product.getUser().getOnSellProduct());
        map.put("onOrderProduct",product.getUser().getOnOrderProduct());
        map.put("productDetailImages", productDetailImages);
        map.put("pvs", pvs);
        map.put("isOfflineOrLackStock", productService.isOfflineOrLackStock(product));
        return Result.success(map);
    }

    /**
     * 商品搜索模糊查询
     * @param key 关键字
     * @return
     */
    @GetMapping("/wx/search")
    public Object search(@RequestParam("key") String key,
                         @RequestParam(name = "sort",defaultValue = "none")String sort){
        List<Product> products = productService.search(key,0,5);
        for (Product p: products) {
            p.setCategory(null);
            p.setSecondaryCategory(null);
        }
        productImageService.setWXFirstProductImages(products);
        //防止不支持异常
        products = new ArrayList<>(products);

        if(null!=sort){
            switch(sort){
                case "price":
                    Collections.sort(products,new ProductPriceComparator());
                    break;
            }
        }

        return Result.success(products);
    }
    /**
     * 预搜索
     */
    @PutMapping("/wx/preSearch")
    public Object preSearch(@RequestParam("key") String key){
        List<String> strings = new ArrayList<>();
        List<Product> products = productService.search(key,0,5);
        for (Product p: products) {
            strings.add(p.getName());
        }
        return strings;
    }
    /**
     * 首页中的全部分类
     * 获取所有分类
     * @return
     */
    @GetMapping("/wx/category/all")
    public Object getAllCategories(){
        List<Category> categories = categoryService.list();
        secondaryCategoryService.fill(categories);
        secondaryCategoryService.removeCategoryFromSecondCategory(categories);
        return Result.success(categories);
    }
    /**
     * 发布页面
     * 获取所有一级分类和所有主题
     */
    @GetMapping("/wx/categoriesAndThemes")
    public Object listCategory(){
        List<Category> categories = categoryService.list();
        List<Theme> themes = themeService.list();

        Map<String,Object> map = new HashMap<>();
        map.put("categories",categories);
        map.put("themes",themes);
        return Result.success(map);
    }
    /**
     * 筛选页面
     * 获取一级分类下的所有产品
     * 1. 获取参数cid
     * 2. 根据cid获取分类Category对象 c
     * 3. 为c填充二级分类和产品
     * 4. 为产品填充销量和评价数据
     * 5. 获取参数sort
     *  5.1 如果sort==null,即不排序
     *  5.2 如果sort!=null,则根据sort的值,从5个Comparator比较器中选择一个对应的排序器进行排序
     6. 返回对象 c
     */
    @GetMapping("/wx/secondaryCategory/{scid}")
    public Object category(@PathVariable("scid")int scid,School school,
                           @RequestParam(name = "sort",defaultValue = "none") String sort){
        //二级分类
        SecondaryCategory sc = secondaryCategoryService.get(scid);
        //填充二级级分类
        productService.wxFillSCBySchool(sc,school);
        secondaryCategoryService.removeSecondCategoryFromProduct(sc);
        productImageService.setWXFirstProductImages(sc.getProductList());

        if(null!=sort){
            switch(sort){
                case "review":
                    Collections.sort(sc.getProductList(),new ProductReviewComparator());
                    break;
                case "date" :
                    Collections.sort(sc.getProductList(),new ProductDateComparator());
                    break;
                case "saleCount" :
                    Collections.sort(sc.getProductList(),new ProductSaleCountComparator());
                    break;
                case "price":
                    Collections.sort(sc.getProductList(),new ProductPriceComparator());
                    break;
                case "all":
                    Collections.sort(sc.getProductList(),new ProductAllComparator());
                    break;
            }
        }

        return sc;
    }
    /**
     * 获取主题中的商品
     */
    @GetMapping("/wx/theme/{tid}/products")
    public Object wxProductByTheme(@PathVariable("tid")int tid,School school,
                                   @RequestParam(name = "sort",defaultValue = "none") String sort){
        Theme theme = themeService.get(tid);
        themeService.wxFill(theme,school);
        if(null!=sort){
            switch(sort){
                case "price":
                    Collections.sort(theme.getProducts(),new ProductPriceComparator());
                    break;
            }
        }
        return theme.getProducts();
    }
    /**
     * 发布页面
     * 根据分类id获取所有属性
     */
    @GetMapping("/wx/categories/{cid}/properties")
    public Object getPropertiesByCid(@PathVariable("cid")int cid){
        Category category = categoryService.get(cid);
        List<Property> properties = propertyService.listByCategory(category);
        /**防止浪费空间*/
        for (Property p: properties) {
            p.setCategory(null);
        }
        return properties;
    }
    /**
     * 发布产品-必须使用post传送而且要@RequestBody不然数组内容接受不正确
     * 1、openid用户、分类cid、内容content、imgs产品图片、price价格、pvs属性参数、title标题
     * 2、工具类创建了一个wxproduct,在赋值给product
     * 3、找到数据中最大的pid,是指pid
     * 注意对三个表同时操作要进行回滚 !!!还没有实现回滚
     * 4、发布产品
     * 5、设置产品属性值
     * 6、设置产品详细图片
     * 7、设置产品主题
     * */
    @Transactional(propagation= Propagation.REQUIRED,rollbackForClassName="Exception")
    @PostMapping("/wx/issueProduct/{scid}/theme/{tid}")
    public Object getProduct(@PathVariable("scid")int scid,
                             @RequestBody WXProduct wxproduct,
                             @PathVariable("tid")int tid){
        System.out.println(wxproduct);
        Product product = new Product();
        User u = userService.getUserByOpenid(wxproduct.getOpenid());
        SecondaryCategory secondaryCategory = secondaryCategoryService.get(scid);
        Category c = secondaryCategory.getCategory();
        /** 用户、分类、创建时间 */
        product.setUser(u);
        product.setCategory(c);
        product.setSecondaryCategory(secondaryCategory);
        product.setCreateDate(new Date());
        /** 库存 在线 标题、内容、原价、二手价、运费、属性值、图片集合 */
        product.setStock(1);
        product.setOnline("T");
        product.setName(wxproduct.getName());
        product.setSubTitle(wxproduct.getSubTitle());
        product.setPromotePrice(wxproduct.getPromotePrice());
        product.setOriginalPrice(wxproduct.getOriginalPrice());
        product.setCarriagePrice(wxproduct.getCarriagePrice());
        String[] pvs = wxproduct.getPvs();
        /**设置产品可以交易的方式*/
        String[] selects = wxproduct.getSelect();
        for (String s:selects) {
            if(s.equals("school"))
                product.setIsSchool("T");
            if(s.equals("change"))
                product.setIsChange("T");
            if(s.equals("express"))
                product.setIsExpress("T");
        }
        //发布产品
        productService.add(product);
        //添加主题产品表
        Theme theme = themeService.get(tid);
        ThemeProduct themeProduct = new ThemeProduct();
        themeProduct.setProduct(product);
        themeProduct.setTheme(theme);
        themeService.addThemeProduct(themeProduct);
//        System.out.println(product);                      //打印
        //初始化属性值,即写入属性值到数据库
        propertyValueService.init(product,pvs);

        return Result.success(product.getId());              //返回产品id,让前端继续上传图片
    }
    /**
     * pid 产品id、imgs用户上传的图片,有以下两种方案
     * 1、只要存储detail 2、两种都要存储比如single 这样就不会报错了 修改多一个WXFill了
     * 选择了方案一
     */
    @PostMapping("/wx/productImgs")
    public Object add(@RequestParam("pid") int pid, @RequestParam(value = "imgs") MultipartFile image,
                      HttpServletRequest request){
        ProductImage bean = new ProductImage();
        Product product = productService.get(pid);
        bean.setProduct(product);
        bean.setType("detail");             //锁定详细
        //添加图片
        productImageService.add(bean);
        //上传图片
        WXUtil.upFile(bean.getId(),"productDetail",image,request);

        return Result.success("图片上传成功");
    }
    /**
     * 商品库存是否足够,是否下架?true继续,否则错误
     * order订单生成
     * pid:产品id, uid:用户id,address:收货地址,post:邮政编号,receiver:收货人,mobile:移动电话, number:1 数量
     * 订单项生成(id,uid,oid,pid,number)
     * 定时任务: 10分钟未支付取消订单
     */
    @PutMapping("/wx/order/{pid}")
    public Object createWxOrder(@PathVariable("pid")int pid,@RequestParam(value = "uid")String uid,@RequestBody Order order){
        User user = userService.getById(Integer.parseInt(uid));
        Product product = productService.get(pid);
        //用户是否登录
        if(null == user)
            return Result.fail("未登录");
        //商品未下架且库存>0
        if(!(product.getOnline().equals("T") && (product.getStock()>0))){
            return Result.fail("无效商品");
        }
        //商品库存-1
        product.setStock(product.getStock() - 1);
        productService.update(product);

        //先创建订单项
        OrderItem oi = new OrderItem();
        oi.setUser(user);
        oi.setProduct(product);
        oi.setNumber(1);
        orderItemService.add(oi);

        //后生成订单
        String orderCode = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + RandomUtils.nextInt(10000);
        order.setOrderCode(orderCode);
        order.setCreateDate(new Date());
        order.setUser(user);
        order.setStatus(OrderService.waitPay);
        //设置订单项中的订单 这里价格没有用到
        orderService.wxAdd(order,oi);

        //设置订单定时任务
        JobKey jobKey = JobKey.jobKey(String.valueOf(order.getId()),"waitPayOrder");
        String desc = "待支付订单,超过十分钟取消订单";
        Map<String,String> jobMap = new HashMap<>();
        jobMap.put("oid",String.valueOf(order.getId()));
        jobMap.put("pid",String.valueOf(product.getId()));
        jobMap.put("status","waitPayOrder");
        try {
            QuartzJobManager.startQuartzJob(quartzJobService,jobKey,jobMap,desc);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        //返回数据
        Map<String,Object> map = new HashMap<>();
        map.put("oid", order.getId());
        map.put("orderCode",order.getOrderCode());
        map.put("tradeWay",order.getTradeWay());
        map.put("total", order.getTotalPrice());
        return Result.success(map);
    }
    /**
     * 获取订单详细信息
     */
    @GetMapping("/wx/order/{oid}/orderDetail")
    public Object onOrderDetail(@PathVariable("oid") int oid){
        Order order = orderService.get(oid);
        //填充order
        orderItemService.wxFill(order);
        orderService.removeOrderFromOrderItem(order);
        return Result.success(order);
    }
    /**
     * 立即支付
     * 1 获取参数oid
     * 2 根据oid获取到订单对象order
     * 3 修改订单对象的状态和支付时间
     * 4 取消待支付订单计时
     * 5 更新这个订单对象到数据库
     * 6 返回订单
     */
    @PutMapping("/wx/payed/{oid}")
    public Object payed(@PathVariable("oid") int oid) {
        Order order = orderService.get(oid);
        //买家账号
        User user = order.getUser();
        //余额不足
        if(user.getMoney() < Float.parseFloat(order.getTotalPrice())){
            return Result.fail("余额不足");
        }
        //扣除买家金额
        user.setMoney(user.getMoney() - Float.parseFloat(order.getTotalPrice()));
        //更新用户账号
        userService.update(user);
        //取消待支付定时10分钟
        JobKey jobKey = JobKey.jobKey(String.valueOf(order.getId()),"waitPayOrder");
        try {
            QuartzJobManager.pauseQuartzJob(quartzJobService,jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

        order.setStatus(OrderService.waitDelivery);
        order.setPayDate(new Date());
        //更新订单
        orderService.update(order);
        return Result.success("支付成功");
    }
    /**
     * 确认发货
     * 1 获取参数oid
     * 2 根据oid获取到订单对象order
     * 3 修改订单对象的状态和发货时间
     * 4 更新这个订单对象到数据库
     * 5 返回订单
     */
    @GetMapping("/wx/delivery/{oid}")
    public Object waitDelivery(@PathVariable("oid") int oid){
        Order order = orderService.get(oid);
        System.out.println(order);
        order.setStatus(OrderService.waitConfirm);
        order.setDeliveryDate(new Date());
        orderService.update(order);
        return Result.success("发货成功");
    }
    /**
     * 确认收货
     * 1 获取参数oid
     * 2 根据oid获取到订单对象order
     * 3 修改订单对象的状态和收货时间
     * 4 更新卖家账号金额
     * 5 更新这个订单对象到数据库
     * 6 返回订单
     */
    @GetMapping("/wx/receive/{oid}")
    public Object waitConfirmReceive(@PathVariable("oid") int oid){
        Order order = orderService.get(oid);
        System.out.println(order);
        //找到卖家,更新账户
        OrderItem orderItem = orderItemService.getByOrderId(order.getId());
        Product product = orderItem.getProduct();
        User user = product.getUser();
        user.setMoney(user.getMoney() + Float.parseFloat(order.getTotalPrice()));
        userService.update(user);

        order.setStatus(OrderService.waitReview);
        order.setConfirmDate(new Date());
        orderService.update(order);
        return Result.success("收货成功");
    }
    /**获取order订单*/
    @GetMapping("/wx/getOrder/{oid}")
    public Object getOrder(@PathVariable("oid") int oid){
        Order order = orderService.get(oid);
        orderItemService.wxFill(order);
        orderService.removeOrderFromOrderItem(order);
        order.setUser(null);
        return Result.success(order);
    }
    /**
     * 获取全部我的订单  微信小程序我买到的
     * 1、订单里面的uid是下单者的(我),并不是商家uid,应该用product中的uid
     * 1. 通过openid获取用户user
     * 2. 查询user所有的状态不是"delete" 的订单集合os
     * 3. 为这些订单填充订单项
     * 4. 返回 订单集合
     */
    @GetMapping("/wx/order/bought")
    public Object bought(@RequestParam(value = "openid")String openid) {
        User user = userService.getUserByOpenid(openid);
        System.out.println(user);
        if(null==user)
            return Result.fail("未登录");
        //微信小程序的获取,由于图片问题没有处理好
        List<Order> os= orderService.wxListByUserWithoutDelete(user);
        orderService.removeOrderFromOrderItem(os);
        return os;
    }
    /**
     * 微信小程序我卖出
     * 1. 通过openid获取用户user
     * 2. 通过user查找到我发布的产品Product
     * 3. 通过我发布的产品找到对应的orderItem
     * 4. 返回 订单项orderItems集合
     */
    @GetMapping("/wx/order/sell")
    public Object mySell(@RequestParam(value = "openid")String openid){
        User user = userService.getUserByOpenid(openid);
        List<Product> products = productService.getProductsByUser(user);
        for(Product p : products){
            //设置为空,防止数据冗余
            p.setCategory(null);
//            System.out.println(p);
        }
        List<List<OrderItem>> listOrderItems = orderItemService.listByProduct(products);
        List<OrderItem> goalOrderItems = new ArrayList<>();
        for (List<OrderItem> orderItems: listOrderItems) {
            for (OrderItem oi: orderItems) {
                goalOrderItems.add(oi);
            }
        }
        //设置第一张图片
        productImageService.setWXFirstProductImages(products);
        return Result.success(goalOrderItems);
    }

    /**
     * 我发布的
     * @param openid
     * @return 产品
     */
    @GetMapping("/wx/order/release")
    public Object myRelease(@RequestParam(value = "openid")String openid){
        User user = userService.getUserByOpenid(openid);
        List<Product> products = productService.getProductsByUser(user);

        for (Product p: products) {
            //设置为空,防止数据冗余
            p.setCategory(null);
            p.setSecondaryCategory(null);
        }
        //设置第一张图片
        productImageService.setWXFirstProductImages(products);
        //设置详细图片
        return Result.success(products);
    }
    /**
     * 下架商品
     * 该商品是否处于交易中,是下架失败,否下架成功
     */
    @PutMapping("/wx/my/product/{pid}/offline")
    public Object offline(@PathVariable("pid") int pid){
        Product product = productService.get(pid);
        boolean isTrading = productService.isTrading(product);
        if(isTrading){
            return Result.fail("无法下架,商品正处于交易");
        }
        product.setOnline("F");
        productService.update(product);
        return Result.success();
    }
    /**
     * 重新上架商品
     * 该商品是否处于交易中,是下架失败,否下架成功
     */
    @PutMapping("/wx/my/product/{pid}/reOnline")
    public Object reOnline(@PathVariable("pid") int pid){
        Product product = productService.get(pid);
        product.setOnline("T");
        productService.update(product);
        return Result.success();
    }
    /**
     * 取消订单-买家
     */
    @GetMapping("/wx/order/{id}/cancel")
    public Object orderCancel(@PathVariable("id") int id){
        Order order = orderService.get(id);
        order.setStatus("waitCancel");
        //更新订单
        orderService.update(order);
        return Result.success("待卖家同意");
    }
    /**
     * 同意取消-卖家
     */
    @GetMapping("/wx/order/{id}/agreeCancel/{pid}")
    public Object agreeOrderCancel(@PathVariable("id") int id,@PathVariable("pid") int pid){
        Order order = orderService.get(id);
        User user = order.getUser();
        Product product = productService.get(pid);
        //更新订单
        order.setStatus("cancel");
        order.setCancelDate(new Date());
        //更新库存+1 买家金额退还
        product.setStock(product.getStock()+1);
        user.setMoney(user.getMoney() + Float.parseFloat(order.getTotalPrice()));

        userService.update(user);
        orderService.update(order);
        productService.update(product);

        return Result.success("同意取消");
    }
    /**
     * 拒绝取消-卖家
     * 少了确认收货后
     */
    @GetMapping("/wx/order/{id}/refuseCancel")
    public Object refuseOrderCancel(@PathVariable("id")int id){
        Order order = orderService.get(id);
        if(order.getPayDate() == null)
            order.setStatus("waitPay");
        else if(order.getDeliveryDate() == null)
            order.setStatus("waitDelivery");
        else if(order.getConfirmDate() == null)
            order.setStatus("waitConfirm");
        else
            return Result.success("拒绝失败");

        orderService.update(order);
        return Result.success("拒绝取消");
    }
    /**
     * 充值recharge 提现 withdraw
     */
    @PutMapping("/wx/my/{id}/wallet")
    public Object rechargeOrWithdraw(@PathVariable("id")int id,@RequestBody String data){
        JSONObject wallet = JSONUtil.parseObj(data);
        User user = userService.getById(id);
        float charge = Float.parseFloat((String)wallet.get("charge"));
        String type = (String) wallet.get("type");
        if(type.equals("recharge")){
            user.setMoney(user.getMoney() + charge);
        }else if(type.equals("withdraw")){
            user.setMoney(user.getMoney() - charge);
        }
        //更新钱包
        userService.update(user);

        return Result.success(user);
    }
    /**
     * 卖家在订单中修改收货地址
     */
    @PutMapping("/wx/order/{id}/updateOrderAddress")
    public Object updateOrderAddress(@PathVariable("id")int id,@RequestBody String address){
        JSONObject addrObj = JSONUtil.parseObj(address);
        String addr = (String)addrObj.get("address");
        //更新订单收货地址
        Order order = orderService.get(id);
        order.setAddress(addr);
        orderService.update(order);

        return Result.success();
    }
    /**
     * 订单评价
     */
    @PostMapping("/wx/orderItem/{id}/evaluation")
    public void orderItemEvaluation(@PathVariable("id")int id,@RequestBody String result){
        JSONObject resultObj = JSONUtil.parseObj(result);
        String content = (String) resultObj.get("content");
        int score = (int) resultObj.get("score");
        if(content.equals("")){
            content = "此用户没有填写评价";
        }
        //订单项
        OrderItem orderItem = orderItemService.get(id);
        Order order = orderItem.getOrder();
        //订单评价
        EvaluationOrder evaluationOrder = new EvaluationOrder();
        evaluationOrder.setContent(content);
        evaluationOrder.setScore(score);
        evaluationOrder.setCreateDate(new Date());
        evaluationOrder.setOrderItem(orderItem);
        //添加评价
        evaluationService.add(evaluationOrder);
        //修改订单状态
        order.setStatus("finish");
        orderService.update(order);

    }
    /**
     * 查看评价
     */
    @GetMapping("/wx/orderItem/{id}/evaluation")
    public Object getEvaluationByOrderItem(@PathVariable("id")int id){
        EvaluationOrder evaluationOrder = evaluationService.getByOrderItem_Id(id);
        evaluationOrder.getOrderItem().setOrder(null);
        //设置商品图片
        productImageService.setWXFirstProductImage(evaluationOrder.getOrderItem().getProduct());
        return Result.success(evaluationOrder);
    }
}
本系统所用的软件都是开源的,为开发软件节省了大量的金钱和时间,达到降低成
本,提高开发效率的目的,本系统对计算机配置的要求不高,甚至网吧更换下来的低配
置电脑都可以完全满足需要,所以在经济上具有完全的可行性。
2.1.3 操作可行性
本系统操作简单,输入信息页面大多数都是下拉框的选择形式,在某些页面,信息
可以自动生成,无需输入,时间的输入也是用的日历控件,操作简便,对操作人员的要
求很低,只需对 WINDOWS 操作熟练,加之对本系统的操作稍加培训即可工作,而且本系
统可视性非常好,所以在技术上不会有很大难度。
2.1.4 法律的可行性
本校园二手物品交易网是自行开发的管理系统,是很有实际意义的系统 ,开发环境
软件和使用的数据库都是开源代码,开发这个系统不同于开发普通的系统软件,不存在
侵权等问题,即法律上是可行的。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿毕业分享网

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值