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

news2024/11/25 20:31:43

基于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 法律的可行性
本校园二手物品交易网是自行开发的管理系统,是很有实际意义的系统 ,开发环境
软件和使用的数据库都是开源代码,开发这个系统不同于开发普通的系统软件,不存在
侵权等问题,即法律上是可行的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/86441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文阅读|Embedding-based Retrieval in Facebook Search

该论文是facebook发表在KDD2020上的一篇关于搜索召回的paper。这篇文章提到的大多trick对于做过召回的同学比较熟悉了&#xff0c;可贵之处在于全面&#xff0c;包括了特征、样本、模型、全链路等各种细节知识。 1. 整体思路与框架 本文的出发点是搜索只做到query关键词匹配的…

电压放大器在农田灌溉管道缺陷检测研究中的应用

实验名称&#xff1a;电压放大器在农田灌溉管道缺陷检测研究中的应用 研究方向&#xff1a;管道检测、超声波检测 图&#xff1a;管道示意图 测试目的&#xff1a; 超声导波检测构件时&#xff0c;先激励导波使其在构件中传播&#xff0c;导波遇到构件中不连续处或有缺陷的地方…

Linux部署Tomcat和Nginx

目录一、Linux相关软件安装1. 安装gcc编译器2. 安装文件上传3. 安装wget4. 安装vim二、安装jdk和Apache-Tomcat1. 上传jdk和Apache-Tomcat2. 配置环境变量3. 测试&#xff08;1&#xff09;测试jdk&#xff08;2&#xff09;测试Apache-Tomcat三、安装Nginx1. 下载Nginx包2. 配…

哪路神仙写的421页MySQL高级笔记,涵盖MySQL所有技术!太香了

第2章MySQL权限与安全 对于企业而言&#xff0c;数据库中保存的企业业务数据是非常重要的信息&#xff0c;尤其是互联网企业&#xff0c;数据库中的用户信息是企业的根本资源。MySQL数据库管理系统的安全性涉及方方面面&#xff0c;不仅和操作系统本身有很大的关系&#xff0c;…

KD 树原理详解

一 点睛 KD 树&#xff08;K-Dimension tree&#xff09;是可以存储 K 维数据的树&#xff0c;是二叉搜索树的拓展&#xff0c;主要用于多维空间数据的搜索&#xff0c;例如范围搜索和最近邻搜索。BST、AVL、Treap 和伸展树等二叉搜索树的节点存储的都是一维信息&#xff0c;一…

上美股份在港交所开启招股:业绩将继续下滑,吕义雄提前大额套现

12月12日&#xff0c;上海上美化妆品股份有限公司&#xff08;HK:02145&#xff0c;下称“上美股份”&#xff09;在港交所开启招股。根据公告&#xff0c;上美股份本次拟全球发售3695.8万股&#xff0c;发售价将为每股发售股份25.20-29.80港元&#xff0c;预期将于2022年12月2…

基于二阶锥规划的主动配电网最优潮流求解(Matlab代码实现)

&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&#xff1a;行百里者&#xff0c;半于九十。 &#x1f4cb;&#x1f4cb;&#x1f4cb;本文目录如下&#xff…

豪横卡塔尔!疯狂世界杯

豪横卡塔尔&#xff01;疯狂世界杯1.Big Data -- Postgres1.1 Big Data -- Postgres2.Big Data -- Postgres3.Big Data -- Postgres1.Big Data – Postgres 这届世界杯是有史以来最贵的一次世界杯&#xff0c;因为这次世界杯卡塔尔就花了2200多亿美元&#xff0c;可以说自世界杯…

[附源码]Node.js计算机毕业设计电影网上购票系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

【Python金融量化】零基础如何开始学?

前言 Python可以说是当前非常流行的编程语言&#xff0c;甚至有点“网红”的感觉。网上还流行一句话“Life is short, I use Python”&#xff08;人生短暂&#xff0c;我用Python&#xff09;。Python是一种非常高级的动态编程语言&#xff08;其表达更接近自然语言&#xff…

C++设计模式系列(二)工厂模式

文章目录一、什么是工厂二、 简单工厂模式UML类图简单工厂模式结构代码一、定义抽象产品类AbstractProduct二、定义具体产品类三、定义工厂类和工厂方法应用扩展一、扩展具体产品类二、扩展工厂类方法三、扩展应用优点缺点使用场合三、工厂方法模式UML类图工厂方法模式结构代码…

【车间调度】基于GA/PSO/SA/ACO/TS优化算法的车间调度比较(Matlab代码实现)

目录 1 概述 2 FJSP 描述 3 运行结果 3.1 main1运行结果 3.2 main2运行结果 4 参考文献 5 Matlab代码实现 1 概述 柔性作业车间调度问题(Flexible Job shop Sched-uling Problem , FJSP)是在离散制造业和流程工业中应用广泛的一类问题,已被证明是典型的 NP-上hard问题。…

【面试题】宏任务和微任务

1. 宏任务和微任务 宏任务(macroTask)和微任务(microTask)都是异步中API的分类。 宏任务&#xff1a;setTimeout&#xff0c;setInterval&#xff0c;Ajax&#xff0c;DOM事件微任务&#xff1a;Promise&#xff0c;async/await 微任务执行时机比宏任务要早。 console.log(1…

策略 模式

策略模式 参考&#xff1a; 三种新姿势&#xff1a;帮你干掉过多的if-else (qq.com) http://t.csdn.cn/5YeOZ http://t.csdn.cn/HcGYw JAVASE中GUI编程中&#xff0c;布局管理 &#xff1b; Spring框架中&#xff0c;Resource接口&#xff0c;资源访问&#xff1b; javax.…

优美的曲线(含蝴蝶线)-CoCube

复现如下这篇&#xff1a; 优美的曲线-turtlesim 两段视频&#xff1a; 优美的曲线-CoCubebutterfly蝴蝶曲线之CoCube篇如何更深入分析&#xff0c;获得更高精度曲线呢&#xff1f; 对比下面两幅图&#xff1a; 尤其需要注意右图&#xff0c;右下角。 什么原因导致这个控制量…

一个元素纯CSS实现开关按钮【介绍box-shadow、单边或多重阴影、appearance属性】

借助checkbox表单元素、:checked伪类、::before/::after伪元素&#xff0c;就可以只需一个input[type"checkbox"]元素&#xff0c;通过纯CSS实现Switch开关效果的按钮。 主要用到的属性&#xff1a; appearance 默认css元素样式box-shadow 阴影效果transition css动…

ICG maleimide, ICG-MAL,2143933-81-5,ICG和PEG链接可在体内长循环.

英文名&#xff1a;ICG maleimide ICG-MAL CAS&#xff1a;2143933-81-5 分子式: C51H56N4O6S 分子量: 853.09 外 观&#xff1a;绿色粉末 溶解度&#xff1a;二氯甲烷 纯 度&#xff1a;95% 结构式&#xff1a; ICG is a tricarbocyanine-type dye with NIR-absorb…

Jenkins自动化测试Robot Framework详解

目录 1. Robot Framework 概念 2. Robot Framework 安装 3. Pycharm Robot Framework 环境搭建 4. Robot Framework 介绍 5. Jenkins 自动化测试 总结 重点&#xff1a;配套学习资料和视频教学 1. Robot Framework 概念 Robot Framework是一个基于Python的&#xff0c;…

MySQL——怎么给字符串字段加索引

现在&#xff0c;几乎所有的系统都支持邮箱登录&#xff0c;如何在邮箱这样的字段上建立合理的索引&#xff0c;是本篇文章要讨论的问题。 假设&#xff0c;现在维护一个支持邮箱登录的系统&#xff0c;用户表是这么定义的&#xff1a; mysql> create table SUser( ID big…

Hive 分析银行转账风险

文章目录创建数据源基于转账记录&#xff0c;计算 7 天内各个账号的转账金额找出相同收付款人 5 天内连续转账3次或以上的记录创建数据源 数据来源&#xff1a;数据源 drop table transfer_log;CREATE TABLE transfer_log ( log_id bigint, -- idlog_ts timestamp, -- 操作时…