1
0
mirror of https://gitee.com/coder-xiaomo/flashsale synced 2025-09-13 23:41:39 +08:00
Code Issues Projects Releases Wiki Activity GitHub Gitee

11 Commits

33 changed files with 1904 additions and 28 deletions

View File

@@ -1,3 +1,5 @@
MavenRepo: 不存在的Maven依赖需要手动复制到本地Maven仓库中
sql: 项目数据库文件
sql: 项目数据库文件
课程https://www.imooc.com/video/18469

View File

@@ -11,7 +11,7 @@
Target Server Version : 50726
File Encoding : 65001
Date: 03/03/2022 18:37:04
Date: 05/03/2022 16:32:52
*/
SET NAMES utf8mb4;
@@ -34,21 +34,21 @@ CREATE TABLE `item_info` (
-- ----------------------------
-- Records of item_info
-- ----------------------------
INSERT INTO `item_info` VALUES (1, 'item-h7p0wt-22680', 22.00, '0sddhs4aeowc26638j5fp2ox', 0, 'https://domain.com/pic/190ghi.jpg');
INSERT INTO `item_info` VALUES (2, '电视机', 1800.00, '一台电视机', 0, 'https://domain.com/pic/television.png');
INSERT INTO `item_info` VALUES (3, '电冰箱', 2800.00, '一台电冰箱', 0, 'https://domain.com/pic/电冰箱.png');
INSERT INTO `item_info` VALUES (4, '空调', 3600.00, '一台空调', 0, 'https://domain.com/pic/空调.png');
INSERT INTO `item_info` VALUES (5, 'item-2xmm6g-5492', 235.00, 'lsudsf67ghobos3q1olbwx27', 0, 'https://domain.com/pic/1fvojf.jpg');
INSERT INTO `item_info` VALUES (6, 'item-wlx9gu-1220', 270.00, '3q234qqp3wwo53mtdv0qjuvg', 0, 'https://domain.com/pic/tkxc5q.jpg');
INSERT INTO `item_info` VALUES (7, 'item-cqru11-3487', 259.00, '04q6lopvj3ubb4458k4wldok', 0, 'https://domain.com/pic/nxmx2h.jpg');
INSERT INTO `item_info` VALUES (8, 'item-7f7qa1-5168', 314.00, 'jqkgc5ks2r9e2k8za3zs9rlc', 0, 'https://domain.com/pic/gvwtzd.jpg');
INSERT INTO `item_info` VALUES (9, 'item-i8flrb-7649', 129.00, 'i0m9w2x5w4gugeq7hlyp8nqx', 0, 'https://domain.com/pic/rz85vu.jpg');
INSERT INTO `item_info` VALUES (10, 'item-epo4p3-8545', 40.00, 'x71zeodg46ziiid7pgfag4bc', 0, 'https://domain.com/pic/o0f3uk.jpg');
INSERT INTO `item_info` VALUES (11, 'item-o7iiuj-1056', 322.00, 'fm3r99ko038jbfhy5cg7kwp8', 0, 'https://domain.com/pic/u0rjr8.jpg');
INSERT INTO `item_info` VALUES (12, 'item-fi7q7p-11366', 24.00, '18e54me0cdbqt8n9mxjnisf8', 0, 'https://domain.com/pic/eetb26.jpg');
INSERT INTO `item_info` VALUES (13, 'item-9lwcps-12165', 9.00, 'hlxnhcfak89wengpsnehgtqs', 0, 'https://domain.com/pic/r9yxmi.jpg');
INSERT INTO `item_info` VALUES (14, 'item-pgdbqk-12664', 151.00, 'irydvab5wixg59c7scgt50yh', 0, 'https://domain.com/pic/xvfgwv.jpg');
INSERT INTO `item_info` VALUES (15, 'item-0lq98b-13424', 164.00, 'vwz4rsb4qhsnjs3phos35415', 0, 'https://domain.com/pic/9qhi3l.jpg');
INSERT INTO `item_info` VALUES (1, 'item-h7p0wt-22680', 22.00, '0sddhs4aeowc26638j5fp2ox', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (2, '电视机', 1800.00, '一台电视机', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (3, '电冰箱', 2800.00, '一台电冰箱', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (4, '空调', 3600.00, '一台空调', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (5, '小米手机', 2235.00, 'lsudsf67ghobos3q1olbwx27', 0, 'https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=edc83f8851f431ada3d245397b37ac0f/d058ccbf6c81800a46a75314ec3533fa828b476e.jpg');
INSERT INTO `item_info` VALUES (6, 'item-wlx9gu-1220', 270.00, '3q234qqp3wwo53mtdv0qjuvg', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (7, 'item-cqru11-3487', 259.00, '04q6lopvj3ubb4458k4wldok', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (8, 'item-7f7qa1-5168', 314.00, 'jqkgc5ks2r9e2k8za3zs9rlc', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (9, 'item-i8flrb-7649', 129.00, 'i0m9w2x5w4gugeq7hlyp8nqx', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (10, 'item-epo4p3-8545', 40.00, 'x71zeodg46ziiid7pgfag4bc', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (11, 'item-o7iiuj-1056', 322.00, 'fm3r99ko038jbfhy5cg7kwp8', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (12, 'item-fi7q7p-11366', 24.00, '18e54me0cdbqt8n9mxjnisf8', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (13, 'item-9lwcps-12165', 9.00, 'hlxnhcfak89wengpsnehgtqs', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (14, 'item-pgdbqk-12664', 151.00, 'irydvab5wixg59c7scgt50yh', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
INSERT INTO `item_info` VALUES (15, 'item-0lq98b-13424', 164.00, 'vwz4rsb4qhsnjs3phos35415', 0, 'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00015-3050.jpg');
-- ----------------------------
-- Table structure for item_stock
@@ -82,6 +82,62 @@ INSERT INTO `item_stock` VALUES (13, 351, 13);
INSERT INTO `item_stock` VALUES (14, 117, 14);
INSERT INTO `item_stock` VALUES (15, 34, 15);
-- ----------------------------
-- Table structure for order_info
-- ----------------------------
DROP TABLE IF EXISTS `order_info`;
CREATE TABLE `order_info` (
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`user_id` int(11) NOT NULL DEFAULT 0,
`item_id` int(11) NOT NULL,
`item_price` decimal(10, 2) NOT NULL,
`amount` int(255) NOT NULL,
`order_price` decimal(10, 2) NOT NULL,
`promo_id` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of order_info
-- ----------------------------
-- ----------------------------
-- Table structure for promo_info
-- ----------------------------
DROP TABLE IF EXISTS `promo_info`;
CREATE TABLE `promo_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`promo_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`start_date` datetime NOT NULL DEFAULT '0000-01-01 00:00:00',
`end_date` datetime NOT NULL DEFAULT '0000-01-01 00:00:00',
`item_id` int(11) NOT NULL DEFAULT 0,
`promo_item_price` decimal(10, 2) NOT NULL DEFAULT 0.00,
PRIMARY KEY (`id`) USING BTREE,
INDEX `item_id`(`item_id`) USING BTREE,
CONSTRAINT `promo_info_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `item_info` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of promo_info
-- ----------------------------
INSERT INTO `promo_info` VALUES (1, '小米手机抢购活动', '2022-03-05 14:00:00', '2022-03-05 16:00:00', 5, 1999.00);
-- ----------------------------
-- Table structure for sequence_info
-- ----------------------------
DROP TABLE IF EXISTS `sequence_info`;
CREATE TABLE `sequence_info` (
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`current_value` int(11) NOT NULL DEFAULT 0,
`step` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of sequence_info
-- ----------------------------
INSERT INTO `sequence_info` VALUES ('order_info', 5, 1);
-- ----------------------------
-- Table structure for user_info
-- ----------------------------

View File

@@ -18,7 +18,7 @@
| ----------------- | --------------------- | --------------------------------------- | ---------------------------------------- | ------------------------------- |
| **Controller层** | | | | |
| Controller | controller | 类 class | | controller.UserController |
| View Object | controller/viewobject | 类 class | 将用户Model转化为可供UI使用的View Object | controller.UserController |
| View Object (VO) | controller/viewobject | 类 class | 将用户Model转化为可供UI使用的View Object | controller.UserController |
| | | | | |
| **Service层** | 转换成业务模型 | | | |
| Service | service | 接口 interface | | service.UserService |
@@ -28,7 +28,7 @@
| **Dao层** | 对数据库的映射 | | | |
| Mapper | dao | 接口 interface | | dao.UserDOMapper |
| Mapping | resources/mapping | Mapper接口实现类 | xml格式SQL语句 | mapping/UserDOMapper.xml |
| Data Object | dataobject | 类 class | | dataobject.UserDO |
| Data Object (DO) | dataobject | 类 class | | dataobject.UserDO |
| | | | | |
| **其他** | | | | |
| response | response | | 用于处理HTTP请求返回 | response.CommonReturnType |
@@ -41,3 +41,47 @@
| BusinessException | error | CommonError接口实现类 & 继承自Exception | | error.BusinessException |
**Tips:** Model与Data Object并非完全一一对应例如UserModel是由ServiceImpl将UserDO和UserPasswordDO组装而成的。
代码构建顺序:
1. 创建Model模型service/model
2. 创建数据库中数据表
3. 使用mybatis-generator生成数据库映射文件dao ; dataobject ; resources/mapping
4. 创建Service接口service
5. 创建Service接口实现Implservice/implclass打上 `Service` 标注;方法上打上 `@Transactional` 标签保证是在同一事务中)
6. 思考ServiceImpl中需要哪几步并逐步实现
> - 如果需要修改自动生成的数据库语句,先改 resources/mapping 下的xml映射SQL语句然后修改 dao 下的DOMapper接口
>
> - 可以用 `org.springframework.beans` 包中的 `BeanUtils.copyProperties` 进行DO转Model或Model转DO要字段和类型完全一致的字段才能拷贝其他不对应字段的需要手动设置
7. Service返回Controller前完成将DO转换为Model同时进行业务处理最后返回Model
8. 创建Controller继承BaseController在class上添加注解
```java
@Controller("/item")
@RequestMapping("/item")
@CrossOrigin(allowedHeaders = "*", allowCredentials = "true")
```
9. 创建Controller方法添加以下注释
```java
// POST
@RequestMapping(value = "/create", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
// GET
@RequestMapping(value = "/get", method = {RequestMethod.GET})
@ResponseBody
```
10.

View File

@@ -11,6 +11,12 @@
<body class="login">
<div class="content">
<h3 class="form-title">商品详情</h3>
<div id="promoStartDateContainer" class="from-group">
<label style="color: blue;" id="promoStatus" class="control-label"></label>
<div>
<label style="color: red;" class="control-label" id="promoStartDate">
</div>
</div>
<div class="from-group">
<div>
<label class="control-label" id="title">
@@ -28,8 +34,14 @@
<label class="control-label" id="price">
</div>
</div>
<div id="promoPriceContainer" class="from-group">
<label class="control-label">秒杀价格</label>
<div>
<label style="color: red;" class="control-label" id="promoPrice">
</div>
</div>
<div class="from-group">
<img id="imgUrl" src="" style="width: 200px; height: auto;"/>
<img id="imgUrl" src="" style="width: 200px; height: auto;"/>
</div>
<div class="from-group">
<label class="control-label">库存</label>
@@ -43,7 +55,10 @@
<label class="control-label" id="sales">
</div>
</div>
<div>
<div class="form-actions">
<button class="btn blue" id="createorder" type="submit">
下单
</button>
<a href="listitem.html">返回</a>
</div>
</div>
@@ -74,6 +89,7 @@
if (data.status == "success") {
g_itemVO = data.data;
reloadDom();
setInterval(reloadDom, 300);
} else {
alert("获取信息失败,原因为" + data.data.errMsg);
}
@@ -82,6 +98,35 @@
alert("获取信息失败,原因为" + data.responseText);
}
})
// 下单
$("#createorder").on("click", function () {
$.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded",
url: "http://localhost:8090/order/createorder",
data: {
"itemId": g_itemVO.id,
"amount": 1, // 暂时写死买1件
"promoId": g_itemVO.promoId,
},
xhrFields: {withCredentials: true},
success: function (data) {
if (data.status == "success") {
alert("下单成功");
window.location.reload();
} else {
alert("下单失败,原因为" + data.data.errMsg);
if (data.data.errCode == "20003") {
window.location.href = "login.html";
}
}
},
error: function (data) {
alert("下单失败,原因为" + data.responseText);
}
})
});
})
function reloadDom() {
@@ -91,6 +136,28 @@
$("#price").text(g_itemVO.price);
$("#imgUrl").attr("src", g_itemVO.imgUrl);
$("#sales").text(g_itemVO.sales);
if (g_itemVO.promoStatus == 1) {
// 秒杀活动还未开始
var startTime = g_itemVO.startDate.replace(new RegExp("-", "gm"), "/");
startTime = new Date(startTime).getTime();
var nowTime = Date.parse(new Date());
var delta = (startTime - nowTime) / 1000;
if (delta < 1) {
// 活动开始了
g_itemVO.promoStatus = 2;
reloadDom();
}
$("#promoStartDate").text("秒杀活动将于 " + g_itemVO.startDate + " 开始" +
"倒计时:" + delta + "s");
$("#promoPrice").text(g_itemVO.promoPrice);
$("#createorder").attr("disabled", true);
} else if (g_itemVO.promoStatus == 2) {
$("#promoStartDate").text("秒杀正在进行中");
$("#promoPrice").text(g_itemVO.promoPrice);
$("#createorder").attr("disabled", false);
}
}
</script>
</body>

View File

@@ -58,6 +58,7 @@
success: function (data) {
if (data.status == "success") {
alert("登录成功");
window.location.href = "listitem.html";
} else {
alert("登录失败,原因为" + data.data.errMsg);
}

View File

@@ -72,6 +72,14 @@
<artifactId>hibernate-validator</artifactId>
<version>5.4.3.Final</version>
</dependency>
<!--日期时间-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
<build>

View File

@@ -5,12 +5,15 @@ import com.cxyxiaomo.flashsale.error.BusinessException;
import com.cxyxiaomo.flashsale.response.CommonReturnType;
import com.cxyxiaomo.flashsale.service.ItemService;
import com.cxyxiaomo.flashsale.service.model.ItemModel;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@@ -76,6 +79,15 @@ public class ItemController extends BaseController {
}
ItemVO itemVO = new ItemVO();
BeanUtils.copyProperties(itemModel, itemVO);
if (itemModel.getPromoModel() != null) {
// 有正在进行或即将进行的秒杀活动
itemVO.setPromoStatus(itemModel.getPromoModel().getStatus());
itemVO.setPromoId(itemModel.getPromoModel().getId());
itemVO.setStartDate(itemModel.getPromoModel().getStartDate().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")));
itemVO.setPromoPrice(itemModel.getPromoModel().getPromoPrice());
} else {
itemVO.setPromoStatus(0);
}
return itemVO;
}
}

View File

@@ -0,0 +1,44 @@
package com.cxyxiaomo.flashsale.controller;
import com.cxyxiaomo.flashsale.error.BusinessException;
import com.cxyxiaomo.flashsale.error.EmBusinessError;
import com.cxyxiaomo.flashsale.response.CommonReturnType;
import com.cxyxiaomo.flashsale.service.OrderService;
import com.cxyxiaomo.flashsale.service.model.OrderModel;
import com.cxyxiaomo.flashsale.service.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@Controller("/order")
@RequestMapping("/order")
@CrossOrigin(allowedHeaders = "*", allowCredentials = "true")
public class OrderController extends BaseController {
@Autowired
private OrderService orderService;
@Autowired
private HttpServletRequest httpServletRequest;
// 封装下单请求
@RequestMapping(value = "/createorder", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
public CommonReturnType createOrder(@RequestParam(name = "itemId") Integer itemId,
@RequestParam(name = "amount") Integer amount,
@RequestParam(name = "promoId", required = false) Integer promoId) throws BusinessException {
// 获取用户登陆状态
Boolean isLogin = (Boolean) httpServletRequest.getSession().getAttribute("IS_LOGIN");
if (isLogin == null || !isLogin.booleanValue()) {
throw new BusinessException(EmBusinessError.USER_NOT_LOGIN, "用户还未登录,不能下单");
}
// 获取用户的登录信息
UserModel userModel = (UserModel) httpServletRequest.getSession().getAttribute("LOGIN_USER");
OrderModel orderModel = orderService.createOrder(userModel.getId(), itemId, promoId, amount);
return CommonReturnType.create(null);
}
}

View File

@@ -24,6 +24,19 @@ public class ItemVO {
// 商品描述图片的URL
private String imgUrl;
// 记录商品是否在秒杀活动中,以及对应的状态
// 0没有秒杀活动 2秒杀活动待开始 3秒杀活动进行中
private Integer promoStatus;
// 秒杀活动价格
private BigDecimal promoPrice;
// 秒杀活动Id
private Integer promoId;
// 秒杀活动开始时间
private String startDate;
public Integer getId() {
return id;
}
@@ -79,4 +92,36 @@ public class ItemVO {
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public Integer getPromoStatus() {
return promoStatus;
}
public void setPromoStatus(Integer promoStatus) {
this.promoStatus = promoStatus;
}
public BigDecimal getPromoPrice() {
return promoPrice;
}
public void setPromoPrice(BigDecimal promoPrice) {
this.promoPrice = promoPrice;
}
public Integer getPromoId() {
return promoId;
}
public void setPromoId(Integer promoId) {
this.promoId = promoId;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
}

View File

@@ -1,6 +1,7 @@
package com.cxyxiaomo.flashsale.dao;
import com.cxyxiaomo.flashsale.dataobject.ItemDO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -54,4 +55,6 @@ public interface ItemDOMapper {
* @mbg.generated Thu Mar 03 13:12:13 CST 2022
*/
int updateByPrimaryKey(ItemDO record);
int increaseSales(@Param("id") Integer id, @Param("amount") Integer amount);
}

View File

@@ -1,6 +1,7 @@
package com.cxyxiaomo.flashsale.dao;
import com.cxyxiaomo.flashsale.dataobject.ItemStockDO;
import org.apache.ibatis.annotations.Param;
public interface ItemStockDOMapper {
/**
@@ -52,4 +53,6 @@ public interface ItemStockDOMapper {
* @mbg.generated Thu Mar 03 13:12:13 CST 2022
*/
int updateByPrimaryKey(ItemStockDO record);
int decreaseStock(@Param("itemId") Integer itemId, @Param("amount") Integer amount);
}

View File

@@ -0,0 +1,53 @@
package com.cxyxiaomo.flashsale.dao;
import com.cxyxiaomo.flashsale.dataobject.OrderDO;
public interface OrderDOMapper {
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table order_info
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
int deleteByPrimaryKey(String id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table order_info
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
int insert(OrderDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table order_info
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
int insertSelective(OrderDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table order_info
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
OrderDO selectByPrimaryKey(String id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table order_info
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
int updateByPrimaryKeySelective(OrderDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table order_info
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
int updateByPrimaryKey(OrderDO record);
}

View File

@@ -0,0 +1,55 @@
package com.cxyxiaomo.flashsale.dao;
import com.cxyxiaomo.flashsale.dataobject.PromoDO;
public interface PromoDOMapper {
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table promo_info
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
int deleteByPrimaryKey(Integer id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table promo_info
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
int insert(PromoDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table promo_info
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
int insertSelective(PromoDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table promo_info
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
PromoDO selectByPrimaryKey(Integer id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table promo_info
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
int updateByPrimaryKeySelective(PromoDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table promo_info
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
int updateByPrimaryKey(PromoDO record);
PromoDO selectByItemId(Integer itemId);
}

View File

@@ -0,0 +1,55 @@
package com.cxyxiaomo.flashsale.dao;
import com.cxyxiaomo.flashsale.dataobject.SequenceDO;
public interface SequenceDOMapper {
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table sequence_info
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
int deleteByPrimaryKey(String name);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table sequence_info
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
int insert(SequenceDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table sequence_info
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
int insertSelective(SequenceDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table sequence_info
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
SequenceDO selectByPrimaryKey(String name);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table sequence_info
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
int updateByPrimaryKeySelective(SequenceDO record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table sequence_info
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
int updateByPrimaryKey(SequenceDO record);
SequenceDO getSequenceByName(String name);
}

View File

@@ -0,0 +1,236 @@
package com.cxyxiaomo.flashsale.dataobject;
import java.math.BigDecimal;
public class OrderDO {
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column order_info.id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
private String id;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column order_info.user_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
private Integer userId;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column order_info.item_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
private Integer itemId;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column order_info.item_price
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
private BigDecimal itemPrice;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column order_info.amount
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
private Integer amount;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column order_info.order_price
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
private BigDecimal orderPrice;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column order_info.promo_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
private Integer promoId;
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column order_info.id
*
* @return the value of order_info.id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public String getId() {
return id;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column order_info.id
*
* @param id the value for order_info.id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public void setId(String id) {
this.id = id == null ? null : id.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column order_info.user_id
*
* @return the value of order_info.user_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public Integer getUserId() {
return userId;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column order_info.user_id
*
* @param userId the value for order_info.user_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public void setUserId(Integer userId) {
this.userId = userId;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column order_info.item_id
*
* @return the value of order_info.item_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public Integer getItemId() {
return itemId;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column order_info.item_id
*
* @param itemId the value for order_info.item_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public void setItemId(Integer itemId) {
this.itemId = itemId;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column order_info.item_price
*
* @return the value of order_info.item_price
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public BigDecimal getItemPrice() {
return itemPrice;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column order_info.item_price
*
* @param itemPrice the value for order_info.item_price
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public void setItemPrice(BigDecimal itemPrice) {
this.itemPrice = itemPrice;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column order_info.amount
*
* @return the value of order_info.amount
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public Integer getAmount() {
return amount;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column order_info.amount
*
* @param amount the value for order_info.amount
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public void setAmount(Integer amount) {
this.amount = amount;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column order_info.order_price
*
* @return the value of order_info.order_price
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public BigDecimal getOrderPrice() {
return orderPrice;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column order_info.order_price
*
* @param orderPrice the value for order_info.order_price
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public void setOrderPrice(BigDecimal orderPrice) {
this.orderPrice = orderPrice;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column order_info.promo_id
*
* @return the value of order_info.promo_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public Integer getPromoId() {
return promoId;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column order_info.promo_id
*
* @param promoId the value for order_info.promo_id
*
* @mbg.generated Sat Mar 05 15:52:04 CST 2022
*/
public void setPromoId(Integer promoId) {
this.promoId = promoId;
}
}

View File

@@ -0,0 +1,204 @@
package com.cxyxiaomo.flashsale.dataobject;
import java.math.BigDecimal;
import java.util.Date;
public class PromoDO {
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column promo_info.id
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
private Integer id;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column promo_info.promo_name
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
private String promoName;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column promo_info.start_date
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
private Date startDate;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column promo_info.end_date
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
private Date endDate;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column promo_info.item_id
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
private Integer itemId;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column promo_info.promo_item_price
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
private BigDecimal promoItemPrice;
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column promo_info.id
*
* @return the value of promo_info.id
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public Integer getId() {
return id;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column promo_info.id
*
* @param id the value for promo_info.id
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public void setId(Integer id) {
this.id = id;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column promo_info.promo_name
*
* @return the value of promo_info.promo_name
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public String getPromoName() {
return promoName;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column promo_info.promo_name
*
* @param promoName the value for promo_info.promo_name
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public void setPromoName(String promoName) {
this.promoName = promoName == null ? null : promoName.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column promo_info.start_date
*
* @return the value of promo_info.start_date
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public Date getStartDate() {
return startDate;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column promo_info.start_date
*
* @param startDate the value for promo_info.start_date
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column promo_info.end_date
*
* @return the value of promo_info.end_date
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public Date getEndDate() {
return endDate;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column promo_info.end_date
*
* @param endDate the value for promo_info.end_date
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column promo_info.item_id
*
* @return the value of promo_info.item_id
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public Integer getItemId() {
return itemId;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column promo_info.item_id
*
* @param itemId the value for promo_info.item_id
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public void setItemId(Integer itemId) {
this.itemId = itemId;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column promo_info.promo_item_price
*
* @return the value of promo_info.promo_item_price
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public BigDecimal getPromoItemPrice() {
return promoItemPrice;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column promo_info.promo_item_price
*
* @param promoItemPrice the value for promo_info.promo_item_price
*
* @mbg.generated Sat Mar 05 12:55:23 CST 2022
*/
public void setPromoItemPrice(BigDecimal promoItemPrice) {
this.promoItemPrice = promoItemPrice;
}
}

View File

@@ -0,0 +1,102 @@
package com.cxyxiaomo.flashsale.dataobject;
public class SequenceDO {
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column sequence_info.name
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
private String name;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column sequence_info.current_value
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
private Integer currentValue;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column sequence_info.step
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
private Integer step;
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column sequence_info.name
*
* @return the value of sequence_info.name
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
public String getName() {
return name;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column sequence_info.name
*
* @param name the value for sequence_info.name
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column sequence_info.current_value
*
* @return the value of sequence_info.current_value
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
public Integer getCurrentValue() {
return currentValue;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column sequence_info.current_value
*
* @param currentValue the value for sequence_info.current_value
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
public void setCurrentValue(Integer currentValue) {
this.currentValue = currentValue;
}
/**
* This method was generated by MyBatis Generator.
* This method returns the value of the database column sequence_info.step
*
* @return the value of sequence_info.step
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
public Integer getStep() {
return step;
}
/**
* This method was generated by MyBatis Generator.
* This method sets the value of the database column sequence_info.step
*
* @param step the value for sequence_info.step
*
* @mbg.generated Thu Mar 03 23:07:17 CST 2022
*/
public void setStep(Integer step) {
this.step = step;
}
}

View File

@@ -1,13 +1,17 @@
package com.cxyxiaomo.flashsale.error;
public enum EmBusinessError implements CommonError {
// 通用错误类型 00001
// 通用错误类型 10001
PARAMETER_VALIDATION_ERROR(10001, "参数不合法"),
UNKNOWN_ERROR(10002, "未知错误"),
// 10000开头为用户信息相关错误定义
// 20000开头为用户信息相关错误定义
USER_NOT_EXIST(20001, "用户不存在"),
USER_LOGIN_FAILED(20002, "用户手机号或密码不正确");
USER_LOGIN_FAILED(20002, "用户手机号或密码不正确"),
USER_NOT_LOGIN(20003, "用户还未登录"),
// 30000开头为交易信息错误定义
STOCK_NOT_ENOUGH(30001, "库存不足");
private EmBusinessError(int errCode, String errMsg) {
this.errCode = errCode;

View File

@@ -14,4 +14,10 @@ public interface ItemService {
// 商品详情浏览
ItemModel getItemById(Integer id);
// 库存扣减
boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException;
// 商品销量增加
void increaseSales(Integer itemId, Integer amount);
}

View File

@@ -0,0 +1,15 @@
package com.cxyxiaomo.flashsale.service;
import com.cxyxiaomo.flashsale.error.BusinessException;
import com.cxyxiaomo.flashsale.service.model.OrderModel;
public interface OrderService {
/**
*
* @param userId 用户id
* @param itemId 购买商品
* @param amount 购买商品数量
* @return
*/
OrderModel createOrder(Integer userId, Integer itemId, Integer promoId, Integer amount) throws BusinessException;
}

View File

@@ -0,0 +1,8 @@
package com.cxyxiaomo.flashsale.service;
import com.cxyxiaomo.flashsale.service.model.PromoModel;
public interface PromoService {
// 根据itemId获取即将进行的或正在进行的秒杀活动
PromoModel getPromoByItemId(Integer itemId);
}

View File

@@ -7,7 +7,9 @@ import com.cxyxiaomo.flashsale.dataobject.ItemStockDO;
import com.cxyxiaomo.flashsale.error.BusinessException;
import com.cxyxiaomo.flashsale.error.EmBusinessError;
import com.cxyxiaomo.flashsale.service.ItemService;
import com.cxyxiaomo.flashsale.service.PromoService;
import com.cxyxiaomo.flashsale.service.model.ItemModel;
import com.cxyxiaomo.flashsale.service.model.PromoModel;
import com.cxyxiaomo.flashsale.validator.ValidationResult;
import com.cxyxiaomo.flashsale.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
@@ -30,6 +32,9 @@ public class ItemServiceImpl implements ItemService {
@Autowired
private ItemStockDOMapper itemStockDOMapper;
@Autowired
private PromoService promoService;
@Override
@Transactional
public ItemModel createItem(ItemModel itemModel) throws BusinessException {
@@ -100,9 +105,35 @@ public class ItemServiceImpl implements ItemService {
// 将Data Object -> Model
ItemModel itemModel = convertModelFromDataObject(itemDO, itemStockDO);
// 获取活动商品信息
PromoModel promoModel = promoService.getPromoByItemId(itemModel.getId());
if (promoModel != null && promoModel.getStatus() != 3) {
itemModel.setPromoModel(promoModel);
}
return itemModel;
}
@Override
@Transactional
public boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException {
int affectedRow = itemStockDOMapper.decreaseStock(itemId, amount);
if (affectedRow > 0) {
// 更新库存成功
return true;
} else {
// 更新库存失败
return false;
}
}
@Override
@Transactional
public void increaseSales(Integer itemId, Integer amount) {
itemDOMapper.increaseSales(itemId, amount);
}
private ItemModel convertModelFromDataObject(ItemDO itemDO, ItemStockDO itemStockDO) {
ItemModel itemModel = new ItemModel();
BeanUtils.copyProperties(itemDO, itemModel);

View File

@@ -0,0 +1,141 @@
package com.cxyxiaomo.flashsale.service.impl;
import com.cxyxiaomo.flashsale.dao.OrderDOMapper;
import com.cxyxiaomo.flashsale.dao.SequenceDOMapper;
import com.cxyxiaomo.flashsale.dataobject.OrderDO;
import com.cxyxiaomo.flashsale.dataobject.SequenceDO;
import com.cxyxiaomo.flashsale.error.BusinessException;
import com.cxyxiaomo.flashsale.error.EmBusinessError;
import com.cxyxiaomo.flashsale.service.ItemService;
import com.cxyxiaomo.flashsale.service.OrderService;
import com.cxyxiaomo.flashsale.service.UserService;
import com.cxyxiaomo.flashsale.service.model.ItemModel;
import com.cxyxiaomo.flashsale.service.model.OrderModel;
import com.cxyxiaomo.flashsale.service.model.UserModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private ItemService itemService;
@Autowired
private UserService userService;
@Autowired
private OrderDOMapper orderDOMapper;
@Autowired
private SequenceDOMapper sequenceDOMapper;
@Override
@Transactional
public OrderModel createOrder(Integer userId, Integer itemId, Integer promoId, Integer amount) throws BusinessException {
// 1. 校验下单状态
// 下单的商品是否存在;用户是否合法;购买数量是否正确
ItemModel itemModel = itemService.getItemById(itemId);
if (itemModel == null) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "商品信息不存在");
}
UserModel userModel = userService.getUserById(userId);
if (userModel == null) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "用户信息不存在");
}
if (amount <= 0 || amount > 99) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "数量信息不正确");
}
// 校验活动信息
if (promoId != null) {
if (promoId.intValue() != itemModel.getPromoModel().getId()) {
// (1) 校验对应活动是否存在这个适用商品
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "活动信息不正确");
} else if (itemModel.getPromoModel().getStatus() != 2) {
// (2) 校验活动是否进行中
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "不在活动时间内");
}
}
// 2. 落单减库存
boolean result = itemService.decreaseStock(itemId, amount);
if (!result) {
throw new BusinessException(EmBusinessError.STOCK_NOT_ENOUGH);
}
// 3. 订单入库
OrderModel orderModel = new OrderModel();
orderModel.setUserId(userId);
orderModel.setItemId(itemId);
orderModel.setAmount(amount);
if (promoId != null) {
orderModel.setItemPrice(itemModel.getPromoModel().getPromoPrice());
} else {
orderModel.setItemPrice(itemModel.getPrice());
}
orderModel.setPromoId(promoId);
orderModel.setOrderPrice(orderModel.getItemPrice().multiply(new BigDecimal(amount)));
// 生成交易流水号(订单号)
orderModel.setId(generateOrderNo());
OrderDO orderDO = convertFromOrderModel(orderModel);
orderDOMapper.insertSelective(orderDO);
// 商品销量增加
itemService.increaseSales(itemId, amount);
// 4. 返回前端
return orderModel;
}
private OrderDO convertFromOrderModel(OrderModel orderModel) {
if (orderModel == null) {
return null;
}
OrderDO orderDO = new OrderDO();
BeanUtils.copyProperties(orderModel, orderDO);
return orderDO;
}
// 生成交易流水号,订单号
@Transactional(propagation = Propagation.REQUIRES_NEW) // 即使包在事务的函数中也新开一个事务来提交,保证全局唯一性
private String generateOrderNo() {
// 订单号为16位
StringBuilder stringBuilder = new StringBuilder();
// 前8位为时间信息年月日
LocalDateTime now = LocalDateTime.now();
String nowDate = now.format(DateTimeFormatter.ISO_DATE).replace("-", "");
stringBuilder.append(nowDate);
// 中间6位为自增序列 暂时不考虑序列超出情况可增加init和max数据表列当达到最大时恢复为初始值作为循环序列使用
// 获取当前Sequence
int sequence = 0;
SequenceDO sequenceDO = sequenceDOMapper.getSequenceByName("order_info");
sequence = sequenceDO.getCurrentValue();
sequenceDO.setCurrentValue(sequenceDO.getCurrentValue() + sequenceDO.getStep());
sequenceDOMapper.updateByPrimaryKeySelective(sequenceDO);
String sequenceStr = String.valueOf(sequence);
for (int i = 0; i < 6 - sequenceStr.length(); i++) { // 补齐前面的 0
stringBuilder.append(0);
}
stringBuilder.append(sequenceStr);
// 最后2位为分库分表位
stringBuilder.append("00"); // 暂时写死
return stringBuilder.toString();
}
}

View File

@@ -0,0 +1,54 @@
package com.cxyxiaomo.flashsale.service.impl;
import com.cxyxiaomo.flashsale.dao.PromoDOMapper;
import com.cxyxiaomo.flashsale.dataobject.PromoDO;
import com.cxyxiaomo.flashsale.service.PromoService;
import com.cxyxiaomo.flashsale.service.model.PromoModel;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PromoServiceImpl implements PromoService {
@Autowired
private PromoDOMapper promoDOMapper;
@Override
public PromoModel getPromoByItemId(Integer itemId) {
// 获取对应商品的秒杀活动信息
PromoDO promoDO = promoDOMapper.selectByItemId(itemId);
// Data Object -> Model
PromoModel promoModel = convertFromDataObject(promoDO);
if (promoModel == null) {
return null;
}
// 判断秒杀活动是否即将开始或正在进行
if (promoModel.getStartDate().isAfterNow()) {
promoModel.setStatus(1); // 还未开始
} else if (promoModel.getEndDate().isBeforeNow()) {
promoModel.setStatus(3); // 已经结束
} else {
promoModel.setStatus(2); // 正在进行中
}
return promoModel;
}
private PromoModel convertFromDataObject(PromoDO promoDO) {
if (promoDO == null) {
return null;
}
PromoModel promoModel = new PromoModel();
BeanUtils.copyProperties(promoDO, promoModel);
promoModel.setPromoPrice(promoDO.getPromoItemPrice());
promoModel.setStartDate(new DateTime(promoDO.getStartDate()));
promoModel.setEndDate(new DateTime(promoDO.getEndDate()));
return promoModel;
}
}

View File

@@ -33,6 +33,10 @@ public class ItemModel {
@NotBlank(message = "商品描述图片不能为空")
private String imgUrl;
// 使用聚合模型
// 如果promoModel不为空则表示其还有未结束的秒杀活动
private PromoModel promoModel;
public Integer getId() {
return id;
}
@@ -88,4 +92,12 @@ public class ItemModel {
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public PromoModel getPromoModel() {
return promoModel;
}
public void setPromoModel(PromoModel promoModel) {
this.promoModel = promoModel;
}
}

View File

@@ -0,0 +1,84 @@
package com.cxyxiaomo.flashsale.service.model;
import java.math.BigDecimal;
// 用户下单的交易模型
public class OrderModel {
// 交易号
private String id;
// 用户id
private Integer userId;
// 购买的商品Id
private Integer itemId;
// 若非空,则表示是以秒杀商品方式下单
private Integer promoId;
// 购买商品的单价若promoId非空则表示秒杀商品价格
private BigDecimal itemPrice;
// 购买数量
private Integer amount;
// 购买金额若promoId非空则表示秒杀商品价格
private BigDecimal orderPrice;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getItemId() {
return itemId;
}
public void setItemId(Integer itemId) {
this.itemId = itemId;
}
public Integer getPromoId() {
return promoId;
}
public void setPromoId(Integer promoId) {
this.promoId = promoId;
}
public BigDecimal getItemPrice() {
return itemPrice;
}
public void setItemPrice(BigDecimal itemPrice) {
this.itemPrice = itemPrice;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public BigDecimal getOrderPrice() {
return orderPrice;
}
public void setOrderPrice(BigDecimal orderPrice) {
this.orderPrice = orderPrice;
}
}

View File

@@ -0,0 +1,85 @@
package com.cxyxiaomo.flashsale.service.model;
import org.joda.time.DateTime;
import java.math.BigDecimal;
public class PromoModel {
private Integer id;
// 秒杀活动名称
private String promoName;
// 活动开始时间
private DateTime startDate;
// 活动结束时间
private DateTime endDate;
// 秒杀活动适用商品
private Integer itemId;
// 秒杀活动的价格
private BigDecimal promoPrice;
// 秒杀活动状态
// 1还未开始 2进行中 3已结束
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPromoName() {
return promoName;
}
public void setPromoName(String promoName) {
this.promoName = promoName;
}
public DateTime getStartDate() {
return startDate;
}
public void setStartDate(DateTime startDate) {
this.startDate = startDate;
}
public DateTime getEndDate() {
return endDate;
}
public void setEndDate(DateTime endDate) {
this.endDate = endDate;
}
public Integer getItemId() {
return itemId;
}
public void setItemId(Integer itemId) {
this.itemId = itemId;
}
public BigDecimal getPromoPrice() {
return promoPrice;
}
public void setPromoPrice(BigDecimal promoPrice) {
this.promoPrice = promoPrice;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@@ -28,7 +28,7 @@
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 13:12:13 CST 2022.
-->
select
select
<include refid="Base_Column_List" />
from item_info
where id = #{id,jdbcType=INTEGER}
@@ -48,10 +48,10 @@
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 13:12:13 CST 2022.
-->
insert into item_info (id, title, price,
insert into item_info (id, title, price,
description, sales, img_url
)
values (#{id,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, #{price,jdbcType=DECIMAL},
values (#{id,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, #{price,jdbcType=DECIMAL},
#{description,jdbcType=VARCHAR}, #{sales,jdbcType=INTEGER}, #{imgUrl,jdbcType=VARCHAR}
)
</insert>
@@ -149,4 +149,9 @@
from item_info
order by sales DESC
</select>
<update id="increaseSales">
update item_info
set sales = sales + #{amount}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>

View File

@@ -114,4 +114,10 @@
from item_stock
where item_id = #{itemId,jdbcType=INTEGER}
</select>
<update id="decreaseStock">
update item_stock
set stock = stock - #{amount},
item_id = #{itemId}
where item_id = #{itemId} and stock >= #{amount}
</update>
</mapper>

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cxyxiaomo.flashsale.dao.OrderDOMapper">
<resultMap id="BaseResultMap" type="com.cxyxiaomo.flashsale.dataobject.OrderDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="user_id" jdbcType="INTEGER" property="userId" />
<result column="item_id" jdbcType="INTEGER" property="itemId" />
<result column="item_price" jdbcType="DECIMAL" property="itemPrice" />
<result column="amount" jdbcType="INTEGER" property="amount" />
<result column="order_price" jdbcType="DECIMAL" property="orderPrice" />
<result column="promo_id" jdbcType="INTEGER" property="promoId" />
</resultMap>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
id, user_id, item_id, item_price, amount, order_price, promo_id
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
select
<include refid="Base_Column_List" />
from order_info
where id = #{id,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
delete from order_info
where id = #{id,jdbcType=VARCHAR}
</delete>
<insert id="insert" parameterType="com.cxyxiaomo.flashsale.dataobject.OrderDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
insert into order_info (id, user_id, item_id,
item_price, amount, order_price,
promo_id)
values (#{id,jdbcType=VARCHAR}, #{userId,jdbcType=INTEGER}, #{itemId,jdbcType=INTEGER},
#{itemPrice,jdbcType=DECIMAL}, #{amount,jdbcType=INTEGER}, #{orderPrice,jdbcType=DECIMAL},
#{promoId,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="com.cxyxiaomo.flashsale.dataobject.OrderDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
insert into order_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="userId != null">
user_id,
</if>
<if test="itemId != null">
item_id,
</if>
<if test="itemPrice != null">
item_price,
</if>
<if test="amount != null">
amount,
</if>
<if test="orderPrice != null">
order_price,
</if>
<if test="promoId != null">
promo_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=VARCHAR},
</if>
<if test="userId != null">
#{userId,jdbcType=INTEGER},
</if>
<if test="itemId != null">
#{itemId,jdbcType=INTEGER},
</if>
<if test="itemPrice != null">
#{itemPrice,jdbcType=DECIMAL},
</if>
<if test="amount != null">
#{amount,jdbcType=INTEGER},
</if>
<if test="orderPrice != null">
#{orderPrice,jdbcType=DECIMAL},
</if>
<if test="promoId != null">
#{promoId,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.cxyxiaomo.flashsale.dataobject.OrderDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
update order_info
<set>
<if test="userId != null">
user_id = #{userId,jdbcType=INTEGER},
</if>
<if test="itemId != null">
item_id = #{itemId,jdbcType=INTEGER},
</if>
<if test="itemPrice != null">
item_price = #{itemPrice,jdbcType=DECIMAL},
</if>
<if test="amount != null">
amount = #{amount,jdbcType=INTEGER},
</if>
<if test="orderPrice != null">
order_price = #{orderPrice,jdbcType=DECIMAL},
</if>
<if test="promoId != null">
promo_id = #{promoId,jdbcType=INTEGER},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="com.cxyxiaomo.flashsale.dataobject.OrderDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 15:52:04 CST 2022.
-->
update order_info
set user_id = #{userId,jdbcType=INTEGER},
item_id = #{itemId,jdbcType=INTEGER},
item_price = #{itemPrice,jdbcType=DECIMAL},
amount = #{amount,jdbcType=INTEGER},
order_price = #{orderPrice,jdbcType=DECIMAL},
promo_id = #{promoId,jdbcType=INTEGER}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cxyxiaomo.flashsale.dao.PromoDOMapper">
<resultMap id="BaseResultMap" type="com.cxyxiaomo.flashsale.dataobject.PromoDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="promo_name" jdbcType="VARCHAR" property="promoName" />
<result column="start_date" jdbcType="TIMESTAMP" property="startDate" />
<result column="end_date" jdbcType="TIMESTAMP" property="endDate" />
<result column="item_id" jdbcType="INTEGER" property="itemId" />
<result column="promo_item_price" jdbcType="DECIMAL" property="promoItemPrice" />
</resultMap>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
id, promo_name, start_date, end_date, item_id, promo_item_price
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
select
<include refid="Base_Column_List" />
from promo_info
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
delete from promo_info
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.cxyxiaomo.flashsale.dataobject.PromoDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
insert into promo_info (id, promo_name, start_date,
end_date, item_id, promo_item_price
)
values (#{id,jdbcType=INTEGER}, #{promoName,jdbcType=VARCHAR}, #{startDate,jdbcType=TIMESTAMP},
#{endDate,jdbcType=TIMESTAMP}, #{itemId,jdbcType=INTEGER}, #{promoItemPrice,jdbcType=DECIMAL}
)
</insert>
<insert id="insertSelective" parameterType="com.cxyxiaomo.flashsale.dataobject.PromoDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
insert into promo_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="promoName != null">
promo_name,
</if>
<if test="startDate != null">
start_date,
</if>
<if test="endDate != null">
end_date,
</if>
<if test="itemId != null">
item_id,
</if>
<if test="promoItemPrice != null">
promo_item_price,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=INTEGER},
</if>
<if test="promoName != null">
#{promoName,jdbcType=VARCHAR},
</if>
<if test="startDate != null">
#{startDate,jdbcType=TIMESTAMP},
</if>
<if test="endDate != null">
#{endDate,jdbcType=TIMESTAMP},
</if>
<if test="itemId != null">
#{itemId,jdbcType=INTEGER},
</if>
<if test="promoItemPrice != null">
#{promoItemPrice,jdbcType=DECIMAL},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.cxyxiaomo.flashsale.dataobject.PromoDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
update promo_info
<set>
<if test="promoName != null">
promo_name = #{promoName,jdbcType=VARCHAR},
</if>
<if test="startDate != null">
start_date = #{startDate,jdbcType=TIMESTAMP},
</if>
<if test="endDate != null">
end_date = #{endDate,jdbcType=TIMESTAMP},
</if>
<if test="itemId != null">
item_id = #{itemId,jdbcType=INTEGER},
</if>
<if test="promoItemPrice != null">
promo_item_price = #{promoItemPrice,jdbcType=DECIMAL},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.cxyxiaomo.flashsale.dataobject.PromoDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Mar 05 12:55:23 CST 2022.
-->
update promo_info
set promo_name = #{promoName,jdbcType=VARCHAR},
start_date = #{startDate,jdbcType=TIMESTAMP},
end_date = #{endDate,jdbcType=TIMESTAMP},
item_id = #{itemId,jdbcType=INTEGER},
promo_item_price = #{promoItemPrice,jdbcType=DECIMAL}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectByItemId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from promo_info
where item_id = #{itemId,jdbcType=INTEGER}
</select>
</mapper>

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cxyxiaomo.flashsale.dao.SequenceDOMapper">
<resultMap id="BaseResultMap" type="com.cxyxiaomo.flashsale.dataobject.SequenceDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
<id column="name" jdbcType="VARCHAR" property="name" />
<result column="current_value" jdbcType="INTEGER" property="currentValue" />
<result column="step" jdbcType="INTEGER" property="step" />
</resultMap>
<sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
name, current_value, step
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
select
<include refid="Base_Column_List" />
from sequence_info
where name = #{name,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
delete from sequence_info
where name = #{name,jdbcType=VARCHAR}
</delete>
<insert id="insert" parameterType="com.cxyxiaomo.flashsale.dataobject.SequenceDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
insert into sequence_info (name, current_value, step
)
values (#{name,jdbcType=VARCHAR}, #{currentValue,jdbcType=INTEGER}, #{step,jdbcType=INTEGER}
)
</insert>
<insert id="insertSelective" parameterType="com.cxyxiaomo.flashsale.dataobject.SequenceDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
insert into sequence_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">
name,
</if>
<if test="currentValue != null">
current_value,
</if>
<if test="step != null">
step,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="currentValue != null">
#{currentValue,jdbcType=INTEGER},
</if>
<if test="step != null">
#{step,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.cxyxiaomo.flashsale.dataobject.SequenceDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
update sequence_info
<set>
<if test="currentValue != null">
current_value = #{currentValue,jdbcType=INTEGER},
</if>
<if test="step != null">
step = #{step,jdbcType=INTEGER},
</if>
</set>
where name = #{name,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="com.cxyxiaomo.flashsale.dataobject.SequenceDO">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Thu Mar 03 23:07:17 CST 2022.
-->
update sequence_info
set current_value = #{currentValue,jdbcType=INTEGER},
step = #{step,jdbcType=INTEGER}
where name = #{name,jdbcType=VARCHAR}
</update>
<select id="getSequenceByName" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sequence_info
where name = #{name,jdbcType=VARCHAR} for update
</select>
</mapper>

View File

@@ -7,7 +7,7 @@
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 数据库链接地址账号密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/flashsale?serverTimezone=Asia/Shanghai"
connectionURL="jdbc:mysql://127.0.0.1:3306/flashsale?serverTimezone=Asia/Shanghai&amp;useSSL=false"
userId="root"
password="111111">
</jdbcConnection>
@@ -53,6 +53,15 @@
<!--<table tableName="item_stock" domainObjectName="ItemStockDO" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false"></table>-->
<!--<table tableName="order_info" domainObjectName="OrderDO" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false"></table>-->
<!--<table tableName="sequence_info" domainObjectName="SequenceDO" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false"></table>-->
<!--<table tableName="promo_info" domainObjectName="PromoDO" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false"></table>-->
</context>
</generatorConfiguration>