草庐IT

基于SpringCloud+redis+Springsecurity实现的微信小程序外卖系统

KJ.JK 2023-04-05 原文

文章目录


🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈
 
🍂个人博客首页: KJ.JK
 
欢迎大家点赞👍收藏💖评论💬关注🔒
 
💖源码获取 | 💻学习交流 | 🤝商务合作 | 💨私信作者


一、项目介绍

今天为大家带来的是weiit-saas这款Java开源项目进行实现的微信小程序weiit-saas是完全开源电商SaaS系统,属于weiit开源的社区版,旧版已不在维护和更新,仅供学习和参考,新版saas从底层架构到前后端UI设计已经全面优化和升级新版访问地址👉 weiit


二、技术栈以及项目特点


⭐新版saas技术栈使用⭐

  • SpringCloud + Oauth2.0 + ShiroRedis + JWT + Gateway + Nacos + Nginx + Vue +Mybatis+Mysql+Elasticsearch+redis+Springsecurity
     

⭐项目特点⭐

  • 项目采用Spring+SpringMVC+Mybatis主流开源框架,遵循MVC架构,设计轻巧,使用简单,开发人员接手与二次开发简单易懂,使用了各种目前主流对的项目框架,包括Mybatis、MybatisPlus、Spring、SpringMVC、SpringBoot、Mysql、Elasticsearch、redis、Spring、Springsecurity
  • 项目完成了对阿里云、腾讯云、微信生态的快速接入与代码示例,并成功运用到了商业中,方便大家学习对OSS/COS/短信服务/快递服务/公众号/小程序/微信开放平台/微信支付的技术点与应用场景的学习
  • 店家可自定义商品,进行上下架功能
  • 发放社群福利以及会员福利
  • 店家可自定义自己需要的模块,一键生成小程序
  • 该小程序使用了Springsecurity+自定义注解进行资源鉴权
  • 小程序与公众号第三方授权集成,让开发者与企业省去繁琐的配置,对AppId/AppSecret集成彻底告别
  • 不同企业数据隔离,真正实现SAAS数据隔离模型,让企业数据互不干扰

三、数据库表设计

营销—拼团活动表:主键,商品id,拼团价格,活动名称,有效期开始时间,有效期结束时间,单位小时,参团人数 ,限购数量
 
营销—优惠券表:优惠券Id,优惠券编号,优惠券名称,优惠券类型,
 
营销—砍价活动表:主键,商品id,活动名称,有效期开始时间,有效期结束时间,原价价格,砍到最低价格,砍价最小价格,砍价最大价格,用户发起砍价后的有效小时,行业
 
商家物流表:主键,物流公司名称,图片,创建时间,修改时间,物流公司id,行业
 
商品SKU信息表:主键,商品SKU编号,商品ID,条形码,SKU规格商品条形码图片,预览字段,SKU规格商品二维码图片,自定义规格值的ID,SKU规格供应价,SKU规格市场销售价,SKU规格销售价格,SKU规格商品的库存
 
商品图片管理表:主键,商品ID,商品图片,创建时间,修改时间,行业
 
商品描述表:主键,商品ID,是否删除,创建时间,修改时间,行业
 
商品属性与规格表:主键,唯一识别号,上级,商品分类,创建时间,修改时间,行业
 
商品表:商品一级分类,商品二级分类,商品三级分类,商品名称,商品供应价,商品市场销售价格,商品实际销售价格,商品总库存,商品主图,商品销量,限购数,商品规格类型设置,属性自定义,规格自定义,商品购买后赠送积分,运费方式,运费,运费模板id,商品重量,商品体积,商品排序,是否禁用,是否删除,建创人id,创建时间,修改人id,修改时间,行业
 
全店风格表:主键,全店配色方案,颜色一,颜色二,行业
 
底部菜单表:主键,方案名称,链接类型,链接类型为选择的商品,链接类型为自定义时,行业
 
页面表:主键,页面名称,页面描述,页面背景,微页面布局参数,微页面封面,删除状态 ,创建时间,行业
 
店铺协议表:主键,协议标题,协议内容,协议类型,行业


四、系统设计


SAAS微信小程序的主要功能模块包括 首页模块,点单模块,订单模块,我的管理模块


          (1)首页模块: 会展现社群福利会员福利领券中心邀请有利自取以及外卖功能


          (2)点单模块: 该模块包含各个周数展现的特价功能会员特惠餐桌啃卤下饭素菜串串米饭


          (3)订单模块: 该模块包含点击添加商品后加入购物车的商品信息最新订单历史订单


          (4)我的管理模块: 该模块包含卡券、积分、余额、我的订单、卡券激活、礼品卡、积分签到、卡券中心、客服、收货地址、退出、退款、收货功能


五、系统功能演示


🚩首页功能演示图




🚩点单功能演示图







🚩订单模块演示图





🚩我的管理模块演示图



六、系统源代码


public enum ApiResponseCode {
    SUCCESS("0","SUCCESS"),
    PARAM_ERROR("1001001","参数异常"),
    TOKEN_INVALID("1001002","请重新登录"),
    VALICODE_ERROR("1001003","验证码过期"),
    BALANCE_NOT_ENOUGH("1001004","余额不足"),
    GROUPON_PEOPLE_ENOUGH("1001005","拼团人数已满"),
    GROUPON_ING("1001005","该拼团进行中"),
    BARGAIN_NO_FINISH("1001006","当前有未完成的团"),
    GROUPON_PEOPLE_NOTEXIST("1001007","拼团异常"),
    BARGAIN_NO_HASBARGAIN("1001008","已帮好友砍价"),
    BARGAIN_HASDEAD("1001009","已完成或已过期的砍价"),
    ERROR_SIGN("1001010","错误签名"),
    BARGAIN_NO_ORDER("1001011","查无订单"),
    ORDER_STATE_ERROR("1001012","订单已完成"),
    WX_CODE_EMPTY("1001013","code 为空"),
    MOBILE_PHONE_NULL("1001014","手机号不能为空"),
    MERCH_HAS_EXIST("1001015","手机账户已注册"),
    VALIDATE_CODE_ERROR("1001016","验证码错误"),
    VALIDATE_CODE_MAX_ERROR("1001017","验证码次数上限"),
    FLOWPATH_ERROR("1001018","请按流程操作"),
    INTEGRAL_PAST("1001019","积分商品过期"),
    INTEGRAL_NOT_ENOUGH("1001020","亲,您的积分不足"),
    INTEGRAL_MAX_LIMIT("1001021","亲,已超兑换数量"),
    INTEGRAL_STATE_ERROR("1001022","稍后再试"),
    SHOP_NOTEL("1001023","店主未设置客服电话"),
    GROUPIDS_EMPTY("1001000","参数异常");


    private String code;
    private String message;





    ApiResponseCode(String code, String message) {
        this.code = code;
        this.message = message;
    }


    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }


}


@Controller
@RequestMapping(value = "/ump/bargain")
public class BargainController extends AdminController {

    public static Logger logger = Logger.getLogger(BargainController.class);

    @Resource
    private BargainService bargainService;

    @Resource
    ProductService productService;


    /**
     * 砍价活动 列表
     */
    @RequestMapping("/bargainList")
    public UIview bargainList() throws Exception {
        logger.info("进入 bargainController-list,砍价活动列表");
        //获取请求参数
        FormMap formMap = getFormMap();
        //开启分页
        PageHelper.startPage(formMap.getPage(), formMap.getRows());
        //查询展示数量
        List<E> list = bargainService.selectList(formMap);

        //返回到list页面
        UIview result = UIView("/center/ump/bargain/bargainList", false);
        //绑定分页返回
        result.addObject("pageInfo", new PageInfo<E>(list));
        //绑定上一次参数
        result.addObject("queryParam", formMap);
        return result;
    }

    /**
     * 砍价活动 新增
     */
    @RequestMapping("/add")
    public UIview add() throws Exception {

        UIview result = UIView("/center/ump/bargain/bargainCreate", false);

        this.getRequest().setAttribute("title", "砍价活动新增");

        return result;
    }



    /**
     * 砍价活动 编辑
     */
    @RequestMapping("/edit")
    public UIview edit() throws Exception {

        FormMap formMap = getFormMap();

        E infoMap = bargainService.selectOne(formMap);
        formMap.put("item_id",infoMap.get("item_id"));
        E itemInfo = productService.getItemById(formMap);


        String specString ="";
        if (itemInfo!=null && itemInfo.get("spec_custom")!=null){
            formMap.put("specIds", itemInfo.getStr("spec_custom").split(";"));
            List<E> specList = productService.getSpecCustomByIds(formMap);

            for(E spec :specList){
                specString+=spec.getStr("key_name")+";";
            }
        }
        specString=specString==""?infoMap.getStr("product_name"):specString;

        infoMap.put("skuName",specString);
        UIview result = UIView("/center/ump/bargain/bargainCreate", false);

        this.getRequest().setAttribute("infoMap", infoMap);

        this.getRequest().setAttribute("title", "砍价活动编辑");

        return result;
    }

    /**
     * 砍价活动 保存
     */
    @RequestMapping("/save")
    public UIview save() throws Exception {

        FormMap param = getFormMap();
        if (param.get("validate_id") == null || param.get("validate_id").equals("")) {

            //根据生效时间判断是否现在生效
            if (System.currentTimeMillis()> DateUtil.getTimeByString(param.getStr("start_time"),"yyyy/MM/dd HH:mm:ss")){
                param.put("state", 0);
            }else {
                //未开始状态
                param.put("state", -2);
            }

            bargainService.insert(param);
        } else {
            param.set("eivt", null);
            //失效后再编辑
            if (System.currentTimeMillis()> DateUtil.getTimeByString(param.getStr("start_time"),"yyyy/MM/dd HH:mm:ss") && System.currentTimeMillis()<DateUtil.getTimeByString(param.getStr("end_time"),"yyyy/MM/dd HH:mm:ss")){
                param.put("state", 0);
            }else if (System.currentTimeMillis()<DateUtil.getTimeByString(param.getStr("start_time"),"yyyy/MM/dd HH:mm:ss")){
                param.put("state", -2);
            }

            bargainService.edit(param);
        }
        UIview result = UIView("redirect:bargainList", false);

        return result;
    }

    /**
     * 砍价活动 状态修改
     */
    @RequestMapping("/status")
    public UIview status() throws Exception {

        FormMap formMap = getFormMap();

        formMap.set("eivt", "state");

        bargainService.edit(formMap);

        UIview result = UIView("redirect:bargainList", false);

        return result;
    }

    /**
     * 秒杀活动 删除
     */
    @RequestMapping("/remove")
    public UIview remove() throws Exception {

        FormMap map = getFormMap();

        bargainService.remove(map);

        UIview result = UIView("redirect:bargainList", false);

        return result;
    }

    /**
     * 砍价活动记录列表
     */
    @RequestMapping("/bargainDetailList")
    public UIview bargainOrderList() throws Exception {
        logger.info("进入 bargainController-bargainOrderList,满减送活动列表");
        //获取请求参数
        FormMap formMap = getFormMap();
        //开启分页
        PageHelper.startPage(formMap.getPage(), formMap.getRows());
        //查询展示数量
        List<E> list = bargainService.selectBargainDetailList(formMap);
        //返回到list页面
        UIview result = UIView("/center/ump/bargain/bargainDetailList", false);
        //绑定分页返回
        result.addObject("pageInfo", new PageInfo<E>(list));
        //绑定上一次参数
        result.addObject("queryParam", formMap);
        return result;
    }

    /**
     * 砍价活动 列表
     */
    @RequestMapping("/bargainNancyList")
    public UIview bargainNancyList() throws Exception {
        logger.info("进入 bargainController-bargainOrderList,砍价活动列表");
        //获取请求参数
        FormMap formMap = getFormMap();
        //开启分页
        PageHelper.startPage(formMap.getPage(), formMap.getRows());
        //查询展示数量
        List<E> list = bargainService.selectBargainNancyList(formMap);
        //返回到list页面
        UIview result = UIView("/center/ump/bargain/bargainNancyList", false);
        //绑定分页返回
        result.addObject("pageInfo", new PageInfo<E>(list));
        //绑定上一次参数
        result.addObject("queryParam", formMap);
        return result;
    }


    /**
     * 查询商品列表
     */
    @ResponseBody
    @RequestMapping("/productList.json")
    public String productList() throws Exception {
        logger.info("进入seckillController-productList,查询商品");
        try {
            FormMap formMap = getFormMap();
            formMap.set("product_name", new String(formMap.getStr("product_name").getBytes("ISO-8859-1")));
            List<E> productList = bargainService.selectProductList(formMap);
            List<E> productJson = new ArrayList<E>();
            for (E e : productList) {
                E productinfo = new E();
                productinfo.set("product_name", "<img src='" + WeiitUtil.getFileDomain() + e.getStr("product_img") + "' width='60px' height='60px'/>" + e.getStr("product_name"));
                productinfo.set("sale_price", e.getStr("sale_price"));
                productinfo.set("stock", e.getStr("stock"));
                if (StringUtils.isEmpty(e.getStr("state"))) {
                    productinfo.set("option", "<a href='javascript:;'   title='选取' class='btn bg-green m-r-5 m-b-5 able_product_" + e.getStr("product_id") + "' style='height: 22px;padding-top: 0px;' οnclick='selectProduct(" + e.getStr("product_id") + ")' price='" + e.getStr("sale_price") + "'spec_config='" + e.getStr("spec_config") + "'>选取</a>");
                } else {
                    productinfo.set("option", "<a href='javascript:;' class='btn bg-grey m-r-5 m-b-5' style='height: 22px;padding-top: 0px;'>已参加</a>");
                }
                productJson.add(productinfo);
            }
            return toJsonAPI(productJson);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("出错啦...");
        }
    }

    /**
     * 选择多规格商品  规格、价格、库存、操作
     * produce_id
     */
    @ResponseBody
    @RequestMapping("/skuList.json")
    public String skuList() throws Exception {
        logger.info("BargainController-skuList,选择多规格商品");
        FormMap formMap = getFormMap();
        formMap.put("is_deleted", 0);
        formMap.put("is_disabled", 0);
        List<E> list = productService.selectItemList(formMap);

        E productInfo = productService.selectById(formMap);

        List<E> productJson = new ArrayList<E>();
        for (E e : list) {
            E productinfo = new E();
            formMap.put("specIds", e.getStr("spec_custom").split(";"));
            List<E> specList = productService.getSpecCustomByIds(formMap);
            String specString ="";
            for(E spec :specList){
                specString+=spec.getStr("key_name")+";";
            }
            specString=specString==""?productInfo.getStr("product_name"):specString;
            productinfo.set("specDesc",specString);
            productinfo.set("sale_price", e.getStr("sale_price"));
            productinfo.set("stock", e.getStr("stock"));
            productinfo.set("option", "<a href='javascript:;'   title='选取' class='btn bg-green m-r-5 m-b-5 able_item_" + e.getStr("item_id") + "' style='height: 22px;padding-top: 0px;' οnclick='selectItem(" + e.getStr("item_id") + ")' specDesc='" + specString + "'  product_id='" + e.getStr("product_id") + "' product_img='" + WeiitUtil.getFileDomain()+productInfo.getStr("product_img") + "' stock='" + e.getStr("stock") + "' price='" + e.getStr("sale_price") + "'>选取</a>");

            productJson.add(productinfo);

        }
        return toJsonAPI(productJson);
    }


    /**
     * 微页面(活动页) 根据bargain_ids 获取砍价商品活动列表
     */
    @ResponseBody
    @RequestMapping("/getProductByBargainIds")
    public String getProductByBargainIds(@RequestParam String token,String bargain_ids,Integer bargainGetType) throws Exception {
        logger.info("进入 bargainController-getProductByBargainIds,微页面根据bargain_ids 获取砍价商品活动列表");
        FormMap formMap = new FormMap();
        try {
            formMap.put("shop_id", DesUtil.decrypt(token));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("token 解密失败");
            return "";
        }
        if (!StringUtils.isEmpty(bargain_ids)&& bargainGetType==0) {
            formMap.put("bargain_ids", StringUtils.strip(bargain_ids, "[]").split(","));
        }
		formMap.put("end_time",new Date());
        List<E> BargainList = bargainService.getProductByBargainIds(formMap);
        return toJsonAPI(BargainList);
    }


}

作者:KJ.JK

文章对你有所帮助的话,欢迎给个赞或者 star,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习

有关基于SpringCloud+redis+Springsecurity实现的微信小程序外卖系统的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  3. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  4. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  5. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  8. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

  9. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  10. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

随机推荐