mirror of
https://gitee.com/coder-xiaomo/flashsale
synced 2025-01-10 11:48:14 +08:00
商品模型-商品创建实现
This commit is contained in:
parent
65a5688804
commit
14f999e598
@ -11,7 +11,7 @@
|
||||
Target Server Version : 50726
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 03/03/2022 13:13:05
|
||||
Date: 03/03/2022 15:29:13
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@ -26,14 +26,15 @@ CREATE TABLE `item_info` (
|
||||
`title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`price` decimal(10, 2) NOT NULL DEFAULT 0.00,
|
||||
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
|
||||
`sales` int(11) NOT NULL,
|
||||
`sales` int(11) NOT NULL DEFAULT 0,
|
||||
`img_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of item_info
|
||||
-- ----------------------------
|
||||
INSERT INTO `item_info` VALUES (1, 'item-h7p0wt-22680', 22.00, '0sddhs4aeowc26638j5fp2ox', 0, 'https://domain.com/pic/190ghi.jpg');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for item_stock
|
||||
@ -46,11 +47,12 @@ CREATE TABLE `item_stock` (
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `item_id`(`item_id`) USING BTREE,
|
||||
CONSTRAINT `item_stock_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `item_info` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of item_stock
|
||||
-- ----------------------------
|
||||
INSERT INTO `item_stock` VALUES (1, 140, 1);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_info
|
||||
|
119
frontend/createitem.html
Normal file
119
frontend/createitem.html
Normal file
@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<link href="static/assets/global/plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="static/assets/global/css/components.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="static/assets/admin/pages/css/login.css" rel="stylesheet" type="text/css"/>
|
||||
<script src="./static/assets/global/plugins/jquery-1.11.0.min.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body class="login">
|
||||
<div class="content">
|
||||
<h3 class="form-title">创建商品</h3>
|
||||
<div class="from-group">
|
||||
<label class="control-label">商品名</label>
|
||||
<div>
|
||||
<input class="form-control" type="text" placeholder="商品名" name="title" id="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="from-group">
|
||||
<label class="control-label">商品描述</label>
|
||||
<div>
|
||||
<input class="form-control" type="text" placeholder="商品描述" name="description" id="description">
|
||||
</div>
|
||||
</div>
|
||||
<div class="from-group">
|
||||
<label class="control-label">价格</label>
|
||||
<div>
|
||||
<input class="form-control" type="text" placeholder="价格" name="price" id="price">
|
||||
</div>
|
||||
</div>
|
||||
<div class="from-group">
|
||||
<label class="control-label">图片</label>
|
||||
<div>
|
||||
<input class="form-control" type="text" placeholder="图片" name="imgUrl" id="imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
<div class="from-group">
|
||||
<label class="control-label">库存</label>
|
||||
<div>
|
||||
<input class="form-control" type="text" placeholder="库存" name="stock" id="stock">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button class="btn blue" id="create" type="submit">
|
||||
创建商品
|
||||
</button>
|
||||
<a href="getotp.html?quickDebug">获取验证码</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function () {
|
||||
$("#create").on("click", function () {
|
||||
var title = $("#title").val();
|
||||
var description = $("#description").val();
|
||||
var imgUrl = $("#imgUrl").val();
|
||||
var price = $("#price").val();
|
||||
var stock = $("#stock").val();
|
||||
|
||||
if (title == null || title == "") {
|
||||
alert("商品名不能为空");
|
||||
return false; // 捕获onclick事件,不让他传递到上一层
|
||||
}
|
||||
if (description == null || description == "") {
|
||||
alert("商品描述不能为空");
|
||||
return false; // 捕获onclick事件,不让他传递到上一层
|
||||
}
|
||||
if (imgUrl == null || imgUrl == "") {
|
||||
alert("图片Url不能为空");
|
||||
return false; // 捕获onclick事件,不让他传递到上一层
|
||||
}
|
||||
if (price == null || price == "") {
|
||||
alert("价格不能为空");
|
||||
return false; // 捕获onclick事件,不让他传递到上一层
|
||||
}
|
||||
if (stock == null || stock == "") {
|
||||
alert("库存不能为空");
|
||||
return false; // 捕获onclick事件,不让他传递到上一层
|
||||
}
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
contentType: "application/x-www-form-urlencoded",
|
||||
url: "http://localhost:8090/item/create",
|
||||
data: {
|
||||
"title": title,
|
||||
"description": description,
|
||||
"imgUrl": imgUrl,
|
||||
"price": price,
|
||||
"stock": stock,
|
||||
},
|
||||
xhrFields: {withCredentials: true},
|
||||
success: function (data) {
|
||||
if (data.status == "success") {
|
||||
alert("创建成功");
|
||||
} else {
|
||||
alert("创建失败,原因为" + data.data.errMsg);
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
alert("创建失败,原因为" + data.responseText);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
function filldata() {
|
||||
const date = new Date();
|
||||
$("#title").val("item-" + Math.random().toString(36).slice(-6) + "-" + date.getSeconds() + date.getMilliseconds());
|
||||
$("#description").val(Math.random().toString(36).slice(-6) + Math.random().toString(36).slice(-6) + Math.random().toString(36).slice(-6) + Math.random().toString(36).slice(-6));
|
||||
$("#imgUrl").val("https://domain.com/pic/" + Math.random().toString(36).slice(-6) + ".jpg");
|
||||
$("#price").val(Math.round(Math.random() * (500 - 1) + 1));
|
||||
$("#stock").val(Math.round(Math.random() * (1000 - 1) + 1));
|
||||
}
|
||||
|
||||
filldata();
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,53 @@
|
||||
package com.cxyxiaomo.flashsale.controller;
|
||||
|
||||
import com.cxyxiaomo.flashsale.controller.viewobject.ItemVO;
|
||||
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.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;
|
||||
|
||||
@Controller("/item")
|
||||
@RequestMapping("/item")
|
||||
@CrossOrigin(allowedHeaders = "*", allowCredentials = "true")
|
||||
public class ItemController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
// 创建商品的Controller
|
||||
@RequestMapping(value = "/create", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
|
||||
@ResponseBody
|
||||
public CommonReturnType createItem(@RequestParam(name = "title") String title,
|
||||
@RequestParam(name = "description") String description,
|
||||
@RequestParam(name = "price") BigDecimal price,
|
||||
@RequestParam(name = "stock") Integer stock,
|
||||
@RequestParam(name = "imgUrl") String imgUrl) throws BusinessException {
|
||||
// 封装Service请求用来创建商品
|
||||
ItemModel itemModel = new ItemModel();
|
||||
itemModel.setTitle(title);
|
||||
itemModel.setDescription(description);
|
||||
itemModel.setPrice(price);
|
||||
itemModel.setStock(stock);
|
||||
itemModel.setImgUrl(imgUrl);
|
||||
|
||||
ItemModel itemModelForReturn = itemService.createItem(itemModel);
|
||||
ItemVO itemVO = convertVOFromModel(itemModelForReturn);
|
||||
|
||||
return CommonReturnType.create(itemVO);
|
||||
}
|
||||
|
||||
private ItemVO convertVOFromModel(ItemModel itemModel) {
|
||||
if (itemModel == null) {
|
||||
return null;
|
||||
}
|
||||
ItemVO itemVO = new ItemVO();
|
||||
BeanUtils.copyProperties(itemModel, itemVO);
|
||||
return itemVO;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.cxyxiaomo.flashsale.controller.viewobject;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ItemVO {
|
||||
// 商品价格
|
||||
private Integer id;
|
||||
|
||||
// 商品名称
|
||||
private String title;
|
||||
|
||||
// 商品价格
|
||||
private BigDecimal price;
|
||||
|
||||
// 商品的库存
|
||||
private Integer stock;
|
||||
|
||||
// 商品的描述
|
||||
private String description;
|
||||
|
||||
// 商品的销量
|
||||
private Integer sales;
|
||||
|
||||
// 商品描述图片的URL
|
||||
private String imgUrl;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public BigDecimal getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(BigDecimal price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public Integer getStock() {
|
||||
return stock;
|
||||
}
|
||||
|
||||
public void setStock(Integer stock) {
|
||||
this.stock = stock;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getSales() {
|
||||
return sales;
|
||||
}
|
||||
|
||||
public void setSales(Integer sales) {
|
||||
this.sales = sales;
|
||||
}
|
||||
|
||||
public String getImgUrl() {
|
||||
return imgUrl;
|
||||
}
|
||||
|
||||
public void setImgUrl(String imgUrl) {
|
||||
this.imgUrl = imgUrl;
|
||||
}
|
||||
}
|
@ -35,6 +35,8 @@ public interface ItemStockDOMapper {
|
||||
*/
|
||||
ItemStockDO selectByPrimaryKey(Integer id);
|
||||
|
||||
ItemStockDO selectByItemId(Integer id);
|
||||
|
||||
/**
|
||||
* This method was generated by MyBatis Generator.
|
||||
* This method corresponds to the database table item_stock
|
||||
|
@ -0,0 +1,17 @@
|
||||
package com.cxyxiaomo.flashsale.service;
|
||||
|
||||
import com.cxyxiaomo.flashsale.error.BusinessException;
|
||||
import com.cxyxiaomo.flashsale.service.model.ItemModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ItemService {
|
||||
// 创建商品
|
||||
ItemModel createItem(ItemModel itemModel) throws BusinessException;
|
||||
|
||||
// 商品列表浏览
|
||||
List<ItemModel> listItem();
|
||||
|
||||
// 商品详情浏览
|
||||
ItemModel getItemById(Integer id);
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.cxyxiaomo.flashsale.service.impl;
|
||||
|
||||
import com.cxyxiaomo.flashsale.dao.ItemDOMapper;
|
||||
import com.cxyxiaomo.flashsale.dao.ItemStockDOMapper;
|
||||
import com.cxyxiaomo.flashsale.dataobject.ItemDO;
|
||||
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.model.ItemModel;
|
||||
import com.cxyxiaomo.flashsale.validator.ValidationResult;
|
||||
import com.cxyxiaomo.flashsale.validator.ValidatorImpl;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ItemServiceImpl implements ItemService {
|
||||
|
||||
@Autowired
|
||||
private ValidatorImpl validator;
|
||||
|
||||
@Autowired
|
||||
private ItemDOMapper itemDOMapper;
|
||||
|
||||
@Autowired
|
||||
private ItemStockDOMapper itemStockDOMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ItemModel createItem(ItemModel itemModel) throws BusinessException {
|
||||
// 校验入参
|
||||
ValidationResult result = validator.validate(itemModel);
|
||||
|
||||
if (result.isHasErrors()) {
|
||||
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
|
||||
}
|
||||
|
||||
// 转化 ItemModel -> Data Object
|
||||
ItemDO itemDO = this.convertItemDOFromItemModel(itemModel);
|
||||
|
||||
// 写入数据库
|
||||
itemDOMapper.insertSelective(itemDO);
|
||||
itemModel.setId(itemDO.getId());
|
||||
|
||||
ItemStockDO itemStockDO = this.convertItemStockDOFormItemStockModel(itemModel);
|
||||
|
||||
itemStockDOMapper.insertSelective(itemStockDO);
|
||||
|
||||
// 返回创建完成的对象
|
||||
return this.getItemById(itemModel.getId());
|
||||
}
|
||||
|
||||
private ItemDO convertItemDOFromItemModel(ItemModel itemModel) {
|
||||
if (itemModel == null) {
|
||||
return null;
|
||||
}
|
||||
ItemDO itemDO = new ItemDO();
|
||||
BeanUtils.copyProperties(itemModel, itemDO);
|
||||
|
||||
return itemDO;
|
||||
}
|
||||
|
||||
private ItemStockDO convertItemStockDOFormItemStockModel(ItemModel itemModel) {
|
||||
if (itemModel == null) {
|
||||
return null;
|
||||
}
|
||||
ItemStockDO itemStockDO = new ItemStockDO();
|
||||
itemStockDO.setItemId(itemModel.getId());
|
||||
itemStockDO.setStock(itemModel.getStock());
|
||||
|
||||
return itemStockDO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemModel> listItem() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemModel getItemById(Integer id) {
|
||||
ItemDO itemDO = itemDOMapper.selectByPrimaryKey(id);
|
||||
if (itemDO == null) {
|
||||
return null;
|
||||
}
|
||||
// 操作获得库存数量
|
||||
ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDO.getId());
|
||||
|
||||
// 将Data Object -> Model
|
||||
ItemModel itemModel = convertModelFromDataObject(itemDO, itemStockDO);
|
||||
return itemModel;
|
||||
}
|
||||
|
||||
private ItemModel convertModelFromDataObject(ItemDO itemDO, ItemStockDO itemStockDO) {
|
||||
ItemModel itemModel = new ItemModel();
|
||||
BeanUtils.copyProperties(itemDO, itemModel);
|
||||
itemModel.setStock(itemStockDO.getStock());
|
||||
|
||||
return itemModel;
|
||||
}
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
package com.cxyxiaomo.flashsale.service.model;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ItemModel {
|
||||
@ -7,21 +10,27 @@ public class ItemModel {
|
||||
private Integer id;
|
||||
|
||||
// 商品名称
|
||||
@NotBlank(message = "商品名称不能为空")
|
||||
private String title;
|
||||
|
||||
// 商品价格
|
||||
@NotNull(message = "商品价格不能为空")
|
||||
@Min(value = 0, message = "商品价格必须大于0")
|
||||
private BigDecimal price;
|
||||
|
||||
// 商品的库存
|
||||
@NotNull(message = "库存不能不填")
|
||||
private Integer stock;
|
||||
|
||||
// 商品的描述
|
||||
@NotBlank(message = "商品描述信息不能为空")
|
||||
private String description;
|
||||
|
||||
// 商品的销量
|
||||
private Integer sales;
|
||||
|
||||
// 商品描述图片的URL
|
||||
@NotBlank(message = "商品描述图片不能为空")
|
||||
private String imgUrl;
|
||||
|
||||
public Integer getId() {
|
||||
|
@ -108,4 +108,10 @@
|
||||
item_id = #{itemId,jdbcType=INTEGER}
|
||||
where id = #{id,jdbcType=INTEGER}
|
||||
</update>
|
||||
<select id="selectByItemId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from item_stock
|
||||
where item_id = #{itemId,jdbcType=INTEGER}
|
||||
</select>
|
||||
</mapper>
|
Loading…
Reference in New Issue
Block a user