Java生鲜电商平台-电商起送价的深入思考与实战

说明:在生鲜电商中,起送价是一个非常普遍的话题,今天我们就用实战来告诉大家,如何设置起送价,如何编写起送价的代码,以及如何同步起送价。

在开始题目之前,我们思考一下几个问题:

1. 业务概念

1.1 什么是起送价。

  起送价就是你这一单要满多少钱才给你送。例如15块钱起送,那你买14块的东西就送不了.

1.2. 为什么要有起送价。

一是为了降低成本
          假设你本来想买两件东西,如果无论价格多少都包邮的话可能会下两次单,动用两次人力和财力。但有包邮价格后人一般都选择一起下单。这样节约了资源。

二是为了获取更大利益
        比如你买了一件10元的东西给你包邮,可能盈利只有4元,但邮费成本(注意:是成本,非对外盈利价格)可能就是4元甚至更多。那盈利肯定就不多。而且大家往往为了凑免运费而买更多的产品。

商人嘛,讲究利益和成本。遇到不明白的往这两方面思考就好。

  因为卖家也需要盈利。如果你买的太少,还不够路费,那卖家不是亏死了。

1.3. 起送价到底设置多少比较合理。

对于生鲜电商来讲,这个是很有讲究的,不能随便设置,一般的情况下,我们实际是采用平均客单价,然后处于2来算一个合理的值,最终我们确定,我们的起送价是58元。

1.4. 如何设置起送价呢?

起送价不能写死,因为公司需要灵活安排,随时可以改,但是也不能随意改,所以需要有一个APP到管理后台,同步的过程,那什么时候同步呢?如何同步呢?

1.4.1  数据是写在参数表中的

1.4.2  每次APP启动的时候,调用这个接口,把最新的起送价数据拿到本地缓存起来。

CREATE TABLE `sys_params` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`param_code` varchar(32) DEFAULT NULL COMMENT '参数编码',
`param_value` varchar(2000) DEFAULT NULL COMMENT '参数值',
`param_type` tinyint(3) unsigned DEFAULT '1' COMMENT '类型 0:系统参数 1:非系统参数',
`remark` varchar(200) DEFAULT NULL COMMENT '备注',
`creator` bigint(20) DEFAULT NULL COMMENT '创建者',
`create_date` datetime DEFAULT NULL COMMENT '创建时间',
`updater` bigint(20) DEFAULT NULL COMMENT '更新者',
`update_date` datetime DEFAULT NULL COMMENT '更新时间',
`del_flag` tinyint(2) DEFAULT '0' COMMENT '是否可用 0:可用 1:不可用',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_param_code` (`param_code`),
KEY `idx_create_date` (`create_date`)
) ENGINE=InnoDB AUTO_INCREMENT DEFAULT CHARSET=utf8mb4 COMMENT='参数管理';

  

2. 业务操作

2.1 使用方式

我们设置了起送价,那么在那个步骤进行使用呢?答案很简单,就是在购物车页面,提交订单的功能中,APP或者小程序页面中,判断下当前的订单总额是否大于或者等于起送价,如果是的,就允许提交订单,否则就显示还差多少金额,去凑单的功能更。

2.2 多次购买如何处理呢?

在实际业务中,我们经常的发现用户买完了东西后,比如起送价100元,但是用户这一单买了300元,起送价也足够了,而且配送也包邮了,但是用户盘点的时候,比如发现

大白菜少了10斤,这个时候,用户再次下单,购买10斤大白菜,很明晰,大白菜不够起送价,那么怎么办?

是强制以订单为单位,如果不满足订单的话,就不让下单,这样简单粗暴的方式肯定是会惹得客户不高兴,或许以后丢失这个客户。那么怎么办呢?

1. 判断用户今天是否下过单,如果下过单,那么第二次下单就不用起送价,否则的话,还是需要起送价。

我们回顾下:

1. 先前我们是在购物车的时候用订单金额跟起送价对比,那么这个下过单的同一天再次下单,应该是在哪里进行判断呢?

答案是:在进入购物车的时候,需要提供一个接口,用来判断用户是否曾经下过单,如果下单了,这次就只判断金额大于0即可。

我贴出来实际的业务代码:

public class ShoppingCartManager {
private ShoppingCartDao shoppingCartDao; public ShoppingCartManager() {
shoppingCartDao = BaseApplication.getInstance().getDaoSession().getShoppingCartDao();
} public List<ShoppingCart> getBySeller(long sellerId, long userId) {
return shoppingCartDao.queryBuilder().where(ShoppingCartDao.Properties.SellerId.eq(sellerId))
.where(ShoppingCartDao.Properties.BuyerId.eq(userId)).build().list();
} public List<ShoppingCart> getByUser(long userId) {
return shoppingCartDao.queryBuilder()
.where(ShoppingCartDao.Properties.BuyerId.eq(userId)).build().list();
} public List<ShoppingCart> getByFormat(long sellerId, long userId, long formatId) {
return shoppingCartDao.queryBuilder().where(ShoppingCartDao.Properties.SellerId.eq(sellerId))
.where(ShoppingCartDao.Properties.BuyerId.eq(userId))
.where(ShoppingCartDao.Properties.FormatId.eq(formatId)).build().list();
} public void shopping(ShoppingCart goodsCart) {
ShoppingCart queryGoods = shoppingCartDao.queryBuilder()
.where(ShoppingCartDao.Properties.BuyerId.eq(goodsCart.getBuyerId()))
.where(ShoppingCartDao.Properties.FormatId.eq(goodsCart.getFormatId()))
.where(ShoppingCartDao.Properties.MethodId.eq(goodsCart.getMethodId()))
.where(ShoppingCartDao.Properties.SellerId.eq(goodsCart.getSellerId()))
.build().unique();
int count = goodsCart.getGoodsNumber();
if (queryGoods == null) {
if (count > 0) {
goodsCart.setIsSelected(1);
shoppingCartDao.insert(goodsCart);
}
} else {
if (count == 0) {
shoppingCartDao.delete(queryGoods);
} else {
queryGoods.setGoodsNumber(goodsCart.getGoodsNumber());
shoppingCartDao.update(queryGoods);
}
}
} public void update(ShoppingCart goodsCart) {
ShoppingCart queryGoods = shoppingCartDao.queryBuilder()
.where(ShoppingCartDao.Properties.BuyerId.eq(goodsCart.getBuyerId()))
.where(ShoppingCartDao.Properties.FormatId.eq(goodsCart.getFormatId()))
.where(ShoppingCartDao.Properties.MethodId.eq(goodsCart.getMethodId()))
.where(ShoppingCartDao.Properties.SellerId.eq(goodsCart.getSellerId()))
.build().unique();
if (queryGoods != null) { queryGoods.setPrice(goodsCart.getPrice());
queryGoods.setIsSelected(goodsCart.getIsSelected()); shoppingCartDao.update(queryGoods);
}
} public void deleteBySeller(long userId, long sellerId) {
List<ShoppingCart> queryGoods = shoppingCartDao.queryBuilder()
.where(ShoppingCartDao.Properties.BuyerId.eq(userId))
.where(ShoppingCartDao.Properties.SellerId.eq(sellerId))
.build().list();
for (ShoppingCart c : queryGoods) {
shoppingCartDao.delete(c);
}
} public void deleteByUser(long userId) {
List<ShoppingCart> queryGoods = shoppingCartDao.queryBuilder()
.where(ShoppingCartDao.Properties.BuyerId.eq(userId))
.build().list();
for (ShoppingCart c : queryGoods) {
shoppingCartDao.delete(c);
}
} public void deleteItem(ShoppingCart goodsCart) {
ShoppingCart queryGoods = shoppingCartDao.queryBuilder()
.where(ShoppingCartDao.Properties.BuyerId.eq(goodsCart.getBuyerId()))
.where(ShoppingCartDao.Properties.FormatId.eq(goodsCart.getFormatId()))
.where(ShoppingCartDao.Properties.MethodId.eq(goodsCart.getMethodId()))
.where(ShoppingCartDao.Properties.SellerId.eq(goodsCart.getSellerId()))
.build().unique();
if (queryGoods != null) {
shoppingCartDao.delete(queryGoods);
}
} public void insert(ShoppingCart shoppingCart) {
shoppingCartDao.insert(shoppingCart);
}
}

Java生鲜电商平台-电商起送价的深入思考与实战的更多相关文章

  1. Java生鲜电商平台-电商会员体系搭建

    Java生鲜电商平台-电商会员体系搭建 说明:因为之前一直从事的是B端的生鲜电商方面的产品,对会员体系方面有深刻的理解,今天来聊一聊会员体系的搭建. 明确会员体系的目的 首先我们需要明确的知道,搭建电 ...

  2. Java生鲜电商平台-电商虚拟币的充值与消费思考

    Java生鲜电商平台-电商虚拟币的充值与消费思考 项目背景 最近由于项目业务原因,需要为系统设计虚拟币的充值及消费功能.公司内已经有成熟的支付网关服务,所以重点变成了如何设计项目内虚拟币的充值流程,让 ...

  3. Java生鲜电商平台-电商系统性能指标

    Java生鲜电商平台-电商系统性能指标 1.响应时间和吞吐量 根据应用程序的响应时间可以知道程序完成传输数据所用的时间.也可以从HTTP请求级别,或者成为数据库级别来看.对那些缓慢的查询你需要做一些优 ...

  4. Java生鲜电商平台-电商数据运营统计与分析

    Java生鲜电商平台-电商数据运营统计与分析 今天分享将会分为以下几个方面来阐述: 1. 作为运营我们需要统计与分析的几个核心数据是什么? 2. 核心数据对业务的指导价值在哪里呢? 3. 作为产品PM ...

  5. Java生鲜电商平台-电商订单系统全解析

    Java生鲜电商平台-电商订单系统全解析 说明:Java生鲜电商平台-电商订单系统全解析主要讲解OMS的内容,设计,开发,架构等知识. 今天分享将会分为以下三个环节来阐述: 1.订单系统的介绍 2.订 ...

  6. Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析

    Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析 生鲜电商搜索引擎的特点 众所周知,标准的搜索引擎主要分成三个大的部分,第一步是爬虫系统,第二步是数据分析,第三步才 ...

  7. Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲

    Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台:   微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...

  8. Java生鲜电商平台-电商会员体系系统的架构设计与源码解析

    Java生鲜电商平台-电商会员体系系统的架构设计与源码解析 说明:Java生鲜电商平台中会员体系作为电商平台的基础设施,重要性不容忽视.我去年整理过生鲜电商中的会员系统,但是比较粗,现在做一个最好的整 ...

  9. Java生鲜电商平台-电商支付流程架构实战

    Java生鲜电商平台-电商支付流程架构实战 说明:我一直秉承的就是接地气的业务架构实战.我的文章都有一个这样的核心. 1. 业务场景 2. 解决问题. 3.代码实现. 4.代码重构. 5.总结与复盘. ...

随机推荐

  1. 守护线程,需要通过调用线程方法:setDaemon(boolean on)来进行设置

    package seday08.thread;/*** @author xingsir * 守护线程又称为后台线程,默认创建出来的线程都是普通线程, 守护线程需要通过调用线程方法:setDaemon( ...

  2. 在 Java 中如何比较日期?

    在 Java 中有多种方法可以比较日期,日期在计算机内部表示为(long型)时间点--自1970年1月1日以来经过的毫秒数.在Java中,Date是一个对象,包含多个用于比较的方法,任何比较两个日期的 ...

  3. 控制DIV移动

    键盘控制DIV移动 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  4. 腾讯云推出一站式 DevOps 解决方案 —— CODING DevOps

    在产业互联网的大背景下,如何将人工智能.大数据等前沿技术与实体产业相结合,推动传统企业转型升级,已经成为每一个企业不得不思考的问题.落后的软件研发能力已经拖慢了中国大量企业的数字化转型进程. 为了满足 ...

  5. Mac OS X 快速添加新文件

    本文为 automator (中文名为 自动操作)的练习之作,尚有许多不足. 如果你想在 OS X 系统中快速添加新文件可直接参考此文 简介 本文使用 automator 创建了一个应用程序 auto ...

  6. Java连载60-类之间的六种关系

    一.类之间的关系 1.泛化关系(UML图:实线空心三角形箭头,箭头指向被继承方) 类和类.接口与接口之间的继承称为泛化关系 public class A {} class B extends A{} ...

  7. HttpRunner学习1--Windows&Linux安装httprunner

    最近在学习HttpRunner,这是一款开源的接口测试框架,可用于HTTP(S)协议的接口测试.通过该框架,我们只需维护一份 YAML/JSON 脚本,即可轻松的进行接口自动化. 更多的介绍,大家可以 ...

  8. Hyperledger Fabric私有数据

    官方文档:点这里 1简介 在同一个通道中,允许某一组织在对同一通道内其他组织保持部分的数据私有.也就是说有一部分被标识为私有的数据只能具有权限的组织查看和操作,而其余组织不具备查看和操作私有数据的权限 ...

  9. Java设计模式 - - 单例模式 装饰者模式

    Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...

  10. Mybatis的小技巧

    一.使用resultMap字段关联对象属性太麻烦 eg:过于复杂,类似这种结果集转换的,只需要在配置文件中开启自动转换进行了,无需再手动写了很麻烦 替换办法:开启骆驼命名法进行匹配就ok了,实体类字段 ...