Commit 32ea87b0 authored by Junling Bu's avatar Junling Bu
Browse files

[litemall-admin, litemall-admin-api]: 管理后台调整

parent a86ec8b6
...@@ -10,17 +10,17 @@ public class GoodsAllinone { ...@@ -10,17 +10,17 @@ public class GoodsAllinone {
LitemallGoodsSpecification[] specifications; LitemallGoodsSpecification[] specifications;
LitemallGoodsAttribute[] attributes; LitemallGoodsAttribute[] attributes;
// 这里采用 Product 再转换到 LitemallProduct // 这里采用 Product 再转换到 LitemallProduct
Product[] products; LitemallProduct[] products;
public LitemallGoods getGoods() { public LitemallGoods getGoods() {
return goods; return goods;
} }
public Product[] getProducts() { public LitemallProduct[] getProducts() {
return products; return products;
} }
public void setProducts(Product[] products) { public void setProducts(LitemallProduct[] products) {
this.products = products; this.products = products;
} }
......
...@@ -93,42 +93,13 @@ public class AdminCategoryController { ...@@ -93,42 +93,13 @@ public class AdminCategoryController {
// 所有一级分类目录 // 所有一级分类目录
List<LitemallCategory> l1CatList = categoryService.queryL1(); List<LitemallCategory> l1CatList = categoryService.queryL1();
HashMap<Integer, String> data = new HashMap<>(l1CatList.size()); List<Map<String, Object>> data = new ArrayList<>(l1CatList.size());
for(LitemallCategory category : l1CatList){ for(LitemallCategory category : l1CatList){
data.put(category.getId(), category.getName()); Map<String, Object> d = new HashMap<>(2);
d.put("value", category.getId());
d.put("label", category.getName());
data.add(d);
} }
return ResponseUtil.ok(data); return ResponseUtil.ok(data);
} }
@GetMapping("/list2")
public Object list2(@LoginAdmin Integer adminId) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
List<LitemallCategory> l1CatList = categoryService.queryL1();
List<CatVo> list = new ArrayList<>(l1CatList.size());
for(LitemallCategory l1 : l1CatList){
CatVo l1CatVo = new CatVo();
l1CatVo.setValue(l1.getId());
l1CatVo.setLabel(l1.getName());
List<LitemallCategory> l2CatList = categoryService.queryByPid(l1.getId());
List<CatVo> children = new ArrayList<>(l2CatList.size());
for(LitemallCategory l2 : l2CatList) {
CatVo l2CatVo = new CatVo();
l2CatVo.setValue(l2.getId());
l2CatVo.setLabel(l2.getName());
children.add(l2CatVo);
}
l1CatVo.setChildren(children);
list.add(l1CatVo);
}
return ResponseUtil.ok(list);
}
} }
package org.linlinjava.litemall.admin.web;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.db.domain.LitemallGoodsAttribute;
import org.linlinjava.litemall.db.service.LitemallGoodsAttributeService;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/goods-attribute")
public class AdminGoodsAttributeController {
private final Log logger = LogFactory.getLog(AdminGoodsAttributeController.class);
@Autowired
private LitemallGoodsAttributeService goodsAttributeService;
@GetMapping("/list")
public Object list(@LoginAdmin Integer adminId,
Integer goodsId,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
String sort, String order){
if(adminId == null){
return ResponseUtil.unlogin();
}
List<LitemallGoodsAttribute> goodsAttributeList = goodsAttributeService.querySelective(goodsId, page, limit, sort, order);
int total = goodsAttributeService.countSelective(goodsId, page, limit, sort, order);
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", goodsAttributeList);
return ResponseUtil.ok(data);
}
@PostMapping("/create")
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsAttribute goodsAttribute){
if(adminId == null){
return ResponseUtil.unlogin();
}
goodsAttributeService.add(goodsAttribute);
return ResponseUtil.ok(goodsAttribute);
}
@GetMapping("/read")
public Object read(@LoginAdmin Integer adminId, Integer id){
if(adminId == null){
return ResponseUtil.unlogin();
}
if(id == null){
return ResponseUtil.badArgument();
}
LitemallGoodsAttribute goodsAttribute = goodsAttributeService.findById(id);
return ResponseUtil.ok(goodsAttribute);
}
@PostMapping("/update")
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsAttribute goodsAttribute){
if(adminId == null){
return ResponseUtil.unlogin();
}
goodsAttributeService.updateById(goodsAttribute);
return ResponseUtil.ok(goodsAttribute);
}
@PostMapping("/delete")
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsAttribute goodsAttribute){
if(adminId == null){
return ResponseUtil.unlogin();
}
goodsAttributeService.deleteById(goodsAttribute.getId());
return ResponseUtil.ok();
}
}
...@@ -6,15 +6,10 @@ import org.apache.commons.logging.LogFactory; ...@@ -6,15 +6,10 @@ import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.annotation.LoginAdmin; import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.admin.dao.GoodsAllinone; import org.linlinjava.litemall.admin.dao.GoodsAllinone;
import org.linlinjava.litemall.admin.dao.Product; import org.linlinjava.litemall.admin.dao.Product;
import org.linlinjava.litemall.db.domain.LitemallGoods; import org.linlinjava.litemall.admin.util.CatVo;
import org.linlinjava.litemall.db.domain.LitemallGoodsAttribute; import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.domain.LitemallGoodsSpecification; import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.domain.LitemallProduct;
import org.linlinjava.litemall.db.service.LitemallGoodsAttributeService;
import org.linlinjava.litemall.db.service.LitemallGoodsService;
import org.linlinjava.litemall.core.util.ResponseUtil; import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.service.LitemallGoodsSpecificationService;
import org.linlinjava.litemall.db.service.LitemallProductService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
...@@ -24,10 +19,7 @@ import org.springframework.web.bind.annotation.*; ...@@ -24,10 +19,7 @@ import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Arrays; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController @RestController
@RequestMapping("/admin/goods") @RequestMapping("/admin/goods")
...@@ -45,6 +37,10 @@ public class AdminGoodsController { ...@@ -45,6 +37,10 @@ public class AdminGoodsController {
private LitemallGoodsAttributeService attributeService; private LitemallGoodsAttributeService attributeService;
@Autowired @Autowired
private LitemallProductService productService; private LitemallProductService productService;
@Autowired
private LitemallCategoryService categoryService;
@Autowired
private LitemallBrandService brandService;
@GetMapping("/list") @GetMapping("/list")
public Object list(@LoginAdmin Integer adminId, public Object list(@LoginAdmin Integer adminId,
...@@ -65,36 +61,71 @@ public class AdminGoodsController { ...@@ -65,36 +61,71 @@ public class AdminGoodsController {
return ResponseUtil.ok(data); return ResponseUtil.ok(data);
} }
@PostMapping("/create") /*
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallGoods goods){ * TODO
* 目前商品修改的逻辑是
* 1. 更新litemall_goods表
* 2. 逻辑删除litemall_goods_specification、litemall_goods_attribute、litemall_product
* 3. 添加litemall_goods_specification、litemall_goods_attribute、litemall_product
*
* 这里商品三个表的数据采用删除再跟新的策略是因为
* 商品编辑页面,管理员可以添加删除商品规格、添加删除商品属性,因此这里仅仅更新表是不可能的,
* 因此这里只能删除所有旧的数据,然后添加新的数据
*/
@PostMapping("/update")
public Object update(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone){
if(adminId == null){ if(adminId == null){
return ResponseUtil.unlogin(); return ResponseUtil.unlogin();
} }
goodsService.add(goods);
return ResponseUtil.ok(goods);
}
@GetMapping("/read") LitemallGoods goods = goodsAllinone.getGoods();
public Object read(@LoginAdmin Integer adminId, Integer id){ LitemallGoodsAttribute[] attributes = goodsAllinone.getAttributes();
if(adminId == null){ LitemallGoodsSpecification[] specifications = goodsAllinone.getSpecifications();
return ResponseUtil.unlogin(); LitemallProduct[] products = goodsAllinone.getProducts();
}
if(id == null){ // 开启事务管理
return ResponseUtil.badArgument(); DefaultTransactionDefinition def = new DefaultTransactionDefinition();
} def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
LitemallGoods goods = goodsService.findById(id); // 商品基本信息表litemall_goods
return ResponseUtil.ok(goods); goodsService.updateById(goods);
}
@PostMapping("/update") Integer gid = goods.getId();
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallGoods goods){ specificationService.deleteByGid(gid);
if(adminId == null){ attributeService.deleteByGid(gid);
return ResponseUtil.unlogin(); productService.deleteByGid(gid);
// 商品规格表litemall_goods_specification
Map<String, Integer> specIds = new HashMap<>();
for(LitemallGoodsSpecification specification : specifications){
specification.setGoodsId(goods.getId());
specification.setAddTime(LocalDateTime.now());
specificationService.add(specification);
specIds.put(specification.getValue(), specification.getId());
}
// 商品参数表litemall_goods_attribute
for(LitemallGoodsAttribute attribute : attributes){
attribute.setGoodsId(goods.getId());
attribute.setAddTime(LocalDateTime.now());
attributeService.add(attribute);
}
// 商品货品表litemall_product
for(LitemallProduct product : products){
product.setGoodsId(goods.getId());
product.setAddTime(LocalDateTime.now());
productService.add(product);
}
} catch (Exception ex) {
txManager.rollback(status);
logger.error("系统内部错误", ex);
} }
goodsService.updateById(goods); txManager.commit(status);
return ResponseUtil.ok(goods);
return ResponseUtil.ok();
} }
@PostMapping("/delete") @PostMapping("/delete")
...@@ -102,12 +133,28 @@ public class AdminGoodsController { ...@@ -102,12 +133,28 @@ public class AdminGoodsController {
if(adminId == null){ if(adminId == null){
return ResponseUtil.unlogin(); return ResponseUtil.unlogin();
} }
goodsService.deleteById(goods.getId());
// 开启事务管理
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
Integer gid = goods.getId();
goodsService.deleteById(gid);
specificationService.deleteByGid(gid);
attributeService.deleteByGid(gid);
productService.deleteByGid(gid);
} catch (Exception ex) {
txManager.rollback(status);
logger.error("系统内部错误", ex);
}
txManager.commit(status);
return ResponseUtil.ok(); return ResponseUtil.ok();
} }
@PostMapping("/publish") @PostMapping("/create")
public Object publish(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone){ public Object create(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone){
if(adminId == null){ if(adminId == null){
return ResponseUtil.unlogin(); return ResponseUtil.unlogin();
} }
...@@ -115,7 +162,7 @@ public class AdminGoodsController { ...@@ -115,7 +162,7 @@ public class AdminGoodsController {
LitemallGoods goods = goodsAllinone.getGoods(); LitemallGoods goods = goodsAllinone.getGoods();
LitemallGoodsAttribute[] attributes = goodsAllinone.getAttributes(); LitemallGoodsAttribute[] attributes = goodsAllinone.getAttributes();
LitemallGoodsSpecification[] specifications = goodsAllinone.getSpecifications(); LitemallGoodsSpecification[] specifications = goodsAllinone.getSpecifications();
Product[] products = goodsAllinone.getProducts(); LitemallProduct[] products = goodsAllinone.getProducts();
String name = goods.getName(); String name = goods.getName();
if(goodsService.checkExistByName(name)){ if(goodsService.checkExistByName(name)){
...@@ -149,23 +196,10 @@ public class AdminGoodsController { ...@@ -149,23 +196,10 @@ public class AdminGoodsController {
} }
// 商品货品表litemall_product // 商品货品表litemall_product
for(Product product : products){ for(LitemallProduct product : products){
LitemallProduct litemallProduct = new LitemallProduct(); product.setGoodsId(goods.getId());
litemallProduct.setRetailPrice(product.getPrice()); product.setAddTime(LocalDateTime.now());
litemallProduct.setGoodsNumber(product.getNumber()); productService.add(product);
litemallProduct.setUrl(product.getUrl());
litemallProduct.setGoodsId(goods.getId());
litemallProduct.setAddTime(LocalDateTime.now());
String[] values = product.getSpecifications();
Integer[] ids = new Integer[values.length];
for(int i = 0; i < values.length; i++){
ids[i] = specIds.get(values[i]);
}
Arrays.sort(ids);
litemallProduct.setGoodsSpecificationIds(ids);
productService.add(litemallProduct);
} }
} catch (Exception ex) { } catch (Exception ex) {
txManager.rollback(status); txManager.rollback(status);
...@@ -175,4 +209,86 @@ public class AdminGoodsController { ...@@ -175,4 +209,86 @@ public class AdminGoodsController {
return ResponseUtil.ok(); return ResponseUtil.ok();
} }
@GetMapping("/catAndBrand")
public Object list2(@LoginAdmin Integer adminId) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
// http://element-cn.eleme.io/#/zh-CN/component/cascader
// 管理员设置“所属分类”
List<LitemallCategory> l1CatList = categoryService.queryL1();
List<CatVo> categoryList = new ArrayList<>(l1CatList.size());
for(LitemallCategory l1 : l1CatList){
CatVo l1CatVo = new CatVo();
l1CatVo.setValue(l1.getId());
l1CatVo.setLabel(l1.getName());
List<LitemallCategory> l2CatList = categoryService.queryByPid(l1.getId());
List<CatVo> children = new ArrayList<>(l2CatList.size());
for(LitemallCategory l2 : l2CatList) {
CatVo l2CatVo = new CatVo();
l2CatVo.setValue(l2.getId());
l2CatVo.setLabel(l2.getName());
children.add(l2CatVo);
}
l1CatVo.setChildren(children);
categoryList.add(l1CatVo);
}
// http://element-cn.eleme.io/#/zh-CN/component/select
// 管理员设置“所属品牌商”
List<LitemallBrand> list = brandService.all();
List<Map<String, Object>> brandList = new ArrayList<>(l1CatList.size());
for(LitemallBrand brand : list){
Map<String, Object> b = new HashMap<>(2);
b.put("value", brand.getId());
b.put("label", brand.getName());
brandList.add(b);
}
Map<String, Object> data = new HashMap<>();
data.put("categoryList" ,categoryList);
data.put("brandList", brandList);
return ResponseUtil.ok(data);
}
@GetMapping("/detail")
public Object detail(@LoginAdmin Integer adminId, Integer id) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
if (id == null) {
return ResponseUtil.badArgument();
}
LitemallGoods goods = goodsService.findById(id);
List<LitemallProduct> products = productService.queryByGid(id);
List<LitemallGoodsSpecification> specifications = specificationService.queryByGid(id);
List<LitemallGoodsAttribute> attributes = attributeService.queryByGid(id);
Integer categoryId = goods.getCategoryId();
LitemallCategory category = categoryService.findById(categoryId);
Integer[] categoryIds = new Integer[]{};
if (category != null) {
Integer parentCategoryId = category.getPid();
categoryIds = new Integer[] {parentCategoryId, categoryId};
}
Map<String, Object> data = new HashMap<>();
data.put("goods" ,goods);
data.put("specifications", specifications);
data.put("products", products);
data.put("attributes", attributes);
data.put("categoryIds", categoryIds);
return ResponseUtil.ok(data);
}
} }
package org.linlinjava.litemall.admin.web;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.db.domain.LitemallGoodsSpecification;
import org.linlinjava.litemall.db.service.LitemallGoodsSpecificationService;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/goods-specification")
public class AdminGoodsSpecificationController {
private final Log logger = LogFactory.getLog(AdminGoodsSpecificationController.class);
@Autowired
private LitemallGoodsSpecificationService goodsSpecificationService;
@GetMapping("/list")
public Object list(@LoginAdmin Integer adminId,
Integer goodsId,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
String sort, String order){
if(adminId == null){
return ResponseUtil.unlogin();
}
List<LitemallGoodsSpecification> goodsSpecificationList = goodsSpecificationService.querySelective(goodsId, page, limit, sort, order);
int total = goodsSpecificationService.countSelective(goodsId, page, limit, sort, order);
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", goodsSpecificationList);
return ResponseUtil.ok(data);
}
@PostMapping("/create")
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsSpecification goodsSpecification){
if(adminId == null){
return ResponseUtil.unlogin();
}
goodsSpecification.setAddTime(LocalDateTime.now());
goodsSpecificationService.add(goodsSpecification);
return ResponseUtil.ok(goodsSpecification);
}
@GetMapping("/read")
public Object read(@LoginAdmin Integer adminId, Integer id){
if(adminId == null){
return ResponseUtil.unlogin();
}
if(id == null){
return ResponseUtil.badArgument();
}
LitemallGoodsSpecification goodsSpecification = goodsSpecificationService.findById(id);
return ResponseUtil.ok(goodsSpecification);
}
@PostMapping("/update")
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsSpecification goodsSpecification){
if(adminId == null){
return ResponseUtil.unlogin();
}
goodsSpecificationService.updateById(goodsSpecification);
return ResponseUtil.ok(goodsSpecification);
}
@PostMapping("/delete")
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallGoodsSpecification goodsSpecification){
if(adminId == null){
return ResponseUtil.unlogin();
}
goodsSpecificationService.deleteById(goodsSpecification.getId());
return ResponseUtil.ok();
}
@GetMapping("/volist")
public Object volist(@LoginAdmin Integer adminId, Integer id){
if(adminId == null){
return ResponseUtil.unlogin();
}
if(id == null){
return ResponseUtil.badArgument();
}
Object goodsSpecificationVoList = goodsSpecificationService.getSpecificationVoList(id);
return ResponseUtil.ok(goodsSpecificationVoList);
}
}
...@@ -112,8 +112,8 @@ public class AdminOrderController { ...@@ -112,8 +112,8 @@ public class AdminOrderController {
for (LitemallOrderGoods orderGoods : orderGoodsList) { for (LitemallOrderGoods orderGoods : orderGoodsList) {
Integer productId = orderGoods.getProductId(); Integer productId = orderGoods.getProductId();
LitemallProduct product = productService.findById(productId); LitemallProduct product = productService.findById(productId);
Integer number = product.getGoodsNumber() + orderGoods.getNumber(); Integer number = product.getNumber() + orderGoods.getNumber();
product.setGoodsNumber(number); product.setNumber(number);
productService.updateById(product); productService.updateById(product);
} }
} catch (Exception ex) { } catch (Exception ex) {
...@@ -162,7 +162,7 @@ public class AdminOrderController { ...@@ -162,7 +162,7 @@ public class AdminOrderController {
order.setOrderStatus(OrderUtil.STATUS_SHIP); order.setOrderStatus(OrderUtil.STATUS_SHIP);
order.setShipSn(shipSn); order.setShipSn(shipSn);
order.setShipChannel(shipChannel); order.setShipChannel(shipChannel);
order.setShipStartTime(LocalDateTime.now()); order.setShipTime(LocalDateTime.now());
orderService.update(order); orderService.update(order);
return ResponseUtil.ok(); return ResponseUtil.ok();
...@@ -207,8 +207,8 @@ public class AdminOrderController { ...@@ -207,8 +207,8 @@ public class AdminOrderController {
for (LitemallOrderGoods orderGoods : orderGoodsList) { for (LitemallOrderGoods orderGoods : orderGoodsList) {
Integer productId = orderGoods.getProductId(); Integer productId = orderGoods.getProductId();
LitemallProduct product = productService.findById(productId); LitemallProduct product = productService.findById(productId);
Integer number = product.getGoodsNumber() + orderGoods.getNumber(); Integer number = product.getNumber() + orderGoods.getNumber();
product.setGoodsNumber(number); product.setNumber(number);
productService.updateById(product); productService.updateById(product);
} }
} catch (Exception ex) { } catch (Exception ex) {
...@@ -242,9 +242,9 @@ public class AdminOrderController { ...@@ -242,9 +242,9 @@ public class AdminOrderController {
List<LitemallOrder> orderList = orderService.queryUnconfirm(); List<LitemallOrder> orderList = orderService.queryUnconfirm();
for(LitemallOrder order : orderList){ for(LitemallOrder order : orderList){
LocalDateTime shipEnd = order.getShipEndTime(); LocalDateTime ship = order.getShipTime();
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
LocalDateTime expired = shipEnd.plusDays(7); LocalDateTime expired = ship.plusDays(7);
if(expired.isAfter(now)){ if(expired.isAfter(now)){
continue; continue;
} }
......
package org.linlinjava.litemall.admin.web;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.db.domain.LitemallGoods;
import org.linlinjava.litemall.db.domain.LitemallProduct;
import org.linlinjava.litemall.db.service.LitemallGoodsService;
import org.linlinjava.litemall.db.service.LitemallGoodsSpecificationService;
import org.linlinjava.litemall.db.service.LitemallProductService;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/product")
public class AdminProductController {
private final Log logger = LogFactory.getLog(AdminProductController.class);
@Autowired
private LitemallProductService productService;
@Autowired
private LitemallGoodsService goodsService;
@Autowired
private LitemallGoodsSpecificationService goodsSpecificationService;
@GetMapping("/list")
public Object list(@LoginAdmin Integer adminId,
Integer goodsId,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "limit", defaultValue = "10") Integer limit,
String sort, String order){
if(adminId == null){
return ResponseUtil.unlogin();
}
List<LitemallProduct> productList = productService.querySelective(goodsId, page, limit, sort, order);
int total = productService.countSelective(goodsId, page, limit, sort, order);
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", productList);
return ResponseUtil.ok(data);
}
/**
*
* @param adminId
* @param litemallProduct
* @return
*/
@PostMapping("/create")
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallProduct litemallProduct){
if(adminId == null){
return ResponseUtil.unlogin();
}
Integer goodsId = litemallProduct.getGoodsId();
if(goodsId == null){
return ResponseUtil.badArgument();
}
LitemallGoods goods = goodsService.findById(goodsId);
if(goods == null){
return ResponseUtil.badArgumentValue();
}
List<LitemallProduct> productList = productService.queryByGid(goodsId);
if(productList.size() != 0){
return ResponseUtil.badArgumentValue();
}
Integer[] goodsSpecificationIds = goodsSpecificationService.queryIdsByGid(goodsId);
if(goodsSpecificationIds.length == 0) {
return ResponseUtil.serious();
}
LitemallProduct product = new LitemallProduct();
product.setGoodsId(goodsId);
product.setGoodsNumber(0);
product.setRetailPrice(new BigDecimal(0.00));
product.setGoodsSpecificationIds(goodsSpecificationIds);
product.setAddTime(LocalDateTime.now());
productService.add(product);
return ResponseUtil.ok();
}
@GetMapping("/read")
public Object read(@LoginAdmin Integer adminId, Integer id){
if(adminId == null){
return ResponseUtil.unlogin();
}
if(id == null){
return ResponseUtil.badArgument();
}
LitemallProduct product = productService.findById(id);
return ResponseUtil.ok(product);
}
@PostMapping("/update")
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallProduct product){
if(adminId == null){
return ResponseUtil.unlogin();
}
productService.updateById(product);
return ResponseUtil.ok(product);
}
@PostMapping("/delete")
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallProduct product){
if(adminId == null){
return ResponseUtil.unlogin();
}
productService.deleteById(product.getId());
return ResponseUtil.ok();
}
}
...@@ -46,11 +46,3 @@ export function deleteCategory(data) { ...@@ -46,11 +46,3 @@ export function deleteCategory(data) {
data data
}) })
} }
export function listCategory2(query) {
return request({
url: '/category/list2',
method: 'get',
params: query
})
}
import request from '@/utils/request'
export function listGoodsAttribute(query) {
return request({
url: '/goods-attribute/list',
method: 'get',
params: query
})
}
export function createGoodsAttribute(data) {
return request({
url: '/goods-attribute/create',
method: 'post',
data
})
}
export function readGoodsAttribute(data) {
return request({
url: '/goods-attribute/read',
method: 'get',
data
})
}
export function updateGoodsAttribute(data) {
return request({
url: '/goods-attribute/update',
method: 'post',
data
})
}
export function deleteGoodsAttribute(data) {
return request({
url: '/goods-attribute/delete',
method: 'post',
data
})
}
import request from '@/utils/request'
export function listGoodsSpecification(query) {
return request({
url: '/goods-specification/list',
method: 'get',
params: query
})
}
export function createGoodsSpecification(data) {
return request({
url: '/goods-specification/create',
method: 'post',
data
})
}
export function readGoodsSpecification(data) {
return request({
url: '/goods-specification/read',
method: 'get',
data
})
}
export function updateGoodsSpecification(data) {
return request({
url: '/goods-specification/update',
method: 'post',
data
})
}
export function deleteGoodsSpecification(data) {
return request({
url: '/goods-specification/delete',
method: 'post',
data
})
}
export function listGoodsSpecificationVo(query) {
return request({
url: '/goods-specification/volist',
method: 'get',
params: query
})
}
...@@ -8,42 +8,41 @@ export function listGoods(query) { ...@@ -8,42 +8,41 @@ export function listGoods(query) {
}) })
} }
export function createGoods(data) { export function deleteGoods(data) {
return request({ return request({
url: '/goods/create', url: '/goods/delete',
method: 'post', method: 'post',
data data
}) })
} }
export function readGoods(data) { export function publishGoods(data) {
return request({ return request({
url: '/goods/read', url: '/goods/create',
method: 'get', method: 'post',
data data
}) })
} }
export function updateGoods(data) { export function detailGoods(id) {
return request({ return request({
url: '/goods/update', url: '/goods/detail',
method: 'post', method: 'get',
data params: { id }
}) })
} }
export function deleteGoods(data) { export function editGoods(data) {
return request({ return request({
url: '/goods/delete', url: '/goods/update',
method: 'post', method: 'post',
data data
}) })
} }
export function publishGoods(data) { export function listCatAndBrand() {
return request({ return request({
url: '/goods/publish', url: '/goods/catAndBrand',
method: 'post', method: 'get'
data
}) })
} }
import request from '@/utils/request'
export function listProduct(query) {
return request({
url: '/product/list',
method: 'get',
params: query
})
}
export function createProduct(data) {
return request({
url: '/product/create',
method: 'post',
data
})
}
export function readProduct(data) {
return request({
url: '/product/read',
method: 'get',
data
})
}
export function updateProduct(data) {
return request({
url: '/product/update',
method: 'post',
data
})
}
export function deleteProduct(data) {
return request({
url: '/product/delete',
method: 'post',
data
})
}
...@@ -98,12 +98,10 @@ export const asyncRouterMap = [ ...@@ -98,12 +98,10 @@ export const asyncRouterMap = [
icon: 'chart' icon: 'chart'
}, },
children: [ children: [
{ path: 'publish', component: _import('goods/publish'), name: 'publish', meta: { title: '商品上架', noCache: true }}, { path: 'list', component: _import('goods/list'), name: 'goodsList', meta: { title: '商品列表', noCache: true }},
{ path: 'goods', component: _import('goods/goods'), name: 'goods', meta: { title: '商品管理', noCache: true }}, { path: 'create', component: _import('goods/create'), name: 'goodsCreate', meta: { title: '商品上架', noCache: true }},
{ path: 'attribute', component: _import('goods/attribute'), name: 'attribute', meta: { title: '商品参数', noCache: true }}, { path: 'edit', component: _import('goods/edit'), name: 'goodsEdit', meta: { title: '商品编辑', noCache: true }, hidden: true },
{ path: 'specification', component: _import('goods/specification'), name: 'specification', meta: { title: '商品规格', noCache: true }}, { path: 'comment', component: _import('goods/comment'), name: 'goodsComment', meta: { title: '商品评论', noCache: true }}
{ path: 'product', component: _import('goods/product'), name: 'product', meta: { title: '货品管理', noCache: true }},
{ path: 'comment', component: _import('goods/comment'), name: 'comment', meta: { title: '用户评论', noCache: true }}
] ]
}, },
......
...@@ -15,25 +15,25 @@ ...@@ -15,25 +15,25 @@
<!-- 查询结果 --> <!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row> <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row>
<el-table-column align="center" width="150px" label="评论ID" prop="id" sortable> <el-table-column align="center" label="评论ID" prop="id">
</el-table-column> </el-table-column>
<el-table-column align="center" width="100px" label="用户ID" prop="userId"> <el-table-column align="center" label="用户ID" prop="userId">
</el-table-column> </el-table-column>
<el-table-column align="center" width="100px" label="商品ID" prop="valueId"> <el-table-column align="center" label="商品ID" prop="valueId">
</el-table-column> </el-table-column>
<el-table-column align="center" min-width="200px" label="评论内容" prop="content"> <el-table-column align="center" min-width="200" label="评论内容" prop="content">
</el-table-column> </el-table-column>
<el-table-column align="center" min-width="200px" label="评论图片" prop="picUrls"> <el-table-column align="center" min-width="200" label="评论图片" prop="picUrls">
</el-table-column> </el-table-column>
<el-table-column align="center" min-width="100px" label="时间" prop="addTime"> <el-table-column align="center" min-width="100" label="时间" prop="addTime">
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width"> <el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button> <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button> <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
......
...@@ -40,27 +40,20 @@ ...@@ -40,27 +40,20 @@
</el-form-item> </el-form-item>
<el-form-item label="首页主图"> <el-form-item label="首页主图">
<el-upload class="avatar-uploader" :action='uploadPath' list-type="picture-card" :show-file-list="false" accept=".jpg,.jpeg,.png,.gif" :on-success="uploadListPicUrl"> <el-upload class="avatar-uploader" :action='uploadPath' list-type="picture-card" :show-file-list="false" accept=".jpg,.jpeg,.png,.gif" :on-success="uploadPicUrl">
<img v-if="goods.listPicUrl" :src="goods.listPicUrl" class="avatar"> <img v-if="goods.picUrl" :src="goods.picUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i> <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
<el-form-item label="商品页主图">
<el-upload class="avatar-uploader" :action='uploadPath' list-type="picture-card" :show-file-list="false" accept=".jpg,.jpeg,.png,.gif" :on-success="uploadPrimaryPicUrl">
<img v-if="goods.primaryPicUrl" :src="goods.primaryPicUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item label="宣传画廊"> <el-form-item label="宣传画廊">
<el-upload :action='uploadPath' :limit='5' multiple accept=".jpg,.jpeg,.png,.gif" :file-list="galleryFileList" list-type="picture-card" :on-exceed='uploadOverrun' :on-success="handleGalleryUrl" :on-remove="handleRemove"> <el-upload :action='uploadPath' :limit='5' multiple accept=".jpg,.jpeg,.png,.gif" list-type="picture-card" :on-exceed='uploadOverrun' :on-success="handleGalleryUrl" :on-remove="handleRemove">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
<el-form-item label="商品单位"> <el-form-item label="商品单位">
<el-input v-model="goods.goodsUnit" placeholder="件 / 个 / 盒"></el-input> <el-input v-model="goods.unit" placeholder="件 / 个 / 盒"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="关键字"> <el-form-item label="关键字">
...@@ -77,15 +70,18 @@ ...@@ -77,15 +70,18 @@
</el-form-item> </el-form-item>
<el-form-item label="所属品牌商"> <el-form-item label="所属品牌商">
<el-input v-model="goods.brandId"></el-input> <el-select v-model="goods.brandId">
<el-option v-for="item in brandList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="商品简介"> <el-form-item label="商品简介">
<el-input v-model="goods.goodsBrief"></el-input> <el-input v-model="goods.brief"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="商品详细介绍"> <el-form-item label="商品详细介绍">
<editor :init="editorInit" v-model="goods.goodsDesc"></editor> <editor :init="editorInit" v-model="goods.desc"></editor>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
...@@ -161,7 +157,7 @@ ...@@ -161,7 +157,7 @@
</el-table-column> </el-table-column>
<el-table-column property="number" width="100" label="货品数量"> <el-table-column property="number" width="100" label="货品数量">
</el-table-column> </el-table-column>
<el-table-column property="price" width="100" label="货品图片"> <el-table-column property="url" width="100" label="货品图片">
<template slot-scope="scope"> <template slot-scope="scope">
<img :src="scope.row.url" width="40" v-if="scope.row.url"/> <img :src="scope.row.url" width="40" v-if="scope.row.url"/>
</template> </template>
...@@ -186,7 +182,7 @@ ...@@ -186,7 +182,7 @@
<el-form-item label="货品数量" prop="number"> <el-form-item label="货品数量" prop="number">
<el-input v-model="productForm.number"></el-input> <el-input v-model="productForm.number"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="货品图片" prop="picUrl"> <el-form-item label="货品图片" prop="url">
<el-upload class="avatar-uploader" :action='uploadPath' list-type="picture-card" :show-file-list="false" accept=".jpg,.jpeg,.png,.gif" :on-success="uploadProductUrl"> <el-upload class="avatar-uploader" :action='uploadPath' list-type="picture-card" :show-file-list="false" accept=".jpg,.jpeg,.png,.gif" :on-success="uploadProductUrl">
<img v-if="productForm.url" :src="productForm.url" class="avatar"> <img v-if="productForm.url" :src="productForm.url" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i> <i v-else class="el-icon-plus avatar-uploader-icon"></i>
...@@ -277,14 +273,13 @@ ...@@ -277,14 +273,13 @@
</style> </style>
<script> <script>
import { publishGoods } from '@/api/goods' import { publishGoods, listCatAndBrand } from '@/api/goods'
import { createStorage, uploadPath } from '@/api/storage' import { createStorage, uploadPath } from '@/api/storage'
import { listCategory2 } from '@/api/category'
import Editor from '@tinymce/tinymce-vue' import Editor from '@tinymce/tinymce-vue'
import { MessageBox } from 'element-ui' import { MessageBox } from 'element-ui'
export default { export default {
name: 'GoodsAdd', name: 'GoodsCreate',
components: { Editor }, components: { Editor },
data() { data() {
return { return {
...@@ -292,26 +287,9 @@ export default { ...@@ -292,26 +287,9 @@ export default {
newKeywordVisible: false, newKeywordVisible: false,
newKeyword: '', newKeyword: '',
keywords: [], keywords: [],
galleryFileList: [],
categoryList: [], categoryList: [],
goods: { brandList: [],
id: undefined, goods: { gallery: [] },
goodsSn: undefined,
name: undefined,
counterPrice: undefined,
retailPrice: undefined,
isHot: false,
isNew: true,
isOnSale: true,
listPicUrl: undefined,
primaryPicUrl: undefined,
goodsBrief: undefined,
goodsDesc: '',
keywords: '',
gallery: [],
categoryId: undefined,
brandId: undefined
},
specVisiable: false, specVisiable: false,
specForm: { specification: '', value: '', picUrl: '' }, specForm: { specification: '', value: '', picUrl: '' },
multipleSpec: false, multipleSpec: false,
...@@ -343,12 +321,13 @@ export default { ...@@ -343,12 +321,13 @@ export default {
} }
}, },
created() { created() {
this.getCatList() this.init()
}, },
methods: { methods: {
getCatList: function() { init: function() {
listCategory2().then(response => { listCatAndBrand().then(response => {
this.categoryList = response.data.data this.categoryList = response.data.data.categoryList
this.brandList = response.data.data.brandList
}) })
}, },
handleCategoryChange(value) { handleCategoryChange(value) {
...@@ -371,7 +350,7 @@ export default { ...@@ -371,7 +350,7 @@ export default {
type: 'success', type: 'success',
duration: 2000 duration: 2000
}) })
this.$router.push({ path: '/goods/goods' }) this.$router.push({ path: '/goods/list' })
}).catch(response => { }).catch(response => {
MessageBox.alert('业务错误:' + response.data.errmsg, '警告', { MessageBox.alert('业务错误:' + response.data.errmsg, '警告', {
confirmButtonText: '确定', confirmButtonText: '确定',
...@@ -398,11 +377,8 @@ export default { ...@@ -398,11 +377,8 @@ export default {
this.newKeywordVisible = false this.newKeywordVisible = false
this.newKeyword = '' this.newKeyword = ''
}, },
uploadPrimaryPicUrl: function(response) { uploadPicUrl: function(response) {
this.goods.primaryPicUrl = response.data.url this.goods.picUrl = response.data.url
},
uploadListPicUrl: function(response) {
this.goods.listPicUrl = response.data.url
}, },
uploadOverrun: function() { uploadOverrun: function() {
this.$message({ this.$message({
......
This diff is collapsed.
<template>
<div class="app-container calendar-list-container">
<!-- 查询和其他操作 -->
<div class="filter-container">
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品编号" v-model="listQuery.goodsSn">
</el-input>
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品名称" v-model="listQuery.name">
</el-input>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
<el-button class="filter-item" type="primary" :loading="downloadLoading" icon="el-icon-download" @click="handleDownload">导出</el-button>
</div>
<!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row>
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" class="demo-table-expand">
<el-form-item label="首页主图">
<span>{{ props.row.listPicUrl }}</span>
</el-form-item>
<el-form-item label="宣传画廊">
<span>{{ props.row.gallery }}</span>
</el-form-item>
<el-form-item label="商品介绍">
<span>{{ props.row.goodsBrief }}</span>
</el-form-item>
<el-form-item label="商品详细介绍">
<span>{{ props.row.goodsDesc }}</span>
</el-form-item>
<el-form-item label="商品主图">
<span>{{ props.row.primaryPicUrl }}</span>
</el-form-item>
<el-form-item label="商品单位">
<span>{{ props.row.goodsUnit }}</span>
</el-form-item>
<el-form-item label="关键字">
<span>{{ props.row.keyword }}</span>
</el-form-item>
<el-form-item label="类目ID">
<span>{{ props.row.categoryId }}</span>
</el-form-item>
<el-form-item label="品牌商ID">
<span>{{ props.row.brandId }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column align="center" width="100px" label="商品ID" prop="id" sortable>
</el-table-column>
<el-table-column align="center" min-width="100px" label="商品编号" prop="goodsSn">
</el-table-column>
<el-table-column align="center" min-width="100px" label="名称" prop="name">
</el-table-column>
<el-table-column align="center" min-width="100px" label="专柜价格" prop="counterPrice">
</el-table-column>
<el-table-column align="center" min-width="100px" label="当前价格" prop="retailPrice">
</el-table-column>
<el-table-column align="center" min-width="100px" label="是否新品" prop="isNew">
<template slot-scope="scope">
<el-tag :type="scope.row.isNew ? 'success' : 'error' ">{{scope.row.isNew ? '新品' : '非新品'}}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" min-width="100px" label="是否热品" prop="isHot">
<template slot-scope="scope">
<el-tag :type="scope.row.isHot ? 'success' : 'error' ">{{scope.row.isHot ? '热品' : '非热品'}}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" min-width="100px" label="是否在售" prop="isOnSale">
<template slot-scope="scope">
<el-tag :type="scope.row.isOnSale ? 'success' : 'error' ">{{scope.row.isOnSale ? '在售' : '未售'}}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.page"
:page-sizes="[10,20,30,50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
<el-tooltip placement="top" content="返回顶部">
<back-to-top :visibilityHeight="100" ></back-to-top>
</el-tooltip>
<!-- 添加或修改对话框 -->
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width: 400px; margin-left:50px;'>
<el-form-item label="商品编号" prop="goodsSn">
<el-input v-model="dataForm.goodsSn"></el-input>
</el-form-item>
<el-form-item label="商品名称" prop="name">
<el-input v-model="dataForm.name"></el-input>
</el-form-item>
<el-form-item label="专柜价格" prop="counterPrice">
<el-input v-model="dataForm.counterPrice"></el-input>
</el-form-item>
<el-form-item label="当前价格" prop="retailPrice">
<el-input v-model="dataForm.retailPrice"></el-input>
</el-form-item>
<el-form-item label="是否新品" prop="isNew">
<el-select v-model="dataForm.isNew" placeholder="请选择">
<el-option label="新品" :value="true">
</el-option>
<el-option label="新品" :value="false">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="是否热品" prop="isHot">
<el-select v-model="dataForm.isHot" placeholder="请选择">
<el-option label="热品" :value="true">
</el-option>
<el-option label="非热品" :value="false">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="是否在售" prop="isOnSale">
<el-select v-model="dataForm.isOnSale" placeholder="请选择">
<el-option label="在售" :value="true">
</el-option>
<el-option label="未售" :value="false">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="首页主图">
<el-input v-model="dataForm.listPicUrl"></el-input>
</el-form-item>
<el-form-item label="宣传画廊">
<el-upload :action='UPLOAD_API' :limit='5' multiple accept=".jpg,.jpeg,.png,.gif" :file-list="galleryFileList" list-type="picture" :on-exceed='uploadOverrun' :on-success="handleGalleryUrl" :on-remove="handleRemove">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item label="商品介绍">
<el-input v-model="dataForm.goodsBrief"></el-input>
</el-form-item>
<el-form-item style="width: 700px;" label="商品详细介绍">
<editor :init="editorInit" v-model="dataForm.goodsDesc"></editor>
</el-form-item>
<el-form-item label="商品主图">
<el-input v-model="dataForm.primaryPicUrl"></el-input>
</el-form-item>
<el-form-item label="商品单位">
<el-input v-model="dataForm.goodsUnit"></el-input>
</el-form-item>
<el-form-item label="关键字">
<el-input v-model="dataForm.keyword"></el-input>
</el-form-item>
<el-form-item label="类目ID">
<el-input v-model="dataForm.categoryId"></el-input>
</el-form-item>
<el-form-item label="品牌商ID">
<el-input v-model="dataForm.brandId"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="updateData">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<style>
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 200px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
}
.el-dialog {
width: 800px;
}
</style>
<script>
import { listGoods, updateGoods, deleteGoods } from '@/api/goods'
import { createStorage } from '@/api/storage'
import BackToTop from '@/components/BackToTop'
import Editor from '@tinymce/tinymce-vue'
export default {
name: 'Goods',
components: { BackToTop, Editor },
data() {
return {
list: [],
galleryFileList: [],
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
goodsSn: undefined,
name: undefined,
sort: '+id'
},
dataForm: {
id: undefined,
goodsSn: undefined,
name: undefined,
counterPrice: undefined,
retailPrice: undefined,
isHot: false,
isNew: true,
isOnSale: true,
listPicUrl: undefined,
primaryPicUrl: undefined,
goodsBrief: undefined,
goodsDesc: '',
keywords: undefined,
gallery: [],
categoryId: undefined,
brandId: undefined
},
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: '编辑',
create: '创建'
},
rules: {
goodsSn: [{ required: true, message: '商品编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '商品名称不能为空', trigger: 'blur' }]
},
downloadLoading: false,
editorInit: {
language: 'zh_CN',
plugins: ['advlist anchor autolink autoresize autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace tabfocus table template textcolor textpattern visualblocks visualchars wordcount'],
toolbar: ['bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript ', 'hr bullist numlist link image charmap preview anchor pagebreak fullscreen media table emoticons forecolor backcolor'],
images_upload_handler: function(blobInfo, success, failure) {
const formData = new FormData()
formData.append('file', blobInfo.blob())
createStorage(formData).then(res => {
success(res.data.data.url)
}).catch(() => {
failure('上传失败,请重新上传')
})
}
}
}
},
created() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listGoods(this.listQuery).then(response => {
this.list = response.data.data.items
this.total = response.data.data.total
this.listLoading = false
}).catch(() => {
this.list = []
this.total = 0
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val
this.getList()
},
resetForm() {
this.galleryFileList = []
this.dataForm = {
id: undefined,
goodsSn: undefined,
name: undefined,
counterPrice: undefined,
retailPrice: undefined,
isHot: false,
isNew: true,
isOnSale: true,
listPicUrl: undefined,
primaryPicUrl: undefined,
goodsBrief: undefined,
goodsDesc: '',
keywords: undefined,
gallery: [],
categoryId: undefined,
brandId: undefined
}
},
filterLevel(value, row) {
return row.level === value
},
uploadOverrun: function() {
this.$message({
type: 'error',
message: '上传文件个数超出限制!最多上传5张图片!'
})
},
handleGalleryUrl(response, file, fileList) {
if (response.errno === 0) {
this.dataForm.gallery.push(response.data.url)
}
},
handleRemove: function(file, fileList) {
for (var i = 0; i < this.dataForm.gallery.length; i++) {
// 这里存在两种情况
// 1. 如果所删除图片是刚刚上传的图片,那么图片地址是file.response.data.url
// 此时的file.url虽然存在,但是是本机地址,而不是远程地址。
// 2. 如果所删除图片是后台返回的已有图片,那么图片地址是file.url
var url
if (file.response === undefined) {
url = file.url
} else {
url = file.response.data.url
}
if (this.dataForm.gallery[i] === url) {
this.dataForm.gallery.splice(i, 1)
}
}
},
handleCreate() {
this.$router.push({ path: '/goods/publish' })
},
handleUpdate(row) {
this.dataForm = Object.assign({}, row)
this.galleryFileList = []
if (this.dataForm.gallery.length > 0) {
for (var i = 0; i < row.gallery.length; i++) {
this.galleryFileList.push({
name: row.gallery[i].substring(row.gallery[i].lastIndexOf('/') + 1),
url: row.gallery[i]
})
}
}
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
updateGoods(this.dataForm).then(() => {
for (const v of this.list) {
if (v.id === this.dataForm.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.dataForm)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleDelete(row) {
deleteGoods(row).then(response => {
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
const index = this.list.indexOf(row)
this.list.splice(index, 1)
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['商品ID', '商品编号', '名称', '专柜价格', '当前价格', '是否新品', '是否热品', '是否在售', '首页主图', '宣传画廊', '商品介绍', '详细介绍', '商品主图', '商品单位', '关键字', '类目ID', '品牌商ID']
const filterVal = ['id', 'goodsSn', 'name', 'counterPrice', 'retailPrice', 'isNew', 'isHot', 'isOnSale', 'listPicUrl', 'gallery', 'goodsBrief', 'goodsDesc', 'primaryPicUrl', 'goodsUnit', 'keywords', 'categoryId', 'brandId']
excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品信息')
this.downloadLoading = false
})
}
}
}
</script>
\ No newline at end of file
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
<!-- 查询和其他操作 --> <!-- 查询和其他操作 -->
<div class="filter-container"> <div class="filter-container">
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品ID" v-model="listQuery.goodsId"> <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品编号" v-model="listQuery.goodsSn">
</el-input>
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品名称" v-model="listQuery.name">
</el-input> </el-input>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button> <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button> <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
...@@ -12,19 +14,75 @@ ...@@ -12,19 +14,75 @@
<!-- 查询结果 --> <!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row> <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row>
<el-table-column align="center" width="150px" label="商品参数ID" prop="id" sortable>
</el-table-column>
<el-table-column align="center" min-width="100px" label="商品ID" prop="goodsId"> <el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" class="table-expand">
<el-form-item label="宣传画廊">
<img class="gallery" v-for="pic in props.row.gallery" :key="pic" :src="pic"/>
</el-form-item>
<el-form-item label="商品介绍">
<span>{{ props.row.brief }}</span>
</el-form-item>
<el-form-item label="商品单位">
<span>{{ props.row.unit }}</span>
</el-form-item>
<el-form-item label="关键字">
<span>{{ props.row.keyword }}</span>
</el-form-item>
<el-form-item label="类目ID">
<span>{{ props.row.categoryId }}</span>
</el-form-item>
<el-form-item label="品牌商ID">
<span>{{ props.row.brandId }}</span>
</el-form-item>
<el-form-item label="商品详细介绍">
<div v-html="props.row.desc"></div>
</el-form-item>
</el-form>
</template>
</el-table-column> </el-table-column>
<el-table-column align="center" min-width="100px" label="商品参数名称" prop="attribute"> <el-table-column align="center" label="商品ID" prop="id">
</el-table-column> </el-table-column>
<el-table-column align="center" min-width="200px" label="商品参数值" prop="value"> <el-table-column align="center" label="商品编号" prop="goodsSn">
</el-table-column> </el-table-column>
<el-table-column align="center" min-width="100" label="名称" prop="name">
</el-table-column>
<el-table-column align="center" property="iconUrl" label="图片">
<template slot-scope="scope">
<img :src="scope.row.picUrl" width="40"/>
</template>
</el-table-column>
<el-table-column align="center" label="专柜价格" prop="counterPrice">
</el-table-column>
<el-table-column align="center" label="当前价格" prop="retailPrice">
</el-table-column>
<el-table-column align="center" label="是否新品" prop="isNew">
<template slot-scope="scope">
<el-tag :type="scope.row.isNew ? 'success' : 'error' ">{{scope.row.isNew ? '新品' : '非新品'}}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="是否热品" prop="isHot">
<template slot-scope="scope">
<el-tag :type="scope.row.isHot ? 'success' : 'error' ">{{scope.row.isHot ? '热品' : '非热品'}}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width"> <el-table-column align="center" label="是否在售" prop="isOnSale">
<template slot-scope="scope">
<el-tag :type="scope.row.isOnSale ? 'success' : 'error' ">{{scope.row.isOnSale ? '在售' : '未售'}}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button> <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button> <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
...@@ -39,61 +97,66 @@ ...@@ -39,61 +97,66 @@
</el-pagination> </el-pagination>
</div> </div>
<!-- 添加或修改对话框 --> <el-tooltip placement="top" content="返回顶部">
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible"> <back-to-top :visibilityHeight="100" ></back-to-top>
<el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width: 400px; margin-left:50px;'> </el-tooltip>
<el-form-item label="商品ID" prop="goodsId">
<el-input v-model="dataForm.goodsId"></el-input>
</el-form-item>
<el-form-item label="商品参数名" prop="attribute">
<el-input v-model="dataForm.attribute"></el-input>
</el-form-item>
<el-form-item label="商品参数值" prop="value">
<el-input v-model="dataForm.value"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button v-if="dialogStatus=='create'" type="primary" @click="createData">确定</el-button>
<el-button v-else type="primary" @click="updateData">确定</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<style>
.table-expand {
font-size: 0;
}
.table-expand label {
width: 100px;
color: #99a9bf;
}
.table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
}
.gallery {
width: 80px;
margin-right: 10px;
}
</style>
<script> <script>
import { listGoodsAttribute, createGoodsAttribute, updateGoodsAttribute, deleteGoodsAttribute } from '@/api/goods-attribute' import { listGoods, deleteGoods } from '@/api/goods'
import BackToTop from '@/components/BackToTop'
export default { export default {
name: 'GoodsAttribute', name: 'GoodsList',
components: { BackToTop },
data() { data() {
return { return {
list: null, list: [],
total: null, total: 0,
listLoading: true, listLoading: true,
listQuery: { listQuery: {
page: 1, page: 1,
limit: 10, limit: 20,
goodsId: undefined, goodsSn: undefined,
name: undefined,
sort: '+id' sort: '+id'
}, },
dataForm: { dataForm: {
id: undefined, id: undefined,
goodsId: undefined, goodsSn: undefined,
attribute: undefined, name: undefined,
value: undefined counterPrice: undefined,
}, retailPrice: undefined,
dialogFormVisible: false, isHot: false,
dialogStatus: '', isNew: true,
textMap: { isOnSale: true,
update: '编辑', picUrl: undefined,
create: '创建' brief: undefined,
}, desc: undefined,
rules: { keywords: undefined,
goodsId: [{ required: true, message: '商品ID不能为空', trigger: 'blur' }], gallery: [],
attribute: [{ required: true, message: '商品参数名称不能为空', trigger: 'blur' }], categoryId: undefined,
value: [{ required: true, message: '商品参数值不能为空', trigger: 'blur' }] brandId: undefined
}, },
downloadLoading: false downloadLoading: false
} }
...@@ -104,7 +167,7 @@ export default { ...@@ -104,7 +167,7 @@ export default {
methods: { methods: {
getList() { getList() {
this.listLoading = true this.listLoading = true
listGoodsAttribute(this.listQuery).then(response => { listGoods(this.listQuery).then(response => {
this.list = response.data.data.items this.list = response.data.data.items
this.total = response.data.data.total this.total = response.data.data.total
this.listLoading = false this.listLoading = false
...@@ -126,70 +189,14 @@ export default { ...@@ -126,70 +189,14 @@ export default {
this.listQuery.page = val this.listQuery.page = val
this.getList() this.getList()
}, },
resetForm() {
this.dataForm = {
id: undefined,
goodsId: undefined,
attribute: undefined,
value: undefined
}
},
handleCreate() { handleCreate() {
this.resetForm() this.$router.push({ path: '/goods/create' })
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
createData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
createGoodsAttribute(this.dataForm).then(response => {
this.list.unshift(response.data.data)
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
}
})
}, },
handleUpdate(row) { handleUpdate(row) {
this.dataForm = Object.assign({}, row) this.$router.push({ path: '/goods/edit', query: { id: row.id }})
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
updateGoodsAttribute(this.dataForm).then(() => {
for (const v of this.list) {
if (v.id === this.dataForm.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.dataForm)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
}
})
}, },
handleDelete(row) { handleDelete(row) {
deleteGoodsAttribute(row).then(response => { deleteGoods(row).then(response => {
this.$notify({ this.$notify({
title: '成功', title: '成功',
message: '删除成功', message: '删除成功',
...@@ -203,12 +210,12 @@ export default { ...@@ -203,12 +210,12 @@ export default {
handleDownload() { handleDownload() {
this.downloadLoading = true this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => { import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['商品参数ID', '商品ID', '商品参数名称', '商品参数值'] const tHeader = ['商品ID', '商品编号', '名称', '专柜价格', '当前价格', '是否新品', '是否热品', '是否在售', '首页主图', '宣传图片列表', '商品介绍', '详细介绍', '商品图片', '商品单位', '关键字', '类目ID', '品牌商ID']
const filterVal = ['id', 'goodsId', 'attribute', 'value'] const filterVal = ['id', 'goodsSn', 'name', 'counterPrice', 'retailPrice', 'isNew', 'isHot', 'isOnSale', 'listPicUrl', 'gallery', 'brief', 'desc', 'picUrl', 'goodsUnit', 'keywords', 'categoryId', 'brandId']
excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品参数信息') excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品信息')
this.downloadLoading = false this.downloadLoading = false
}) })
} }
} }
} }
</script> </script>
\ No newline at end of file
<template>
<div class="app-container calendar-list-container">
<!-- 查询和其他操作 -->
<div class="filter-container">
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品ID" v-model="listQuery.goodsId">
</el-input>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<el-button class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload" :loading="downloadLoading">导出</el-button>
</div>
<!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row>
<el-table-column type="expand">
<template slot-scope="props">
</template>
</el-table-column>
<el-table-column align="center" width="100px" label="货品ID" prop="id" sortable>
</el-table-column>
<el-table-column align="center" min-width="100px" label="商品ID" prop="goodsId">
</el-table-column>
<el-table-column align="center" min-width="150px" label="商品规格ID列表" prop="goodsSpecificationIds">
<template slot-scope="scope">
{{ scope.row.goodsSpecificationIds.join(',') }}
</template>
</el-table-column>
<el-table-column align="center" min-width="100px" label="货品数量" prop="goodsNumber">
</el-table-column>
<el-table-column align="center" min-width="100px" label="货品价格" prop="retailPrice">
</el-table-column>
<el-table-column align="center" min-width="200px" label="货品图片" prop="url">
</el-table-column>
<el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.page"
:page-sizes="[10,20,30,50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
<!-- 修改对话框 -->
<el-dialog title="编辑商品货品" :visible.sync="editDialogFormVisible">
<el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width: 400px; margin-left:50px;'>
<el-form-item label="商品ID" prop="goodsId">
<el-input v-model="dataForm.goodsId" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="商品规格ID列表" prop="goodsSpecificationIds">
<el-input v-model="dataForm.goodsSpecificationIds" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="货品数量" prop="goodsNumber">
<el-input v-model="dataForm.goodsNumber"></el-input>
</el-form-item>
<el-form-item label="货品价格" prop="retailPrice">
<el-input v-model="dataForm.retailPrice"></el-input>
</el-form-item>
<el-form-item label="货品图片" prop="url">
<el-input v-model="dataForm.url"></el-input>
<el-upload action="#" list-type="picture" :show-file-list="false" :limit="1" :http-request="uploadUrl">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogFormVisible = false">取消</el-button>
\ <el-button type="primary" @click="updateData">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<style>
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 200px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
}
</style>
<script>
import { listProduct, updateProduct } from '@/api/product'
import { createStorage } from '@/api/storage'
export default {
name: 'Product',
data() {
return {
list: undefined,
total: undefined,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
goodsId: undefined,
sort: '+id'
},
editDialogFormVisible: false,
dataForm: {
id: undefined,
goodsId: undefined,
goodsSpecificationIds: undefined,
goodsNumber: 0,
retailPrice: 0,
url: undefined
},
rules: {
goodsId: [{ required: true, message: '商品ID不能为空', trigger: 'blur' }],
goodsSpecificationIds: [{ required: true, message: '商品规格ID列表不能为空', trigger: 'blur' }]
},
downloadLoading: false
}
},
created() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listProduct(this.listQuery).then(response => {
this.list = response.data.data.items
this.total = response.data.data.total
this.listLoading = false
}).catch(() => {
this.list = []
this.total = 0
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val
this.getList()
},
resetForm() {
this.dataForm = {
id: undefined,
goodsId: undefined,
goodsSpecificationIds: undefined,
goodsNumber: 0,
retailPrice: 0,
url: undefined
}
},
uploadUrl(item) {
const formData = new FormData()
formData.append('file', item.file)
createStorage(formData).then(res => {
this.dataForm.url = res.data.data.url
}).catch(() => {
this.$message.error('上传失败,请重新上传')
})
},
handleUpdate(row) {
this.dataForm = Object.assign({}, row)
this.editDialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
updateProduct(this.dataForm).then(() => {
for (const v of this.list) {
if (v.id === this.dataForm.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.dataForm)
break
}
}
this.editDialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['货品ID', '商品ID', '商品规格ID列表', '货品数量', '货品价格', '货品图片']
const filterVal = ['id', 'goodsId', 'goodsSpecificationIds', 'goodsNumber', 'retailPrice', 'url']
excel.export_json_to_excel2(tHeader, this.list, filterVal, '货品信息')
this.downloadLoading = false
})
}
}
}
</script>
<template>
<div class="app-container calendar-list-container">
<!-- 查询和其他操作 -->
<div class="filter-container">
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品ID" v-model="listQuery.goodsId">
</el-input>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<el-button class="filter-item" type="primary" :loading="downloadLoading" icon="el-icon-download" @click="handleDownload">导出</el-button>
</div>
<!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row>
<el-table-column align="center" width="150px" label="商品参数ID" prop="id" sortable>
</el-table-column>
<el-table-column align="center" min-width="100px" label="商品ID" prop="goodsId">
</el-table-column>
<el-table-column align="center" min-width="100px" label="商品规格名称" prop="specification">
</el-table-column>
<el-table-column align="center" min-width="200px" label="商品规格值" prop="value">
</el-table-column>
<el-table-column align="center" min-width="200px" label="商品规格图片" prop="picUrl">
</el-table-column>
<el-table-column align="center" label="操作" width="250" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.page"
:page-sizes="[10,20,30,50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
<!-- 修改对话框 -->
<el-dialog title="编辑商品规格" :visible.sync="dialogFormVisible">
<el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width: 400px; margin-left:50px;'>
<el-form-item label="商品ID" prop="goodsId">
<el-input v-model="dataForm.goodsId"></el-input>
</el-form-item>
<el-form-item label="商品规格名" prop="specification">
<el-input v-model="dataForm.specification"></el-input>
</el-form-item>
<el-form-item label="商品规格值" prop="value">
<el-input v-model="dataForm.value"></el-input>
</el-form-item>
<el-form-item label="商品规格图片" prop="picUrl">
<el-input v-model="dataForm.picUrl"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="updateData">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listGoodsSpecification, updateGoodsSpecification } from '@/api/goods-specification'
export default {
name: 'GoodsSpecification',
data() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
page: 1,
limit: 10,
goodsId: undefined,
sort: '+id'
},
dataForm: {
id: undefined,
goodsId: undefined,
specification: undefined,
value: undefined,
picUrl: undefined
},
dialogFormVisible: false,
dialogStatus: '',
rules: {
goodsId: [{ required: true, message: '商品ID不能为空', trigger: 'blur' }],
specification: [{ required: true, message: '商品规格名称不能为空', trigger: 'blur' }],
value: [{ required: true, message: '商品规格值不能为空', trigger: 'blur' }]
},
downloadLoading: false
}
},
created() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listGoodsSpecification(this.listQuery).then(response => {
this.list = response.data.data.items
this.total = response.data.data.total
this.listLoading = false
}).catch(() => {
this.list = []
this.total = 0
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val
this.getList()
},
resetForm() {
this.dataForm = {
id: undefined,
goodsId: undefined,
specification: undefined,
value: undefined,
picUrl: undefined
}
},
handleUpdate(row) {
this.dataForm = Object.assign({}, row)
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
updateGoodsSpecification(this.dataForm).then(() => {
for (const v of this.list) {
if (v.id === this.dataForm.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.dataForm)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['商品规格ID', '商品ID', '商品规格名称', '商品规格值', '商品规格图片']
const filterVal = ['id', 'goodsId', 'specification', 'value', 'picUrl']
excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品规格信息')
this.downloadLoading = false
})
}
}
}
</script>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment