mirror of
https://github.com/kirklin/kkmall.git
synced 2024-09-20 06:46:15 +08:00
商品品牌管理基础CRUD及数据校验
This commit is contained in:
parent
be70a27905
commit
c742c181e2
|
@ -79,5 +79,6 @@
|
|||
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.23" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:3.11.4" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:servlet-api:2.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -84,5 +84,10 @@
|
|||
<version>${javax.servlet.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>2.0.1.Final</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,26 @@
|
|||
package name.lkk.common.enume;
|
||||
|
||||
public enum OrderStatusEnum {
|
||||
CREATE_NEW(0,"待付款"),
|
||||
PAYED(1,"已付款"),
|
||||
SENDED(2,"已发货"),
|
||||
RECIEVED(3,"已完成"),
|
||||
CANCLED(4,"已取消"),
|
||||
SERVICING(5,"售后中"),
|
||||
SERVICED(6,"售后完成");
|
||||
private Integer code;
|
||||
private String msg;
|
||||
|
||||
OrderStatusEnum(Integer code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package name.lkk.common.exception;
|
||||
|
||||
/**
|
||||
* <p>Title: BizCodeEnum</p>
|
||||
* Description:
|
||||
* 错误码和错误信息定义类
|
||||
* 1. 错误码定义规则为5为数字
|
||||
* 2. 前两位表示业务场景,最后三位表示错误码。例如:100001。10:通用 001:系统未知异常
|
||||
* 3. 维护错误码后需要维护错误描述,将他们定义为枚举形式
|
||||
* 错误码列表:
|
||||
* 10: 通用
|
||||
* 001:参数格式校验
|
||||
* 002: 短信验证码频率太高
|
||||
* 11: 商品
|
||||
* 12: 订单
|
||||
* 13: 购物车
|
||||
* 14: 物流
|
||||
* 15: 用户
|
||||
* 21: 库存
|
||||
*/
|
||||
public enum BizCodeEnum {
|
||||
UNKNOW_EXCEPTION(10000, "系统未知异常"),
|
||||
VAILD_EXCEPTION(10001, "参数格式校验失败"),
|
||||
SMS_CODE_EXCEPTION(10002, "验证码获取频率太高,稍后再试"),
|
||||
TO_MANY_REQUEST(10003, "请求流量过大"),
|
||||
SMS_SEND_CODE_EXCEPTION(10403, "短信发送失败"),
|
||||
USER_EXIST_EXCEPTION(15001, "用户已经存在"),
|
||||
PHONE_EXIST_EXCEPTION(15002, "手机号已经存在"),
|
||||
LOGINACTT_PASSWORD_ERROR(15003, "账号或密码错误"),
|
||||
SOCIALUSER_LOGIN_ERROR(15004, "社交账号登录失败"),
|
||||
NOT_STOCK_EXCEPTION(21000, "商品库存不足"),
|
||||
PRODUCT_UP_EXCEPTION(11000,"商品上架异常");
|
||||
|
||||
private int code;
|
||||
|
||||
private String msg;
|
||||
|
||||
BizCodeEnum(int code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package name.lkk.common.exception;
|
||||
|
||||
/**
|
||||
* <p>Title: NotStockException</p>
|
||||
* Description:
|
||||
* date:2020/7/2 11:43
|
||||
*/
|
||||
public class NotStockException extends RuntimeException{
|
||||
|
||||
private Long skuId;
|
||||
|
||||
public NotStockException(String msg) {
|
||||
super(msg + "号商品没有足够的库存了");
|
||||
}
|
||||
|
||||
public Long getSkuId() {
|
||||
return skuId;
|
||||
}
|
||||
|
||||
public void setSkuId(Long skuId) {
|
||||
this.skuId = skuId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package name.lkk.common.valid;
|
||||
|
||||
/**
|
||||
* 新增分组
|
||||
*/
|
||||
public interface AddGroup {
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package name.lkk.common.valid;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* <p>Title: ListValue</p>
|
||||
* Description:JSR303自定义注解 必须有前三个方法
|
||||
* date:2020/6/1 23:25
|
||||
*/
|
||||
@Documented
|
||||
// 指定校验器 这里可以指定多个不同的校验器
|
||||
@Constraint(validatedBy = { ListValueConstraintValidator.class })
|
||||
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
|
||||
@Retention(RUNTIME)
|
||||
public @interface ListValue {
|
||||
String message() default "{com.firenay.common.valid.ListValue.message}";
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
|
||||
int[] vals() default { };
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package name.lkk.common.valid;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>Title: ListValueConstraintValidator</p>
|
||||
* Description:校验器:规定ListValue这个注解 用于校验 Integer 类型的数据
|
||||
* POSTman :{"name":"aaa","logo":"https://github.com/1046762075","sort":0,"firstLetter":"d","showStatus":0}
|
||||
* date:2020/6/1 23:33
|
||||
*/
|
||||
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
|
||||
|
||||
/**
|
||||
* set 里面就是使用注解时规定的值, 例如: @ListValue(vals = {0,1}) set= {0,1}
|
||||
*/
|
||||
private Set<Integer> set = new HashSet<>();
|
||||
|
||||
//初始化方法
|
||||
@Override
|
||||
public void initialize(ListValue constraintAnnotation) {
|
||||
|
||||
int[] vals = constraintAnnotation.vals();
|
||||
for (int val : vals) {
|
||||
set.add(val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否校验成功
|
||||
* @param value 需要校验的值
|
||||
* 判断这个值再set里面没
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid(Integer value, ConstraintValidatorContext context) {
|
||||
return set.contains(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package name.lkk.common.valid;
|
||||
|
||||
/**
|
||||
* 修改分组
|
||||
*/
|
||||
public interface UpdateGroup {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package name.lkk.common.valid;
|
||||
|
||||
public interface UpdateStatusGroup {
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
com.firenay.common.valid.ListValue.message=\u5FC5\u987B\u63D0\u4EA4\u6307\u5B9A\u7684\u503C [0,1]
|
|
@ -38,6 +38,14 @@ spring:
|
|||
- Path=/api/ware/**
|
||||
filters:
|
||||
- RewritePath=/api/(?<segment>.*), /$\{segment}
|
||||
# OSS签名的转发
|
||||
- id: third-server_route
|
||||
uri: lb://kkmall-third-server
|
||||
predicates:
|
||||
- Path=/api/third/server/**
|
||||
filters:
|
||||
- RewritePath=/api/(?<segment>.*), /$\{segment}
|
||||
|
||||
#过滤器要放最下面才不会被替换路径/api/*路径
|
||||
- id: admin_route
|
||||
uri: lb://kkmall-admin
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package name.lkk.kkmall.product.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import name.lkk.common.valid.AddGroup;
|
||||
import name.lkk.common.valid.UpdateGroup;
|
||||
import name.lkk.common.valid.UpdateStatusGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import name.lkk.kkmall.product.entity.BrandEntity;
|
||||
import name.lkk.kkmall.product.service.BrandService;
|
||||
|
@ -53,25 +54,40 @@ public class BrandController {
|
|||
return R.ok().put("brand", brand);
|
||||
}
|
||||
|
||||
@GetMapping("/infos")
|
||||
public R info(@RequestParam("brandIds") List<Long> brandIds) {
|
||||
List<BrandEntity> brand = brandService.getBrandByIds(brandIds);
|
||||
return R.ok().put("data", brand);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
* 保存 开启JSR303校验 规定这是新增分组 实现新增的规则
|
||||
* POSTman:{"name":"aaa","logo":"abc","brandId":1}
|
||||
* POSTman :{"name":"aaa","logo":"https://github.com/1046762075","sort":0,"firstLetter":"d","showStatus":0}
|
||||
*/
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermissions("product:brand:save")
|
||||
public R save(@RequestBody BrandEntity brand){
|
||||
brandService.save(brand);
|
||||
public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand) {
|
||||
brandService.save(brand);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
* POSTman:{"name":"aaa","logo":"abc"}
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermissions("product:brand:update")
|
||||
public R update(@RequestBody BrandEntity brand){
|
||||
brandService.updateById(brand);
|
||||
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand) {
|
||||
brandService.updateDetail(brand);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改状态
|
||||
*/
|
||||
@RequestMapping("/update/status")
|
||||
public R updateStatus(@Validated(UpdateStatusGroup.class) @RequestBody BrandEntity brand) {
|
||||
brandService.updateById(brand);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,35 +2,52 @@ package name.lkk.kkmall.product.entity;
|
|||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
import name.lkk.common.valid.AddGroup;
|
||||
import name.lkk.common.valid.ListValue;
|
||||
import name.lkk.common.valid.UpdateGroup;
|
||||
import name.lkk.common.valid.UpdateStatusGroup;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Null;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 品牌
|
||||
*
|
||||
* @author KirkLin
|
||||
* @email linkirk@163.com
|
||||
* @date 2021-06-07 15:14:37
|
||||
* 自定义JSR303校验
|
||||
* 根据分组进行校验 Controller里面要进行规定
|
||||
*/
|
||||
@Data
|
||||
@TableName("pms_brand")
|
||||
public class BrandEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 品牌id
|
||||
* POSTman:{"name":"aaa","logo":"abc","brandId":1}
|
||||
*/
|
||||
@NotNull(message = "修改必须定制品牌id", groups = {UpdateGroup.class})
|
||||
@Null(message = "新增不能指定id", groups = {AddGroup.class})
|
||||
@TableId
|
||||
private Long brandId;
|
||||
|
||||
/**
|
||||
* 品牌名
|
||||
*/
|
||||
@NotBlank(message = "品牌名必须提交", groups = {AddGroup.class, UpdateGroup.class})
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 品牌logo地址
|
||||
* 品牌logo地址 修改可以不带上logoURL
|
||||
*/
|
||||
@NotBlank(groups = {AddGroup.class})
|
||||
@URL(message = "logo必须是一个合法的URL地址", groups={AddGroup.class, UpdateGroup.class})
|
||||
private String logo;
|
||||
/**
|
||||
* 介绍
|
||||
|
@ -39,14 +56,21 @@ public class BrandEntity implements Serializable {
|
|||
/**
|
||||
* 显示状态[0-不显示;1-显示]
|
||||
*/
|
||||
@NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})
|
||||
@ListValue(vals = {0,1}, groups = {AddGroup.class, UpdateGroup.class, UpdateStatusGroup.class})
|
||||
private Integer showStatus;
|
||||
|
||||
/**
|
||||
* 检索首字母
|
||||
* 检索首字母 修改可以不带, 不管是新增还是修改都必须是一个字母
|
||||
*/
|
||||
@NotEmpty(groups = {AddGroup.class})
|
||||
@Pattern(regexp = "^[a-zA-Z]$", message = "检索首字母必须是一个字母", groups = {AddGroup.class, UpdateGroup.class})
|
||||
private String firstLetter;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@NotNull(groups = {AddGroup.class})
|
||||
@Min(value = 0, message = "排序必须是一个正整数" , groups = {AddGroup.class, UpdateGroup.class})
|
||||
private Integer sort;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package name.lkk.kkmall.product.exception;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import name.lkk.common.exception.BizCodeEnum;
|
||||
import name.lkk.common.utils.R;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.bind.support.WebExchangeBindException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>Title: MallExceptionControllerAdvice</p>
|
||||
* Description:集中处理所有异常
|
||||
* date:2020/6/1 21:19
|
||||
* @author kirklin
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice(basePackages = "com.firenay.mall.product.controller")
|
||||
public class MallExceptionControllerAdvice {
|
||||
|
||||
|
||||
@ExceptionHandler(value = {WebExchangeBindException.class})
|
||||
public R handleVaildException(WebExchangeBindException e) {
|
||||
log.error("数据校验出现问题{},异常类型:{}", e.getMessage(), e.getClass());
|
||||
BindingResult bindingResult = e.getBindingResult();
|
||||
|
||||
Map<String, String> errorMap = new HashMap<>();
|
||||
bindingResult.getFieldErrors().forEach((fieldError) -> {
|
||||
// 错误字段 、 错误提示
|
||||
errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
|
||||
});
|
||||
return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMsg()).put("data", errorMap);
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = Throwable.class)
|
||||
public R handleException(Throwable throwable) {
|
||||
|
||||
log.error("错误:", throwable);
|
||||
return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), BizCodeEnum.UNKNOW_EXCEPTION.getMsg());
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||
import name.lkk.common.utils.PageUtils;
|
||||
import name.lkk.kkmall.product.entity.BrandEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -16,5 +17,13 @@ import java.util.Map;
|
|||
public interface BrandService extends IService<BrandEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 当品牌进行更新的时候 保证关联表的数据也需要进行更新
|
||||
*/
|
||||
void updateDetail(BrandEntity brand);
|
||||
|
||||
List<BrandEntity> getBrandByIds(List<Long> brandIds);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -16,5 +16,8 @@ import java.util.Map;
|
|||
public interface CategoryBrandRelationService extends IService<CategoryBrandRelationEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
|
||||
void updateBrand(Long brandId, String name);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package name.lkk.kkmall.product.service.impl;
|
||||
|
||||
import name.lkk.kkmall.product.service.CategoryBrandRelationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
@ -11,10 +15,14 @@ import name.lkk.common.utils.Query;
|
|||
import name.lkk.kkmall.product.dao.BrandDao;
|
||||
import name.lkk.kkmall.product.entity.BrandEntity;
|
||||
import name.lkk.kkmall.product.service.BrandService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
@Service("brandService")
|
||||
public class BrandServiceImpl extends ServiceImpl<BrandDao, BrandEntity> implements BrandService {
|
||||
@Autowired
|
||||
private CategoryBrandRelationService categoryBrandRelationService;
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
|
@ -26,4 +34,24 @@ public class BrandServiceImpl extends ServiceImpl<BrandDao, BrandEntity> impleme
|
|||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当品牌进行更新的时候 保证关联表的数据也需要进行更新
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public void updateDetail(BrandEntity brand) {
|
||||
// 保证冗余字段的数据一致
|
||||
this.updateById(brand);
|
||||
if(!StringUtils.isEmpty(brand.getName())){
|
||||
// 同步更新其他关联表的数据
|
||||
categoryBrandRelationService.updateBrand(brand.getBrandId(), brand.getName());
|
||||
// TODO 更新其它关联
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BrandEntity> getBrandByIds(List<Long> brandIds) {
|
||||
return baseMapper.selectList(new QueryWrapper<BrandEntity>().in("brand_id",brandIds));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package name.lkk.kkmall.product.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.Map;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
@ -26,4 +27,13 @@ public class CategoryBrandRelationServiceImpl extends ServiceImpl<CategoryBrandR
|
|||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBrand(Long brandId, String name) {
|
||||
CategoryBrandRelationEntity entity = new CategoryBrandRelationEntity();
|
||||
entity.setBrandId(brandId);
|
||||
entity.setBrandName(name);
|
||||
// 将所有品牌id为 brandId 的进行更新
|
||||
this.update(entity, new UpdateWrapper<CategoryBrandRelationEntity>().eq("brand_id",brandId));
|
||||
}
|
||||
|
||||
}
|
84
kkmall-third-server/pom.xml
Normal file
84
kkmall-third-server/pom.xml
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.5.0</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>name.lkk.kkmall</groupId>
|
||||
<artifactId>kkmall-third-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>kkmall-third-server</name>
|
||||
<description>第三方服务</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-cloud.version>2020.0.3</spring-cloud.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>name.lkk.kkmall</groupId>
|
||||
<artifactId>kkmall-common</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<!-- 排除 Mybatis-Plus -->
|
||||
<exclusion>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>2.2.0.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,15 @@
|
|||
package name.lkk.kkmall.thirdserver;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
public class KkmallThirdServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(KkmallThirdServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package name.lkk.kkmall.thirdserver.controller;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.common.utils.BinaryUtil;
|
||||
import com.aliyun.oss.model.MatchMode;
|
||||
import com.aliyun.oss.model.PolicyConditions;
|
||||
import name.lkk.common.utils.R;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 生成后端签名
|
||||
*/
|
||||
@RestController
|
||||
public class OSSController {
|
||||
|
||||
@Resource
|
||||
OSS ossClient;
|
||||
|
||||
@Value("${spring.cloud.alicloud.oss.endpoint}")
|
||||
private String endpoint;
|
||||
|
||||
@Value("${spring.cloud.alicloud.oss.bucket}")
|
||||
private String bucket;
|
||||
|
||||
@Value("${spring.cloud.alicloud.access-key}")
|
||||
private String accessId;
|
||||
private PolicyConditions policyConds;
|
||||
|
||||
@RequestMapping("/third/server/oss/policy")
|
||||
public R policy() {
|
||||
String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
|
||||
// callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
|
||||
String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
String dir = format + "/"; // 用户上传文件时指定的前缀。
|
||||
|
||||
Map<String, String> respMap = null;
|
||||
try {
|
||||
long expireTime = 30;
|
||||
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
|
||||
Date expiration = new Date(expireEndTime);
|
||||
PolicyConditions policyConds = new PolicyConditions();
|
||||
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
|
||||
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
|
||||
|
||||
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
|
||||
byte[] binaryData = postPolicy.getBytes("utf-8");
|
||||
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
|
||||
String postSignature = ossClient.calculatePostSignature(postPolicy);
|
||||
|
||||
respMap = new LinkedHashMap<>();
|
||||
respMap.put("accessid", accessId);
|
||||
respMap.put("policy", encodedPolicy);
|
||||
respMap.put("signature", postSignature);
|
||||
respMap.put("dir", dir);
|
||||
respMap.put("host", host);
|
||||
respMap.put("expire", String.valueOf(expireEndTime / 1000));
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return R.ok().put("data", respMap);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
management.endpoints.web.exposure.include=*
|
15
kkmall-third-server/src/main/resources/application.yml
Normal file
15
kkmall-third-server/src/main/resources/application.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
spring:
|
||||
application:
|
||||
name: kkmall-third-server
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
alicloud:
|
||||
oss:
|
||||
endpoint: oss-cn-hangzhou.aliyuncs.com
|
||||
bucket: mall-kk
|
||||
access-key: LTAI5tCHtotRisgLvCsp5pv5
|
||||
secret-key: zWiSQOcz5faTSkropwNssB7rqgMYmV
|
||||
server:
|
||||
port: 30000
|
|
@ -0,0 +1,37 @@
|
|||
package name.lkk.kkmall.thirdserver;
|
||||
|
||||
import com.aliyun.oss.OSSClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@SpringBootTest
|
||||
class KkmallThirdServerApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private OSSClient ossClient;
|
||||
|
||||
@Value("${spring.cloud.alicloud.oss.bucket}")
|
||||
private String bucketName;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindPath() throws IOException {
|
||||
// 上传网络流。
|
||||
InputStream inputStream = new FileInputStream("/Users/kirklin/Pictures/ideabg.jpeg");
|
||||
|
||||
ossClient.putObject(bucketName, "ideabg.jpeg", inputStream);
|
||||
|
||||
// 关闭OSSClient。
|
||||
ossClient.shutdown();
|
||||
System.out.println("上传成功");
|
||||
}
|
||||
}
|
|
@ -9,14 +9,15 @@ function resolve (dir) {
|
|||
}
|
||||
|
||||
const createLintingRule = () => ({
|
||||
test: /\.(js|vue)$/,
|
||||
loader: 'eslint-loader',
|
||||
enforce: 'pre',
|
||||
include: [resolve('src'), resolve('test')],
|
||||
options: {
|
||||
formatter: require('eslint-friendly-formatter'),
|
||||
emitWarning: !config.dev.showEslintErrorsInOverlay
|
||||
}
|
||||
//关闭语法检查
|
||||
// test: /\.(js|vue)$/,
|
||||
// loader: 'eslint-loader',
|
||||
// enforce: 'pre',
|
||||
// include: [resolve('src'), resolve('test')],
|
||||
// options: {
|
||||
// formatter: require('eslint-friendly-formatter'),
|
||||
// emitWarning: !config.dev.showEslintErrorsInOverlay
|
||||
// }
|
||||
})
|
||||
|
||||
module.exports = {
|
||||
|
|
128
renren-fast-vue/src/components/upload/multiUpload.vue
Normal file
128
renren-fast-vue/src/components/upload/multiUpload.vue
Normal file
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
action="http://mall-kk.oss-cn-hangzhou.aliyuncs.com"
|
||||
:data="dataObj"
|
||||
:list-type="listType"
|
||||
:file-list="fileList"
|
||||
:before-upload="beforeUpload"
|
||||
:on-remove="handleRemove"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-preview="handlePreview"
|
||||
:limit="maxCount"
|
||||
:on-exceed="handleExceed"
|
||||
:show-file-list="showFile"
|
||||
>
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogVisible">
|
||||
<img width="100%" :src="dialogImageUrl" alt />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { policy } from "./policy";
|
||||
import { getUUID } from '@/utils'
|
||||
export default {
|
||||
name: "multiUpload",
|
||||
props: {
|
||||
//图片属性数组
|
||||
value: Array,
|
||||
//最大上传图片数量
|
||||
maxCount: {
|
||||
type: Number,
|
||||
default: 30
|
||||
},
|
||||
listType:{
|
||||
type: String,
|
||||
default: "picture-card"
|
||||
},
|
||||
showFile:{
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataObj: {
|
||||
policy: "",
|
||||
signature: "",
|
||||
key: "",
|
||||
ossaccessKeyId: "",
|
||||
dir: "",
|
||||
host: "",
|
||||
uuid: ""
|
||||
},
|
||||
dialogVisible: false,
|
||||
dialogImageUrl: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
fileList() {
|
||||
let fileList = [];
|
||||
for (let i = 0; i < this.value.length; i++) {
|
||||
fileList.push({ url: this.value[i] });
|
||||
}
|
||||
|
||||
return fileList;
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
emitInput(fileList) {
|
||||
let value = [];
|
||||
for (let i = 0; i < fileList.length; i++) {
|
||||
value.push(fileList[i].url);
|
||||
}
|
||||
this.$emit("input", value);
|
||||
},
|
||||
handleRemove(file, fileList) {
|
||||
this.emitInput(fileList);
|
||||
},
|
||||
handlePreview(file) {
|
||||
this.dialogVisible = true;
|
||||
this.dialogImageUrl = file.url;
|
||||
},
|
||||
beforeUpload(file) {
|
||||
let _self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
policy()
|
||||
.then(response => {
|
||||
// console.log("这是什么${filename}");
|
||||
_self.dataObj.policy = response.data.policy;
|
||||
_self.dataObj.signature = response.data.signature;
|
||||
_self.dataObj.ossaccessKeyId = response.data.accessid;
|
||||
_self.dataObj.key = response.data.dir +getUUID()+"_${filename}";
|
||||
_self.dataObj.dir = response.data.dir;
|
||||
_self.dataObj.host = response.data.host;
|
||||
resolve(true);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log("出错了...",err)
|
||||
reject(false);
|
||||
});
|
||||
});
|
||||
},
|
||||
handleUploadSuccess(res, file) {
|
||||
this.fileList.push({
|
||||
name: file.name,
|
||||
// url: this.dataObj.host + "/" + this.dataObj.dir + "/" + file.name; 替换${filename}为真正的文件名
|
||||
url: this.dataObj.host + "/" + this.dataObj.key.replace("${filename}",file.name)
|
||||
});
|
||||
this.emitInput(this.fileList);
|
||||
},
|
||||
handleExceed(files, fileList) {
|
||||
this.$message({
|
||||
message: "最多只能上传" + this.maxCount + "张图片",
|
||||
type: "warning",
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
12
renren-fast-vue/src/components/upload/policy.js
Normal file
12
renren-fast-vue/src/components/upload/policy.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import http from '@/utils/httpRequest.js'
|
||||
export function policy() {
|
||||
return new Promise((resolve,reject)=>{
|
||||
http({
|
||||
url: http.adornUrl("/third/server/oss/policy"),
|
||||
method: "get",
|
||||
params: http.adornParams({})
|
||||
}).then(({ data }) => {
|
||||
resolve(data);
|
||||
})
|
||||
});
|
||||
}
|
121
renren-fast-vue/src/components/upload/singleUpload.vue
Normal file
121
renren-fast-vue/src/components/upload/singleUpload.vue
Normal file
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
action="http://mall-kk.oss-cn-hangzhou.aliyuncs.com"
|
||||
:data="dataObj"
|
||||
list-type="picture"
|
||||
:multiple="false"
|
||||
:show-file-list="showFileList"
|
||||
:file-list="fileList"
|
||||
:before-upload="beforeUpload"
|
||||
:on-remove="handleRemove"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-preview="handlePreview"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过5MB</div>
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogVisible">
|
||||
<img width="100%" :src="fileList[0].url" alt />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { policy } from "./policy";
|
||||
import { getUUID } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "singleUpload",
|
||||
props: {
|
||||
value: String
|
||||
},
|
||||
computed: {
|
||||
imageUrl() {
|
||||
return this.value;
|
||||
},
|
||||
imageName() {
|
||||
if (this.value != null && this.value !== "") {
|
||||
return this.value.substr(this.value.lastIndexOf("/") + 1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
fileList() {
|
||||
return [
|
||||
{
|
||||
name: this.imageName,
|
||||
url: this.imageUrl
|
||||
}
|
||||
];
|
||||
},
|
||||
showFileList: {
|
||||
get: function() {
|
||||
return (
|
||||
this.value !== null && this.value !== "" && this.value !== undefined
|
||||
);
|
||||
},
|
||||
set: function(newValue) {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataObj: {
|
||||
policy: "",
|
||||
signature: "",
|
||||
key: "",
|
||||
ossaccessKeyId: "",
|
||||
dir: "",
|
||||
host: ""
|
||||
// callback:'',
|
||||
},
|
||||
dialogVisible: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
emitInput(val) {
|
||||
this.$emit("input", val);
|
||||
},
|
||||
handleRemove(file, fileList) {
|
||||
this.emitInput("");
|
||||
},
|
||||
handlePreview(file) {
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
beforeUpload(file) {
|
||||
let _self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
policy()
|
||||
.then(response => {
|
||||
_self.dataObj.policy = response.data.policy;
|
||||
_self.dataObj.signature = response.data.signature;
|
||||
_self.dataObj.ossaccessKeyId = response.data.accessid;
|
||||
_self.dataObj.key = response.data.dir + getUUID() + "_${filename}";
|
||||
_self.dataObj.dir = response.data.dir;
|
||||
_self.dataObj.host = response.data.host;
|
||||
// console.log("响应的数据", _self.dataObj);
|
||||
resolve(true);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(false);
|
||||
});
|
||||
});
|
||||
},
|
||||
handleUploadSuccess(res, file) {
|
||||
this.showFileList = true;
|
||||
this.fileList.pop();
|
||||
this.fileList.push({
|
||||
name: file.name,
|
||||
url:
|
||||
this.dataObj.host +
|
||||
"/" +
|
||||
this.dataObj.key.replace("${filename}", file.name)
|
||||
});
|
||||
this.emitInput(this.fileList[0].url);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
|
@ -16,7 +16,8 @@ export function getUUID () {
|
|||
* @param {*} key
|
||||
*/
|
||||
export function isAuth (key) {
|
||||
return JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== -1 || false
|
||||
//return JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== -1 || false
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
80
renren-fast-vue/src/views/modules/common/brand-select.vue
Normal file
80
renren-fast-vue/src/views/modules/common/brand-select.vue
Normal file
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-select placeholder="请选择" v-model="brandId" filterable clearable>
|
||||
<el-option
|
||||
v-for="item in brands"
|
||||
:key="item.brandId"
|
||||
:label="item.brandName"
|
||||
:value="item.brandId"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
|
||||
//例如:import 《组件名称》 from '《组件路径》';
|
||||
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: {},
|
||||
props: {},
|
||||
data() {
|
||||
//这里存放数据
|
||||
return {
|
||||
catId: 0,
|
||||
brands: [
|
||||
{
|
||||
label: "a",
|
||||
value: 1
|
||||
}
|
||||
],
|
||||
brandId: "",
|
||||
subscribe: null
|
||||
};
|
||||
},
|
||||
//计算属性 类似于data概念
|
||||
computed: {},
|
||||
//监控data中的数据变化
|
||||
watch: {
|
||||
brandId(val) {
|
||||
this.PubSub.publish("brandId", val);
|
||||
}
|
||||
},
|
||||
//方法集合
|
||||
methods: {
|
||||
getCatBrands() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/categorybrandrelation/brands/list"),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
catId: this.catId
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
this.brands = data.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
//生命周期 - 创建完成(可以访问当前this实例)
|
||||
created() {},
|
||||
//生命周期 - 挂载完成(可以访问DOM元素)
|
||||
mounted() {
|
||||
//监听三级分类消息的变化
|
||||
this.subscribe = PubSub.subscribe("catPath", (msg, val) => {
|
||||
this.catId = val[val.length - 1];
|
||||
this.getCatBrands();
|
||||
});
|
||||
},
|
||||
beforeCreate() {}, //生命周期 - 创建之前
|
||||
beforeMount() {}, //生命周期 - 挂载之前
|
||||
beforeUpdate() {}, //生命周期 - 更新之前
|
||||
updated() {}, //生命周期 - 更新之后
|
||||
beforeDestroy() {
|
||||
PubSub.unsubscribe(this.subscribe); //销毁订阅
|
||||
}, //生命周期 - 销毁之前
|
||||
destroyed() {}, //生命周期 - 销毁完成
|
||||
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<!--
|
||||
使用说明:
|
||||
1)、引入category-cascader.vue
|
||||
2)、语法:<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
|
||||
解释:
|
||||
catelogPath:指定的值是cascader初始化需要显示的值,应该和父组件的catelogPath绑定;
|
||||
由于有sync修饰符,所以cascader路径变化以后自动会修改父的catelogPath,这是结合子组件this.$emit("update:catelogPath",v);做的
|
||||
-->
|
||||
<div>
|
||||
<el-cascader
|
||||
filterable
|
||||
clearable
|
||||
placeholder="试试搜索:手机"
|
||||
v-model="paths"
|
||||
:options="categorys"
|
||||
:props="setting"
|
||||
></el-cascader>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: {},
|
||||
//接受父组件传来的值
|
||||
props: {
|
||||
catelogPath: {
|
||||
type: Array,
|
||||
default(){
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
//这里存放数据
|
||||
return {
|
||||
setting: {
|
||||
value: "catId",
|
||||
label: "name",
|
||||
children: "children"
|
||||
},
|
||||
categorys: [],
|
||||
paths: this.catelogPath
|
||||
};
|
||||
},
|
||||
watch:{
|
||||
catelogPath(v){
|
||||
this.paths = this.catelogPath;
|
||||
},
|
||||
paths(v){
|
||||
this.$emit("update:catelogPath",v);
|
||||
//还可以使用pubsub-js进行传值
|
||||
this.PubSub.publish("catPath",v);
|
||||
}
|
||||
},
|
||||
//方法集合
|
||||
methods: {
|
||||
getCategorys() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/category/list/tree"),
|
||||
method: "get"
|
||||
}).then(({ data }) => {
|
||||
this.categorys = data.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
//生命周期 - 创建完成(可以访问当前this实例)
|
||||
created() {
|
||||
this.getCategorys();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
80
renren-fast-vue/src/views/modules/common/category.vue
Normal file
80
renren-fast-vue/src/views/modules/common/category.vue
Normal file
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input>
|
||||
<el-tree
|
||||
:data="menus"
|
||||
:props="defaultProps"
|
||||
node-key="catId"
|
||||
ref="menuTree"
|
||||
@node-click="nodeclick"
|
||||
:filter-node-method="filterNode"
|
||||
:highlight-current = "true"
|
||||
></el-tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: {},
|
||||
props: {},
|
||||
data() {
|
||||
//这里存放数据
|
||||
return {
|
||||
filterText: "",
|
||||
menus: [],
|
||||
expandedKey: [],
|
||||
defaultProps: {
|
||||
children: "children",
|
||||
label: "name"
|
||||
}
|
||||
};
|
||||
},
|
||||
//计算属性 类似于data概念
|
||||
computed: {},
|
||||
//监控data中的数据变化
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.menuTree.filter(val);
|
||||
}
|
||||
},
|
||||
//方法集合
|
||||
methods: {
|
||||
//树节点过滤
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.name.indexOf(value) !== -1;
|
||||
},
|
||||
getMenus() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/category/list/tree"),
|
||||
method: "get"
|
||||
}).then(({ data }) => {
|
||||
this.menus = data.data;
|
||||
});
|
||||
},
|
||||
nodeclick(data, node, component) {
|
||||
// console.log("子组件category的节点被点击", data, node, component);
|
||||
//向父组件发送事件;
|
||||
this.$emit("tree-node-click", data, node, component);
|
||||
}
|
||||
},
|
||||
//生命周期 - 创建完成(可以访问当前this实例)
|
||||
created() {
|
||||
this.getMenus();
|
||||
},
|
||||
//生命周期 - 挂载完成(可以访问DOM元素)
|
||||
mounted() {},
|
||||
beforeCreate() {}, //生命周期 - 创建之前
|
||||
beforeMount() {}, //生命周期 - 挂载之前
|
||||
beforeUpdate() {}, //生命周期 - 更新之前
|
||||
updated() {}, //生命周期 - 更新之后
|
||||
beforeDestroy() {}, //生命周期 - 销毁之前
|
||||
destroyed() {}, //生命周期 - 销毁完成
|
||||
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
283
renren-fast-vue/src/views/modules/product/attr-add-or-update.vue
Normal file
283
renren-fast-vue/src/views/modules/product/attr-add-or-update.vue
Normal file
|
@ -0,0 +1,283 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:title="!dataForm.id ? '新增' : '修改'"
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="visible"
|
||||
@closed="dialogClose"
|
||||
>
|
||||
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="120px">
|
||||
<!-- @keyup.enter.native="dataFormSubmit()" -->
|
||||
<el-form-item label="属性名" prop="attrName">
|
||||
<el-input v-model="dataForm.attrName" placeholder="属性名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="属性类型" prop="attrType">
|
||||
<el-select v-model="dataForm.attrType" placeholder="请选择">
|
||||
<el-option label="规格参数" :value="1"></el-option>
|
||||
<el-option label="销售属性" :value="0"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="值类型" prop="valueType">
|
||||
<el-switch
|
||||
v-model="dataForm.valueType"
|
||||
active-text="允许多个值"
|
||||
inactive-text="只能单个值"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
:inactive-value="0"
|
||||
:active-value="1"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="可选值" prop="valueSelect">
|
||||
<!-- <el-input v-model="dataForm.valueSelect"></el-input> -->
|
||||
<el-select
|
||||
v-model="dataForm.valueSelect"
|
||||
multiple
|
||||
filterable
|
||||
allow-create
|
||||
placeholder="请输入内容"
|
||||
></el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="属性图标" prop="icon">
|
||||
<el-input v-model="dataForm.icon" placeholder="属性图标"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属分类" prop="catelogId">
|
||||
<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属分组" prop="attrGroupId" v-if="type == 1">
|
||||
<el-select ref="groupSelect" v-model="dataForm.attrGroupId" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in attrGroups"
|
||||
:key="item.attrGroupId"
|
||||
:label="item.attrGroupName"
|
||||
:value="item.attrGroupId"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="可检索" prop="searchType" v-if="type == 1">
|
||||
<el-switch
|
||||
v-model="dataForm.searchType"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="快速展示" prop="showDesc" v-if="type == 1">
|
||||
<el-switch
|
||||
v-model="dataForm.showDesc"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="启用状态" prop="enable">
|
||||
<el-switch
|
||||
v-model="dataForm.enable"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CategoryCascader from "../common/category-cascader";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
attrId: 0,
|
||||
attrName: "",
|
||||
searchType: 0,
|
||||
valueType: 1,
|
||||
icon: "",
|
||||
valueSelect: "",
|
||||
attrType: 1,
|
||||
enable: 1,
|
||||
catelogId: "",
|
||||
attrGroupId: "",
|
||||
showDesc: 0
|
||||
},
|
||||
catelogPath: [],
|
||||
attrGroups: [],
|
||||
dataRule: {
|
||||
attrName: [
|
||||
{ required: true, message: "属性名不能为空", trigger: "blur" }
|
||||
],
|
||||
searchType: [
|
||||
{
|
||||
required: true,
|
||||
message: "是否需要检索不能为空",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
valueType: [
|
||||
{
|
||||
required: true,
|
||||
message: "值类型不能为空",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
icon: [
|
||||
{ required: true, message: "属性图标不能为空", trigger: "blur" }
|
||||
],
|
||||
attrType: [
|
||||
{
|
||||
required: true,
|
||||
message: "属性类型不能为空",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
enable: [
|
||||
{
|
||||
required: true,
|
||||
message: "启用状态不能为空",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
catelogId: [
|
||||
{
|
||||
required: true,
|
||||
message: "需要选择正确的三级分类数据",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
showDesc: [
|
||||
{
|
||||
required: true,
|
||||
message: "快速展示不能为空",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
props:{
|
||||
type:{
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
catelogPath(path) {
|
||||
//监听到路径变化需要查出这个三级分类的分组信息
|
||||
// console.log("路径变了", path);
|
||||
this.attrGroups = [];
|
||||
this.dataForm.attrGroupId = "";
|
||||
this.dataForm.catelogId = path[path.length - 1];
|
||||
if (path && path.length == 3) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attrgroup/list/${path[path.length - 1]}`
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({ page: 1, limit: 10000000 })
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.attrGroups = data.page.list;
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
} else if (path.length == 0) {
|
||||
this.dataForm.catelogId = "";
|
||||
} else {
|
||||
this.$message.error("请选择正确的分类");
|
||||
this.dataForm.catelogId = "";
|
||||
}
|
||||
}
|
||||
},
|
||||
components: { CategoryCascader },
|
||||
methods: {
|
||||
init(id) {
|
||||
this.dataForm.attrId = id || 0;
|
||||
this.dataForm.attrType = this.type;
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["dataForm"].resetFields();
|
||||
if (this.dataForm.attrId) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attr/info/${this.dataForm.attrId}`
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams()
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataForm.attrName = data.attr.attrName;
|
||||
this.dataForm.searchType = data.attr.searchType;
|
||||
this.dataForm.valueType = data.attr.valueType;
|
||||
this.dataForm.icon = data.attr.icon;
|
||||
this.dataForm.valueSelect = data.attr.valueSelect.split(";");
|
||||
this.dataForm.attrType = data.attr.attrType;
|
||||
this.dataForm.enable = data.attr.enable;
|
||||
this.dataForm.catelogId = data.attr.catelogId;
|
||||
this.dataForm.showDesc = data.attr.showDesc;
|
||||
//attrGroupId
|
||||
//catelogPath
|
||||
this.catelogPath = data.attr.catelogPath;
|
||||
this.$nextTick(() => {
|
||||
this.dataForm.attrGroupId = data.attr.attrGroupId;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmit() {
|
||||
this.$refs["dataForm"].validate(valid => {
|
||||
if (valid) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attr/${!this.dataForm.attrId ? "save" : "update"}`
|
||||
),
|
||||
method: "post",
|
||||
data: this.$http.adornData({
|
||||
attrId: this.dataForm.attrId || undefined,
|
||||
attrName: this.dataForm.attrName,
|
||||
searchType: this.dataForm.searchType,
|
||||
valueType: this.dataForm.valueType,
|
||||
icon: this.dataForm.icon,
|
||||
valueSelect: this.dataForm.valueSelect.join(";"),
|
||||
attrType: this.dataForm.attrType,
|
||||
enable: this.dataForm.enable,
|
||||
catelogId: this.dataForm.catelogId,
|
||||
attrGroupId: this.dataForm.attrGroupId,
|
||||
showDesc: this.dataForm.showDesc
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.visible = false;
|
||||
this.$emit("refreshDataList");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
//dialogClose
|
||||
dialogClose() {
|
||||
this.catelogPath = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,245 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-dialog :close-on-click-modal="false" :visible.sync="visible" @closed="dialogClose">
|
||||
<el-dialog width="40%" title="选择属性" :visible.sync="innerVisible" append-to-body>
|
||||
<div>
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="getDataList()">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
:data="dataList"
|
||||
border
|
||||
v-loading="dataListLoading"
|
||||
@selection-change="innerSelectionChangeHandle"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-table-column type="selection" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="attrId" header-align="center" align="center" label="属性id"></el-table-column>
|
||||
<el-table-column prop="attrName" header-align="center" align="center" label="属性名"></el-table-column>
|
||||
<el-table-column prop="icon" header-align="center" align="center" label="属性图标">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.logo" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="valueSelect" header-align="center" align="center" label="可选值列表"></el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="innerVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitAddRealtion">确认新增</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-button type="primary" @click="addRelation">新建关联</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
@click="batchDeleteRelation"
|
||||
:disabled="dataListSelections.length <= 0"
|
||||
>批量删除</el-button>
|
||||
<!-- -->
|
||||
<el-table
|
||||
:data="relationAttrs"
|
||||
style="width: 100%"
|
||||
@selection-change="selectionChangeHandle"
|
||||
border
|
||||
>
|
||||
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
|
||||
<el-table-column prop="attrId" label="#"></el-table-column>
|
||||
<el-table-column prop="attrName" label="属性名"></el-table-column>
|
||||
<el-table-column prop="valueSelect" label="可选值">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
<span v-for="(i,index) in scope.row.valueSelect.split(';')" :key="index">
|
||||
{{i}}
|
||||
<br />
|
||||
</span>
|
||||
</div>
|
||||
<el-tag>{{scope.row.valueSelect.split(";")[0]+" ..."}}</el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" header-align="center" align="center" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="relationRemove(scope.row.attrId)">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
|
||||
//例如:import 《组件名称》 from '《组件路径》';
|
||||
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: {},
|
||||
props: {},
|
||||
data() {
|
||||
//这里存放数据
|
||||
return {
|
||||
attrGroupId: 0,
|
||||
visible: false,
|
||||
innerVisible: false,
|
||||
relationAttrs: [],
|
||||
dataListSelections: [],
|
||||
dataForm: {
|
||||
key: ""
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
innerdataListSelections: []
|
||||
};
|
||||
},
|
||||
//计算属性 类似于data概念
|
||||
computed: {},
|
||||
//监控data中的数据变化
|
||||
watch: {},
|
||||
//方法集合
|
||||
methods: {
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val;
|
||||
},
|
||||
innerSelectionChangeHandle(val) {
|
||||
this.innerdataListSelections = val;
|
||||
},
|
||||
addRelation() {
|
||||
this.getDataList();
|
||||
this.innerVisible = true;
|
||||
},
|
||||
batchDeleteRelation(val) {
|
||||
let postData = [];
|
||||
this.dataListSelections.forEach(item => {
|
||||
postData.push({ attrId: item.attrId, attrGroupId: this.attrGroupId });
|
||||
});
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/attrgroup/attr/relation/delete"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(postData, false)
|
||||
}).then(({ data }) => {
|
||||
if (data.code == 0) {
|
||||
this.$message({ type: "success", message: "删除成功" });
|
||||
this.init(this.attrGroupId);
|
||||
} else {
|
||||
this.$message({ type: "error", message: data.msg });
|
||||
}
|
||||
}).catch(() => {});
|
||||
},
|
||||
//移除关联
|
||||
relationRemove(attrId) {
|
||||
let data = [];
|
||||
data.push({ attrId, attrGroupId: this.attrGroupId });
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/attrgroup/attr/relation/delete"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(data, false)
|
||||
}).then(({ data }) => {
|
||||
if (data.code == 0) {
|
||||
this.$message({ type: "success", message: "删除成功" });
|
||||
this.init(this.attrGroupId);
|
||||
} else {
|
||||
this.$message({ type: "error", message: data.msg });
|
||||
}
|
||||
}).catch(() => {});
|
||||
},
|
||||
submitAddRealtion() {
|
||||
this.innerVisible = false;
|
||||
//准备数据
|
||||
// console.log("准备新增的数据", this.innerdataListSelections);
|
||||
if (this.innerdataListSelections.length > 0) {
|
||||
let postData = [];
|
||||
this.innerdataListSelections.forEach(item => {
|
||||
postData.push({ attrId: item.attrId, attrGroupId: this.attrGroupId });
|
||||
});
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/attrgroup/attr/relation"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(postData, false)
|
||||
}).then(({ data }) => {
|
||||
if (data.code == 0) {
|
||||
this.$message({ type: "success", message: "新增关联成功" });
|
||||
}
|
||||
this.$emit("refreshData");
|
||||
this.init(this.attrGroupId);
|
||||
}).catch(() => {});
|
||||
} else {
|
||||
}
|
||||
},
|
||||
init(id) {
|
||||
this.attrGroupId = id || 0;
|
||||
this.visible = true;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
"/product/attrgroup/" + this.attrGroupId + "/attr/relation"
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({})
|
||||
}).then(({ data }) => {
|
||||
this.relationAttrs = data.data;
|
||||
}).catch(() => {});
|
||||
},
|
||||
dialogClose() {},
|
||||
|
||||
//========
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
"/product/attrgroup/" + this.attrGroupId + "/noattr/relation"
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
key: this.dataForm.key
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.data.list;
|
||||
this.totalPage = data.data.totalCount;
|
||||
} else {
|
||||
this.dataList = [];
|
||||
this.totalPage = 0;
|
||||
}
|
||||
this.dataListLoading = false;
|
||||
}).catch(() => {});
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val;
|
||||
this.pageIndex = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val;
|
||||
this.getDataList();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,159 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:title="!dataForm.id ? '新增' : '修改'"
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="visible"
|
||||
@closed="dialogClose"
|
||||
>
|
||||
<el-form
|
||||
:model="dataForm"
|
||||
:rules="dataRule"
|
||||
ref="dataForm"
|
||||
@keyup.enter.native="dataFormSubmit()"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="组名" prop="attrGroupName">
|
||||
<el-input v-model="dataForm.attrGroupName" placeholder="组名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input v-model="dataForm.sort" placeholder="排序"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="descript">
|
||||
<el-input v-model="dataForm.descript" placeholder="描述"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="组图标" prop="icon">
|
||||
<el-input v-model="dataForm.icon" placeholder="组图标"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属分类" prop="catelogId">
|
||||
<!-- filterable:让这个选择器可以搜索 -->
|
||||
<!-- <el-cascader filterable placeholder="试试搜索:手机" v-model="catelogPath" :options="categorys" :props="props"></el-cascader> -->
|
||||
<!-- :catelogPath="catelogPath"自定义绑定的属性,可以给子组件传值 -->
|
||||
<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CategoryCascader from "../common/category-cascader";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
props: {
|
||||
value: "catId",
|
||||
label: "name",
|
||||
children: "children"
|
||||
},
|
||||
visible: false,
|
||||
categorys: [],
|
||||
catelogPath: [],
|
||||
dataForm: {
|
||||
attrGroupId: 0,
|
||||
attrGroupName: "",
|
||||
sort: "",
|
||||
descript: "",
|
||||
icon: "",
|
||||
catelogId: 0
|
||||
},
|
||||
dataRule: {
|
||||
attrGroupName: [
|
||||
{ required: true, message: "组名不能为空", trigger: "blur" }
|
||||
],
|
||||
sort: [{ required: true, message: "排序不能为空", trigger: "blur" }],
|
||||
descript: [
|
||||
{ required: true, message: "描述不能为空", trigger: "blur" }
|
||||
],
|
||||
icon: [{ required: true, message: "组图标不能为空", trigger: "blur" }],
|
||||
catelogId: [
|
||||
{ required: true, message: "所属分类id不能为空", trigger: "blur" }
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
components: { CategoryCascader },
|
||||
|
||||
methods: {
|
||||
dialogClose() {
|
||||
this.catelogPath = [];
|
||||
},
|
||||
getCategorys() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/category/list/tree"),
|
||||
method: "get"
|
||||
}).then(({ data }) => {
|
||||
this.categorys = data.data;
|
||||
});
|
||||
},
|
||||
init(id) {
|
||||
this.dataForm.attrGroupId = id || 0;
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["dataForm"].resetFields();
|
||||
if (this.dataForm.attrGroupId) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attrgroup/info/${this.dataForm.attrGroupId}`
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams()
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataForm.attrGroupName = data.attrGroup.attrGroupName;
|
||||
this.dataForm.sort = data.attrGroup.sort;
|
||||
this.dataForm.descript = data.attrGroup.descript;
|
||||
this.dataForm.icon = data.attrGroup.icon;
|
||||
this.dataForm.catelogId = data.attrGroup.catelogId;
|
||||
// 查出catelogId的完整路径
|
||||
this.catelogPath = data.attrGroup.catelogPath;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmit() {
|
||||
this.$refs["dataForm"].validate(valid => {
|
||||
if (valid) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attrgroup/${
|
||||
!this.dataForm.attrGroupId ? "save" : "update"
|
||||
}`
|
||||
),
|
||||
method: "post",
|
||||
data: this.$http.adornData({
|
||||
attrGroupId: this.dataForm.attrGroupId || undefined,
|
||||
attrGroupName: this.dataForm.attrGroupName,
|
||||
sort: this.dataForm.sort,
|
||||
descript: this.dataForm.descript,
|
||||
icon: this.dataForm.icon,
|
||||
catelogId: this.catelogPath[this.catelogPath.length - 1]
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.visible = false;
|
||||
this.$emit("refreshDataList");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getCategorys();
|
||||
}
|
||||
};
|
||||
</script>
|
225
renren-fast-vue/src/views/modules/product/attrgroup.vue
Normal file
225
renren-fast-vue/src/views/modules/product/attrgroup.vue
Normal file
|
@ -0,0 +1,225 @@
|
|||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<category @tree-node-click="treenodeclick"></category>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="getDataList()">查询</el-button>
|
||||
<el-button type="success" @click="getAllDataList()">查询全部</el-button>
|
||||
<el-button
|
||||
v-if="isAuth('product:attrgroup:save')"
|
||||
type="primary"
|
||||
@click="addOrUpdateHandle()"
|
||||
>新增</el-button>
|
||||
<el-button
|
||||
v-if="isAuth('product:attrgroup:delete')"
|
||||
type="danger"
|
||||
@click="deleteHandle()"
|
||||
:disabled="dataListSelections.length <= 0"
|
||||
>批量删除</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
:data="dataList"
|
||||
border
|
||||
v-loading="dataListLoading"
|
||||
@selection-change="selectionChangeHandle"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
|
||||
<el-table-column prop="attrGroupId" header-align="center" align="center" label="分组id"></el-table-column>
|
||||
<el-table-column prop="attrGroupName" header-align="center" align="center" label="组名"></el-table-column>
|
||||
<el-table-column prop="sort" header-align="center" align="center" label="排序"></el-table-column>
|
||||
<el-table-column prop="descript" header-align="center" align="center" label="描述"></el-table-column>
|
||||
<el-table-column prop="icon" header-align="center" align="center" label="组图标">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.logo" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="catelogId" header-align="center" align="center" label="分类id"></el-table-column>
|
||||
<el-table-column
|
||||
fixed="right"
|
||||
header-align="center"
|
||||
align="center"
|
||||
width="150"
|
||||
label="操作"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="relationHandle(scope.row.attrGroupId)">关联</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="addOrUpdateHandle(scope.row.attrGroupId)"
|
||||
>修改</el-button>
|
||||
<el-button type="text" size="small" @click="deleteHandle(scope.row.attrGroupId)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
<!-- 弹窗, 新增 / 修改 -->
|
||||
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
|
||||
|
||||
<!-- 修改关联关系 -->
|
||||
<relation-update v-if="relationVisible" ref="relationUpdate" @refreshData="getDataList"></relation-update>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 父子组件传递数据
|
||||
* 1)、子组件给父组件传递数据,事件机制;
|
||||
* 子组件给父组件发送一个事件,携带上数据。
|
||||
* // this.$emit("事件名",携带的数据...)
|
||||
*/
|
||||
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
|
||||
//例如:import 《组件名称》 from '《组件路径》';
|
||||
import Category from "../common/category";
|
||||
import AddOrUpdate from "./attrgroup-add-or-update";
|
||||
import RelationUpdate from "./attr-group-relation";
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: { Category, AddOrUpdate, RelationUpdate },
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
catId: 0,
|
||||
dataForm: {
|
||||
key: ""
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false,
|
||||
relationVisible: false
|
||||
};
|
||||
},
|
||||
activated() {
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
//处理分组与属性的关联
|
||||
relationHandle(groupId) {
|
||||
this.relationVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.relationUpdate.init(groupId);
|
||||
});
|
||||
},
|
||||
//感知树节点被点击
|
||||
treenodeclick(data, node, component) {
|
||||
if (node.level == 3) {
|
||||
this.catId = data.catId;
|
||||
this.getDataList(); //重新查询
|
||||
}
|
||||
},
|
||||
getAllDataList() {
|
||||
this.catId = 0;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/product/attrgroup/list/${this.catId}`),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
key: this.dataForm.key
|
||||
})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.page.list;
|
||||
this.totalPage = data.page.totalCount;
|
||||
} else {
|
||||
this.dataList = [];
|
||||
this.totalPage = 0;
|
||||
}
|
||||
this.dataListLoading = false;
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val;
|
||||
this.pageIndex = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val;
|
||||
this.getDataList();
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val;
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle(id) {
|
||||
this.addOrUpdateVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init(id);
|
||||
});
|
||||
},
|
||||
// 删除
|
||||
deleteHandle(id) {
|
||||
var ids = id
|
||||
? [id]
|
||||
: this.dataListSelections.map(item => {
|
||||
return item.attrGroupId;
|
||||
});
|
||||
this.$confirm(
|
||||
`确定对[id=${ids.join(",")}]进行[${id ? "删除" : "批量删除"}]操作?`,
|
||||
"提示",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/attrgroup/delete"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(ids, false)
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
191
renren-fast-vue/src/views/modules/product/attrupdate.vue
Normal file
191
renren-fast-vue/src/views/modules/product/attrupdate.vue
Normal file
|
@ -0,0 +1,191 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-card class="box-card">
|
||||
<el-tabs tab-position="left" style="width:98%">
|
||||
<el-tab-pane
|
||||
:label="group.attrGroupName"
|
||||
v-for="(group,gidx) in dataResp.attrGroups"
|
||||
:key="group.attrGroupId"
|
||||
>
|
||||
<!-- 遍历属性,每个tab-pane对应一个表单,每个属性是一个表单项 spu.baseAttrs[0] = [{attrId:xx,val:}]-->
|
||||
<el-form ref="form" :model="dataResp">
|
||||
<el-form-item
|
||||
:label="attr.attrName"
|
||||
v-for="(attr,aidx) in group.attrs"
|
||||
:key="attr.attrId"
|
||||
>
|
||||
<el-input
|
||||
v-model="dataResp.baseAttrs[gidx][aidx].attrId"
|
||||
type="hidden"
|
||||
v-show="false"
|
||||
></el-input>
|
||||
<el-select
|
||||
v-model="dataResp.baseAttrs[gidx][aidx].attrValues"
|
||||
:multiple="attr.valueType == 1"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请选择或输入值"
|
||||
>
|
||||
<el-option
|
||||
v-for="(val,vidx) in attr.valueSelect.split(';')"
|
||||
:key="vidx"
|
||||
:label="val"
|
||||
:value="val"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<el-checkbox
|
||||
v-model="dataResp.baseAttrs[gidx][aidx].showDesc"
|
||||
:true-label="1"
|
||||
:false-label="0"
|
||||
>快速展示</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div style="margin:auto">
|
||||
<el-button type="success" style="float:right" @click="submitSpuAttrs">确认修改</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
spuId: "",
|
||||
catalogId: "",
|
||||
dataResp: {
|
||||
//后台返回的所有数据
|
||||
attrGroups: [],
|
||||
baseAttrs: []
|
||||
},
|
||||
spuAttrsMap: {}
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
clearData(){
|
||||
this.dataResp.attrGroups = [];
|
||||
this.dataResp.baseAttrs = [];
|
||||
this.spuAttrsMap = {};
|
||||
},
|
||||
getSpuBaseAttrs() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/product/attr/base/listforspu/${this.spuId}`),
|
||||
method: "get"
|
||||
}).then(({ data }) => {
|
||||
data.data.forEach(item => {
|
||||
this.spuAttrsMap["" + item.attrId] = item;
|
||||
});
|
||||
// console.log("~~~~", this.spuAttrsMap);
|
||||
});
|
||||
},
|
||||
getQueryParams() {
|
||||
this.spuId = this.$route.query.spuId;
|
||||
this.catalogId = this.$route.query.catalogId;
|
||||
// console.log("----", this.spuId, this.catalogId);
|
||||
},
|
||||
showBaseAttrs() {
|
||||
let _this = this;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attrgroup/${this.catalogId}/withattr`
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({})
|
||||
}).then(({ data }) => {
|
||||
//先对表单的baseAttrs进行初始化
|
||||
data.data.forEach(item => {
|
||||
let attrArray = [];
|
||||
item.attrs.forEach(attr => {
|
||||
let v = "";
|
||||
if (_this.spuAttrsMap["" + attr.attrId]) {
|
||||
v = _this.spuAttrsMap["" + attr.attrId].attrValue.split(";");
|
||||
if (v.length == 1) {
|
||||
v = v[0] + "";
|
||||
}
|
||||
}
|
||||
attrArray.push({
|
||||
attrId: attr.attrId,
|
||||
attrName: attr.attrName,
|
||||
attrValues: v,
|
||||
showDesc: _this.spuAttrsMap["" + attr.attrId]
|
||||
? _this.spuAttrsMap["" + attr.attrId].quickShow
|
||||
: attr.showDesc
|
||||
});
|
||||
});
|
||||
this.dataResp.baseAttrs.push(attrArray);
|
||||
});
|
||||
this.dataResp.attrGroups = data.data;
|
||||
});
|
||||
},
|
||||
submitSpuAttrs() {
|
||||
// console.log("·····", this.dataResp.baseAttrs);
|
||||
//spu_id attr_id attr_name attr_value attr_sort quick_show
|
||||
let submitData = [];
|
||||
this.dataResp.baseAttrs.forEach(item => {
|
||||
item.forEach(attr => {
|
||||
let val = "";
|
||||
if (attr.attrValues instanceof Array) {
|
||||
val = attr.attrValues.join(";");
|
||||
} else {
|
||||
val = attr.attrValues;
|
||||
}
|
||||
|
||||
if (val != "") {
|
||||
submitData.push({
|
||||
attrId: attr.attrId,
|
||||
attrName: attr.attrName,
|
||||
attrValue: val,
|
||||
quickShow: attr.showDesc
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.$confirm("修改商品规格信息, 是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/product/attr/update/${this.spuId}`),
|
||||
method: "post",
|
||||
data: this.$http.adornData(submitData, false)
|
||||
}).then(({ data }) => {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "属性修改成功!"
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message({
|
||||
type: "info",
|
||||
message: "已取消修改"+e
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
activated() {
|
||||
this.clearData();
|
||||
this.getQueryParams();
|
||||
if (this.spuId && this.catalogId) {
|
||||
this.showBaseAttrs();
|
||||
this.getSpuBaseAttrs();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
267
renren-fast-vue/src/views/modules/product/baseattr.vue
Normal file
267
renren-fast-vue/src/views/modules/product/baseattr.vue
Normal file
|
@ -0,0 +1,267 @@
|
|||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<category @tree-node-click="treenodeclick"></category>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="getDataList()">查询</el-button>
|
||||
<el-button type="success" @click="getAllDataList()">查询全部</el-button>
|
||||
<el-button
|
||||
v-if="isAuth('product:attr:save')"
|
||||
type="primary"
|
||||
@click="addOrUpdateHandle()"
|
||||
>新增</el-button>
|
||||
<el-button
|
||||
v-if="isAuth('product:attr:delete')"
|
||||
type="danger"
|
||||
@click="deleteHandle()"
|
||||
:disabled="dataListSelections.length <= 0"
|
||||
>批量删除</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
:data="dataList"
|
||||
border
|
||||
v-loading="dataListLoading"
|
||||
@selection-change="selectionChangeHandle"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
|
||||
<el-table-column prop="attrId" header-align="center" align="center" label="id"></el-table-column>
|
||||
<el-table-column prop="attrName" header-align="center" align="center" label="属性名"></el-table-column>
|
||||
<el-table-column
|
||||
v-if="attrtype == 1"
|
||||
prop="searchType"
|
||||
header-align="center"
|
||||
align="center"
|
||||
label="可检索"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-success" v-if="scope.row.searchType==1"></i>
|
||||
<i class="el-icon-error" v-else></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="valueType" header-align="center" align="center" label="值类型">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.valueType==0">单选</el-tag>
|
||||
<el-tag v-else>多选</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="icon" header-align="center" align="center" label="图标">
|
||||
<template slot-scope="scope">
|
||||
<!-- 自定义表格+自定义图片 -->
|
||||
<img :src="scope.row.logo" style="width: 60px; height: 60px" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="valueSelect" header-align="center" align="center" label="可选值">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
<span v-for="(i,index) in scope.row.valueSelect.split(';')" :key="index">
|
||||
{{i}}
|
||||
<br />
|
||||
</span>
|
||||
</div>
|
||||
<el-tag>{{scope.row.valueSelect.split(";")[0]+" ..."}}</el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="enable" header-align="center" align="center" label="启用">
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-success" v-if="scope.row.enable==1"></i>
|
||||
<i class="el-icon-error" v-else></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="catelogName" header-align="center" align="center" label="所属分类"></el-table-column>
|
||||
<el-table-column
|
||||
v-if="attrtype == 1"
|
||||
prop="groupName"
|
||||
header-align="center"
|
||||
align="center"
|
||||
label="所属分组"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
v-if="attrtype == 1"
|
||||
prop="showDesc"
|
||||
header-align="center"
|
||||
align="center"
|
||||
label="快速展示"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-success" v-if="scope.row.showDesc==1"></i>
|
||||
<i class="el-icon-error" v-else></i>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
fixed="right"
|
||||
header-align="center"
|
||||
align="center"
|
||||
width="150"
|
||||
label="操作"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.attrId)">修改</el-button>
|
||||
<el-button type="text" size="small" @click="deleteHandle(scope.row.attrId)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
<!-- 弹窗, 新增 / 修改 -->
|
||||
<add-or-update
|
||||
:type="attrtype"
|
||||
v-if="addOrUpdateVisible"
|
||||
ref="addOrUpdate"
|
||||
@refreshDataList="getDataList"
|
||||
></add-or-update>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Category from "../common/category";
|
||||
import AddOrUpdate from "./attr-add-or-update";
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: { Category, AddOrUpdate },
|
||||
props: {
|
||||
attrtype: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
catId: 0,
|
||||
type: 1,
|
||||
dataForm: {
|
||||
key: ""
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false
|
||||
};
|
||||
},
|
||||
activated() {
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
//感知树节点被点击
|
||||
treenodeclick(data, node, component) {
|
||||
if (node.level == 3) {
|
||||
this.catId = data.catId;
|
||||
this.getDataList(); //重新查询
|
||||
}
|
||||
},
|
||||
getAllDataList() {
|
||||
this.catId = 0;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
let type = this.attrtype == 0 ? "sale" : "base";
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(`/product/attr/${type}/list/${this.catId}`),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
key: this.dataForm.key
|
||||
})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.page.list;
|
||||
this.totalPage = data.page.totalCount;
|
||||
} else {
|
||||
this.dataList = [];
|
||||
this.totalPage = 0;
|
||||
}
|
||||
this.dataListLoading = false;
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val;
|
||||
this.pageIndex = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val;
|
||||
this.getDataList();
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val;
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle(id) {
|
||||
this.addOrUpdateVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init(id);
|
||||
});
|
||||
},
|
||||
// 删除
|
||||
deleteHandle(id) {
|
||||
var ids = id
|
||||
? [id]
|
||||
: this.dataListSelections.map(item => {
|
||||
return item.attrId;
|
||||
});
|
||||
this.$confirm(
|
||||
`确定对[id=${ids.join(",")}]进行[${id ? "删除" : "批量删除"}]操作?`,
|
||||
"提示",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/attr/delete"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(ids, false)
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:title="!dataForm.id ? '新增' : '修改'"
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="visible"
|
||||
>
|
||||
<el-form
|
||||
:model="dataForm"
|
||||
:rules="dataRule"
|
||||
ref="dataForm"
|
||||
@keyup.enter.native="dataFormSubmit()"
|
||||
label-width="140px"
|
||||
>
|
||||
<el-form-item label="品牌名" prop="name">
|
||||
<el-input v-model="dataForm.name" placeholder="品牌名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="品牌logo地址" prop="logo">
|
||||
<!-- <el-input v-model="dataForm.logo" placeholder="品牌logo地址"></el-input> -->
|
||||
<single-upload v-model="dataForm.logo"></single-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="介绍" prop="descript">
|
||||
<el-input v-model="dataForm.descript" placeholder="介绍"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示状态" prop="showStatus">
|
||||
<el-switch
|
||||
v-model="dataForm.showStatus"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="检索首字母" prop="firstLetter">
|
||||
<el-input v-model="dataForm.firstLetter" placeholder="检索首字母"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<!-- 传入的必须是一个数字 -->
|
||||
<el-input v-model.number="dataForm.sort" placeholder="排序"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SingleUpload from "@/components/upload/singleUpload";
|
||||
export default {
|
||||
components: { SingleUpload },
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
dataForm: {
|
||||
brandId: 0,
|
||||
name: "",
|
||||
logo: "",
|
||||
descript: "",
|
||||
showStatus: 1,
|
||||
firstLetter: "",
|
||||
sort: 0
|
||||
},
|
||||
dataRule: {
|
||||
name: [{ required: true, message: "品牌名不能为空", trigger: "blur" }],
|
||||
logo: [
|
||||
{ required: true, message: "品牌logo地址不能为空", trigger: "blur" }
|
||||
],
|
||||
descript: [
|
||||
{ required: true, message: "介绍不能为空", trigger: "blur" }
|
||||
],
|
||||
showStatus: [
|
||||
{
|
||||
required: true,
|
||||
message: "显示状态[0-不显示;1-显示]不能为空",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
firstLetter: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value == "") {
|
||||
callback(new Error("首字母必须填写"));
|
||||
} else if (!/^[a-zA-Z]$/.test(value)) {
|
||||
callback(new Error("首字母必须a-z或者A-Z之间"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
sort: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (value == "" && value != 0) {
|
||||
callback(new Error("排序字段必须填写"));
|
||||
} else if (!Number.isInteger(value) || value<0) {
|
||||
callback(new Error("排序必须是一个正整数"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init(id) {
|
||||
this.dataForm.brandId = id || 0;
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["dataForm"].resetFields();
|
||||
if (this.dataForm.brandId) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/brand/info/${this.dataForm.brandId}`
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams()
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataForm.name = data.brand.name;
|
||||
this.dataForm.logo = data.brand.logo;
|
||||
this.dataForm.descript = data.brand.descript;
|
||||
this.dataForm.showStatus = data.brand.showStatus;
|
||||
this.dataForm.firstLetter = data.brand.firstLetter;
|
||||
this.dataForm.sort = data.brand.sort;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 表单提交
|
||||
dataFormSubmit() {
|
||||
this.$refs["dataForm"].validate(valid => {
|
||||
if (valid) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/brand/${!this.dataForm.brandId ? "save" : "update"}`
|
||||
),
|
||||
method: "post",
|
||||
data: this.$http.adornData({
|
||||
brandId: this.dataForm.brandId || undefined,
|
||||
name: this.dataForm.name,
|
||||
logo: this.dataForm.logo,
|
||||
descript: this.dataForm.descript,
|
||||
showStatus: this.dataForm.showStatus,
|
||||
firstLetter: this.dataForm.firstLetter,
|
||||
sort: this.dataForm.sort
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.visible = false;
|
||||
this.$emit("refreshDataList");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
278
renren-fast-vue/src/views/modules/product/brand.vue
Normal file
278
renren-fast-vue/src/views/modules/product/brand.vue
Normal file
|
@ -0,0 +1,278 @@
|
|||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
||||
<el-form-item>
|
||||
<el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="getDataList()">查询</el-button>
|
||||
<el-button
|
||||
v-if="isAuth('product:brand:save')"
|
||||
type="primary"
|
||||
@click="addOrUpdateHandle()"
|
||||
>新增</el-button>
|
||||
<el-button
|
||||
v-if="isAuth('product:brand:delete')"
|
||||
type="danger"
|
||||
@click="deleteHandle()"
|
||||
:disabled="dataListSelections.length <= 0"
|
||||
>批量删除</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
:data="dataList"
|
||||
border
|
||||
v-loading="dataListLoading"
|
||||
@selection-change="selectionChangeHandle"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
|
||||
<el-table-column prop="brandId" header-align="center" align="center" label="品牌id"></el-table-column>
|
||||
<el-table-column prop="name" header-align="center" align="center" label="品牌名"></el-table-column>
|
||||
<el-table-column prop="logo" header-align="center" align="center" label="品牌logo地址">
|
||||
<template slot-scope="scope">
|
||||
<!-- 自定义表格+自定义图片 -->
|
||||
<img :src="scope.row.logo" style="width: 100px; height: 80px" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="descript" header-align="center" align="center" label="介绍"></el-table-column>
|
||||
<el-table-column prop="showStatus" header-align="center" align="center" label="显示状态">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.showStatus"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@change="updateBrandStatus(scope.row)"
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="firstLetter" header-align="center" align="center" label="检索首字母"></el-table-column>
|
||||
<el-table-column prop="sort" header-align="center" align="center" label="排序"></el-table-column>
|
||||
<el-table-column fixed="right" header-align="center" align="center" width="250" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="updateCatelogHandle(scope.row.brandId)">关联分类</el-button>
|
||||
<el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.brandId)">修改</el-button>
|
||||
<el-button type="text" size="small" @click="deleteHandle(scope.row.brandId)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
<!-- 弹窗, 新增 / 修改 -->
|
||||
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update>
|
||||
|
||||
<el-dialog title="关联分类" :visible.sync="cateRelationDialogVisible" width="30%">
|
||||
<el-popover placement="right-end" v-model="popCatelogSelectVisible">
|
||||
<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="popCatelogSelectVisible = false">取消</el-button>
|
||||
<el-button type="primary" size="mini" @click="addCatelogSelect">确定</el-button>
|
||||
</div>
|
||||
<el-button slot="reference">新增关联</el-button>
|
||||
</el-popover>
|
||||
<el-table :data="cateRelationTableData" style="width: 100%">
|
||||
<el-table-column prop="id" label="#"></el-table-column>
|
||||
<el-table-column prop="brandName" label="品牌名"></el-table-column>
|
||||
<el-table-column prop="catelogName" label="分类名"></el-table-column>
|
||||
<el-table-column fixed="right" header-align="center" align="center" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="deleteCateRelationHandle(scope.row.id,scope.row.brandId)"
|
||||
>移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cateRelationDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="cateRelationDialogVisible = false">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AddOrUpdate from "./brand-add-or-update";
|
||||
import CategoryCascader from "../common/category-cascader";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataForm: {
|
||||
key: ""
|
||||
},
|
||||
brandId: 0,
|
||||
catelogPath: [],
|
||||
dataList: [],
|
||||
cateRelationTableData: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false,
|
||||
cateRelationDialogVisible: false,
|
||||
popCatelogSelectVisible: false
|
||||
};
|
||||
},
|
||||
components: {
|
||||
AddOrUpdate,
|
||||
CategoryCascader
|
||||
},
|
||||
activated() {
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
addCatelogSelect() {
|
||||
//{"brandId":1,"catelogId":2}
|
||||
this.popCatelogSelectVisible = false;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/categorybrandrelation/save"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(
|
||||
{
|
||||
brandId: this.brandId,
|
||||
catelogId: this.catelogPath[this.catelogPath.length - 1]
|
||||
},
|
||||
false
|
||||
)
|
||||
}).then(({ data }) => {
|
||||
this.getCateRelation();
|
||||
}).catch(() => {});
|
||||
},
|
||||
deleteCateRelationHandle(id, brandId) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/categorybrandrelation/delete"),
|
||||
method: "post",
|
||||
data: this.$http.adornData([id], false)
|
||||
}).then(({ data }) => {
|
||||
this.getCateRelation();
|
||||
}).catch(() => {});;
|
||||
},
|
||||
updateCatelogHandle(brandId) {
|
||||
this.cateRelationDialogVisible = true;
|
||||
this.brandId = brandId;
|
||||
this.getCateRelation();
|
||||
},
|
||||
getCateRelation() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/categorybrandrelation/catelog/list"),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
brandId: this.brandId
|
||||
})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
this.cateRelationTableData = data.data;
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/brand/list"),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
key: this.dataForm.key
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.page.list;
|
||||
this.totalPage = data.page.totalCount;
|
||||
} else {
|
||||
this.dataList = [];
|
||||
this.totalPage = 0;
|
||||
}
|
||||
this.dataListLoading = false;
|
||||
}).catch(() => {});;
|
||||
},
|
||||
updateBrandStatus(data) {
|
||||
// console.log("最新信息", data);
|
||||
let { brandId, showStatus } = data;
|
||||
//发送请求修改状态
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/brand/update/status"),
|
||||
method: "post",
|
||||
data: this.$http.adornData({ brandId, showStatus }, false)
|
||||
}).then(({ data }) => {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "状态更新成功"
|
||||
});
|
||||
}).catch(() => {});;
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val;
|
||||
this.pageIndex = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val;
|
||||
this.getDataList();
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val;
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle(id) {
|
||||
this.addOrUpdateVisible = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.addOrUpdate.init(id);
|
||||
});
|
||||
},
|
||||
// 删除
|
||||
deleteHandle(id) {
|
||||
var ids = id
|
||||
? [id]
|
||||
: this.dataListSelections.map(item => {
|
||||
return item.brandId;
|
||||
});
|
||||
this.$confirm(
|
||||
`确定对[id=${ids.join(",")}]进行[${id ? "删除" : "批量删除"}]操作?`,
|
||||
"提示",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/brand/delete"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(ids, false)
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
197
renren-fast-vue/src/views/modules/product/manager.vue
Normal file
197
renren-fast-vue/src/views/modules/product/manager.vue
Normal file
|
@ -0,0 +1,197 @@
|
|||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
||||
<el-form :inline="true" :model="dataForm">
|
||||
<el-form-item label="分类">
|
||||
<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="品牌">
|
||||
<brand-select style="width:160px"></brand-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="价格">
|
||||
<el-input-number style="width:160px" v-model="dataForm.price.min" :min="0"></el-input-number>-
|
||||
<el-input-number style="width:160px" v-model="dataForm.price.max" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="检索">
|
||||
<el-input style="width:160px" v-model="dataForm.key" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="searchSkuInfo">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form>
|
||||
<el-table
|
||||
:data="dataList"
|
||||
border
|
||||
v-loading="dataListLoading"
|
||||
@selection-change="selectionChangeHandle"
|
||||
style="width: 100%;"
|
||||
@expand-change="getSkuDetails"
|
||||
>
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="scope">
|
||||
商品标题:{{scope.row.skuTitle}}
|
||||
<br />
|
||||
商品副标题:{{scope.row.skuSubtitle}}
|
||||
<br />
|
||||
商品描述:{{scope.row.skuDesc}}
|
||||
<br />
|
||||
分类ID:{{scope.row.catalogId}}
|
||||
<br />
|
||||
SpuID:{{scope.row.spuId}}
|
||||
<br />
|
||||
品牌ID:{{scope.row.brandId}}
|
||||
<br />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
|
||||
<el-table-column prop="skuId" header-align="center" align="center" label="skuId"></el-table-column>
|
||||
<el-table-column prop="skuName" header-align="center" align="center" label="名称"></el-table-column>
|
||||
<el-table-column prop="skuDefaultImg" header-align="center" align="center" label="默认图片">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.skuDefaultImg" style="width:80px;height:80px;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" header-align="center" align="center" label="价格(¥)"></el-table-column>
|
||||
<el-table-column prop="saleCount" header-align="center" align="center" label="销量"></el-table-column>
|
||||
<el-table-column fixed="right" header-align="center" align="center" width="150" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="previewHandle(scope.row.skuId)">预览</el-button>
|
||||
<el-button type="text" size="small" @click="commentHandle(scope.row.skuId)">评论</el-button>
|
||||
<el-dropdown
|
||||
@command="handleCommand(scope.row,$event)"
|
||||
size="small"
|
||||
split-button
|
||||
type="text"
|
||||
>
|
||||
更多
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="uploadImages">上传图片</el-dropdown-item>
|
||||
<el-dropdown-item command="seckillSettings">参与秒杀</el-dropdown-item>
|
||||
<el-dropdown-item command="reductionSettings">满减设置</el-dropdown-item>
|
||||
<el-dropdown-item command="discountSettings">折扣设置</el-dropdown-item>
|
||||
<el-dropdown-item command="memberPriceSettings">会员价格</el-dropdown-item>
|
||||
<el-dropdown-item command="stockSettings">库存管理</el-dropdown-item>
|
||||
<el-dropdown-item command="couponSettings">优惠劵</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CategoryCascader from "../common/category-cascader";
|
||||
import BrandSelect from "../common/brand-select";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
catPathSub: null,
|
||||
brandIdSub: null,
|
||||
dataForm: {
|
||||
key: "",
|
||||
brandId: 0,
|
||||
catelogId: 0,
|
||||
price: {
|
||||
min: 0,
|
||||
max: 0
|
||||
}
|
||||
},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false,
|
||||
catelogPath: []
|
||||
};
|
||||
},
|
||||
components: {
|
||||
CategoryCascader,
|
||||
BrandSelect
|
||||
},
|
||||
activated() {
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
getSkuDetails(row, expand) {
|
||||
//sku详情查询
|
||||
// console.log("展开某行...", row, expand);
|
||||
},
|
||||
//处理更多指令
|
||||
handleCommand(row, command) {
|
||||
// console.log("~~~~~", row, command);
|
||||
if ("stockSettings" == command) {
|
||||
this.$router.push({ path: "/ware-sku", query: { skuId: row.skuId } });
|
||||
}
|
||||
},
|
||||
searchSkuInfo() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/skuinfo/list"),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize,
|
||||
key: this.dataForm.key,
|
||||
catelogId: this.dataForm.catelogId,
|
||||
brandId: this.dataForm.brandId,
|
||||
min: this.dataForm.price.min,
|
||||
max: this.dataForm.price.max
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.page.list;
|
||||
this.totalPage = data.page.totalCount;
|
||||
} else {
|
||||
this.dataList = [];
|
||||
this.totalPage = 0;
|
||||
}
|
||||
this.dataListLoading = false;
|
||||
});
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val;
|
||||
this.pageIndex = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val;
|
||||
this.getDataList();
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.catPathSub = PubSub.subscribe("catPath", (msg, val) => {
|
||||
this.dataForm.catelogId = val[val.length - 1];
|
||||
});
|
||||
this.brandIdSub = PubSub.subscribe("brandId", (msg, val) => {
|
||||
this.dataForm.brandId = val;
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
PubSub.unsubscribe(this.catPathSub);
|
||||
PubSub.unsubscribe(this.brandIdSub);
|
||||
} //生命周期 - 销毁之前
|
||||
};
|
||||
</script>
|
37
renren-fast-vue/src/views/modules/product/saleattr.vue
Normal file
37
renren-fast-vue/src/views/modules/product/saleattr.vue
Normal file
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<div>
|
||||
<base-attr :attrtype="0"></base-attr>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseAttr from './baseattr'
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: {BaseAttr},
|
||||
props: {},
|
||||
data() {
|
||||
//这里存放数据
|
||||
return {};
|
||||
},
|
||||
//计算属性 类似于data概念
|
||||
computed: {},
|
||||
//监控data中的数据变化
|
||||
watch: {},
|
||||
//方法集合
|
||||
methods: {},
|
||||
//生命周期 - 创建完成(可以访问当前this实例)
|
||||
created() {},
|
||||
//生命周期 - 挂载完成(可以访问DOM元素)
|
||||
mounted() {},
|
||||
beforeCreate() {}, //生命周期 - 创建之前
|
||||
beforeMount() {}, //生命周期 - 挂载之前
|
||||
beforeUpdate() {}, //生命周期 - 更新之前
|
||||
updated() {}, //生命周期 - 更新之后
|
||||
beforeDestroy() {}, //生命周期 - 销毁之前
|
||||
destroyed() {}, //生命周期 - 销毁完成
|
||||
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
93
renren-fast-vue/src/views/modules/product/spu.vue
Normal file
93
renren-fast-vue/src/views/modules/product/spu.vue
Normal file
|
@ -0,0 +1,93 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form :inline="true" :model="dataForm">
|
||||
<el-form-item label="分类">
|
||||
<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="品牌">
|
||||
<brand-select style="width:160px"></brand-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select style="width:160px" v-model="dataForm.status" clearable>
|
||||
<el-option label="新建" :value="0"></el-option>
|
||||
<el-option label="上架" :value="1"></el-option>
|
||||
<el-option label="下架" :value="2"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="检索">
|
||||
<el-input style="width:160px" v-model="dataForm.key" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="searchSpuInfo">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<spuinfo :catId="catId"></spuinfo>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CategoryCascader from "../common/category-cascader";
|
||||
import BrandSelect from "../common/brand-select";
|
||||
import Spuinfo from "./spuinfo";
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: { CategoryCascader, Spuinfo, BrandSelect },
|
||||
props: {},
|
||||
data() {
|
||||
//这里存放数据
|
||||
return {
|
||||
catId: 0,
|
||||
catelogPath: [],
|
||||
dataForm: {
|
||||
status: "",
|
||||
key: "",
|
||||
brandId: 0,
|
||||
catelogId: 0
|
||||
},
|
||||
catPathSub: null,
|
||||
brandIdSub: null
|
||||
|
||||
};
|
||||
},
|
||||
//计算属性 类似于data概念
|
||||
computed: {},
|
||||
//监控data中的数据变化
|
||||
watch: {},
|
||||
//方法集合
|
||||
methods: {
|
||||
searchSpuInfo() {
|
||||
// console.log("搜索条件", this.dataForm);
|
||||
this.PubSub.publish("dataForm",this.dataForm);
|
||||
}
|
||||
},
|
||||
//生命周期 - 创建完成(可以访问当前this实例)
|
||||
created() {},
|
||||
//生命周期 - 挂载完成(可以访问DOM元素)
|
||||
mounted() {
|
||||
this.catPathSub = PubSub.subscribe("catPath", (msg, val) => {
|
||||
this.dataForm.catelogId = val[val.length-1];
|
||||
});
|
||||
this.brandIdSub = PubSub.subscribe("brandId", (msg, val) => {
|
||||
this.dataForm.brandId = val;
|
||||
});
|
||||
},
|
||||
beforeCreate() {}, //生命周期 - 创建之前
|
||||
beforeMount() {}, //生命周期 - 挂载之前
|
||||
beforeUpdate() {}, //生命周期 - 更新之前
|
||||
updated() {}, //生命周期 - 更新之后
|
||||
beforeDestroy() {
|
||||
PubSub.unsubscribe(this.catPathSub);
|
||||
PubSub.unsubscribe(this.brandIdSub);
|
||||
}, //生命周期 - 销毁之前
|
||||
destroyed() {}, //生命周期 - 销毁完成
|
||||
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
818
renren-fast-vue/src/views/modules/product/spuadd.vue
Normal file
818
renren-fast-vue/src/views/modules/product/spuadd.vue
Normal file
|
@ -0,0 +1,818 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-steps :active="step" finish-status="success">
|
||||
<el-step title="基本信息"></el-step>
|
||||
<el-step title="规格参数"></el-step>
|
||||
<el-step title="销售属性"></el-step>
|
||||
<el-step title="SKU信息"></el-step>
|
||||
<el-step title="保存完成"></el-step>
|
||||
</el-steps>
|
||||
</el-col>
|
||||
<el-col :span="24" v-show="step==0">
|
||||
<el-card class="box-card" style="width:80%;margin:20px auto">
|
||||
<el-form ref="spuBaseForm" :model="spu" label-width="120px" :rules="spuBaseInfoRules">
|
||||
<el-form-item label="商品名称" prop="spuName">
|
||||
<el-input v-model="spu.spuName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品描述" prop="spuDescription">
|
||||
<el-input v-model="spu.spuDescription"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择分类" prop="catalogId">
|
||||
<category-cascader></category-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择品牌" prop="brandId">
|
||||
<brand-select></brand-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品重量(Kg)" prop="weight">
|
||||
<el-input-number v-model.number="spu.weight" :min="0" :precision="3" :step="0.1"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="设置积分" prop="bounds">
|
||||
<label>金币</label>
|
||||
<el-input-number
|
||||
style="width:130px"
|
||||
placeholder="金币"
|
||||
v-model="spu.bounds.buyBounds"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
></el-input-number>
|
||||
<label style="margin-left:15px">成长值</label>
|
||||
<el-input-number
|
||||
style="width:130px"
|
||||
placeholder="成长值"
|
||||
v-model="spu.bounds.growBounds"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
>
|
||||
<template slot="prepend">成长值</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品介绍" prop="decript">
|
||||
<multi-upload v-model="spu.decript"></multi-upload>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品图集" prop="images">
|
||||
<multi-upload v-model="spu.images"></multi-upload>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="success" @click="collectSpuBaseInfo">下一步:设置基本参数</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24" v-show="step==1">
|
||||
<el-card class="box-card" style="width:80%;margin:20px auto">
|
||||
<el-tabs tab-position="left" style="width:98%">
|
||||
<el-tab-pane
|
||||
:label="group.attrGroupName"
|
||||
v-for="(group,gidx) in dataResp.attrGroups"
|
||||
:key="group.attrGroupId"
|
||||
>
|
||||
<!-- 遍历属性,每个tab-pane对应一个表单,每个属性是一个表单项 spu.baseAttrs[0] = [{attrId:xx,val:}]-->
|
||||
<el-form ref="form" :model="spu">
|
||||
<el-form-item
|
||||
:label="attr.attrName"
|
||||
v-for="(attr,aidx) in group.attrs"
|
||||
:key="attr.attrId"
|
||||
>
|
||||
<el-input
|
||||
v-model="dataResp.baseAttrs[gidx][aidx].attrId"
|
||||
type="hidden"
|
||||
v-show="false"
|
||||
></el-input>
|
||||
<el-select
|
||||
v-model="dataResp.baseAttrs[gidx][aidx].attrValues"
|
||||
:multiple="attr.valueType == 1"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请选择或输入值"
|
||||
>
|
||||
<el-option
|
||||
v-for="(val,vidx) in attr.valueSelect.split(';')"
|
||||
:key="vidx"
|
||||
:label="val"
|
||||
:value="val"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<el-checkbox
|
||||
v-model="dataResp.baseAttrs[gidx][aidx].showDesc"
|
||||
:true-label="1"
|
||||
:false-label="0"
|
||||
>快速展示</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div style="margin:auto">
|
||||
<el-button type="primary" @click="step = 0">上一步</el-button>
|
||||
<el-button type="success" @click="generateSaleAttrs">下一步:设置销售属性</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24" v-show="step==2">
|
||||
<el-card class="box-card" style="width:80%;margin:20px auto">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>选择销售属性</span>
|
||||
<el-form ref="saleform" :model="spu">
|
||||
<el-form-item
|
||||
:label="attr.attrName"
|
||||
v-for="(attr,aidx) in dataResp.saleAttrs"
|
||||
:key="attr.attrId"
|
||||
>
|
||||
<el-input
|
||||
v-model="dataResp.tempSaleAttrs[aidx].attrId"
|
||||
type="hidden"
|
||||
v-show="false"
|
||||
></el-input>
|
||||
<el-checkbox-group v-model="dataResp.tempSaleAttrs[aidx].attrValues">
|
||||
<el-checkbox
|
||||
v-if="dataResp.saleAttrs[aidx].valueSelect != ''"
|
||||
:label="val"
|
||||
v-for="val in dataResp.saleAttrs[aidx].valueSelect.split(';')"
|
||||
:key="val"
|
||||
></el-checkbox>
|
||||
<div style="margin-left:20px;display:inline">
|
||||
<el-button
|
||||
v-show="!inputVisible[aidx].view"
|
||||
class="button-new-tag"
|
||||
size="mini"
|
||||
@click="showInput(aidx)"
|
||||
>+自定义</el-button>
|
||||
<el-input
|
||||
v-show="inputVisible[aidx].view"
|
||||
v-model="inputValue[aidx].val"
|
||||
:ref="'saveTagInput'+aidx"
|
||||
size="mini"
|
||||
style="width:150px"
|
||||
@keyup.enter.native="handleInputConfirm(aidx)"
|
||||
@blur="handleInputConfirm(aidx)"
|
||||
></el-input>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-button type="primary" @click="step = 1">上一步</el-button>
|
||||
<el-button type="success" @click="generateSkus">下一步:设置SKU信息</el-button>
|
||||
</el-card>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24" v-show="step==3">
|
||||
<el-card class="box-card" style="width:80%;margin:20px auto">
|
||||
<el-table :data="spu.skus" style="width: 100%">
|
||||
<el-table-column label="属性组合">
|
||||
<el-table-column
|
||||
:label="item.attrName"
|
||||
v-for="(item,index) in dataResp.tableAttrColumn"
|
||||
:key="item.attrId"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span style="margin-left: 10px">{{ scope.row.attr[index].attrValue }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" prop="skuName">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.skuName"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="标题" prop="skuTitle">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.skuTitle"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="副标题" prop="skuSubtitle">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.skuSubtitle"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" prop="price">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.price"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="scope">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<label style="display:block;float:left">选择图集 或</label>
|
||||
<multi-upload
|
||||
style="float:left;margin-left:10px;"
|
||||
:showFile="false"
|
||||
:listType="'text'"
|
||||
v-model="uploadImages"
|
||||
></multi-upload>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-divider></el-divider>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-card
|
||||
style="width:170px;float:left;margin-left:15px;margin-top:15px;"
|
||||
:body-style="{ padding: '0px' }"
|
||||
v-for="(img,index) in spu.images"
|
||||
:key="index"
|
||||
>
|
||||
<img :src="img" style="width:160px;height:120px" />
|
||||
<div style="padding: 14px;">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-checkbox
|
||||
v-model="scope.row.images[index].imgUrl"
|
||||
:true-label="img"
|
||||
false-label
|
||||
></el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-tag v-if="scope.row.images[index].defaultImg == 1">
|
||||
<input
|
||||
type="radio"
|
||||
checked
|
||||
:name="scope.row.skuName"
|
||||
@change="checkDefaultImg(scope.row,index,img)"
|
||||
/>设为默认
|
||||
</el-tag>
|
||||
<el-tag v-else>
|
||||
<input
|
||||
type="radio"
|
||||
:name="scope.row.skuName"
|
||||
@change="checkDefaultImg(scope.row,index,img)"
|
||||
/>设为默认
|
||||
</el-tag>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 折扣,满减,会员价 -->
|
||||
<el-form :model="scope.row">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="设置折扣">
|
||||
<label>满</label>
|
||||
<el-input-number
|
||||
style="width:160px"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
v-model="scope.row.fullCount"
|
||||
></el-input-number>
|
||||
<label>件</label>
|
||||
|
||||
<label style="margin-left:15px;">打</label>
|
||||
<el-input-number
|
||||
style="width:160px"
|
||||
v-model="scope.row.discount"
|
||||
:precision="2"
|
||||
:max="1"
|
||||
:min="0"
|
||||
:step="0.01"
|
||||
controls-position="right"
|
||||
></el-input-number>
|
||||
<label>折</label>
|
||||
<el-checkbox
|
||||
v-model="scope.row.countStatus"
|
||||
:true-label="1"
|
||||
:false-label="0"
|
||||
>可叠加优惠</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="设置满减">
|
||||
<label>满</label>
|
||||
<el-input-number
|
||||
style="width:160px"
|
||||
v-model="scope.row.fullPrice"
|
||||
:step="100"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
></el-input-number>
|
||||
<label>元</label>
|
||||
<label style="margin-left:15px;">减</label>
|
||||
<el-input-number
|
||||
style="width:160px"
|
||||
v-model="scope.row.reducePrice"
|
||||
:step="10"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
></el-input-number>
|
||||
<label>元</label>
|
||||
<el-checkbox
|
||||
v-model="scope.row.priceStatus"
|
||||
:true-label="1"
|
||||
:false-label="0"
|
||||
>可叠加优惠</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="设置会员价" v-if="scope.row.memberPrice.length>0">
|
||||
<br />
|
||||
<!-- @change="handlePriceChange(scope,mpidx,$event)" -->
|
||||
<el-form-item v-for="(mp,mpidx) in scope.row.memberPrice" :key="mp.id">
|
||||
{{mp.name}}
|
||||
<el-input-number
|
||||
style="width:160px"
|
||||
v-model="scope.row.memberPrice[mpidx].price"
|
||||
:precision="2"
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-button type="primary" @click="step = 2">上一步</el-button>
|
||||
<el-button type="success" @click="submitSkus">下一步:保存商品信息</el-button>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="24" v-show="step==4">
|
||||
<el-card class="box-card" style="width:80%;margin:20px auto">
|
||||
<h1>保存成功</h1>
|
||||
<el-button type="primary" @click="addAgian">继续添加</el-button>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CategoryCascader from "../common/category-cascader";
|
||||
import BrandSelect from "../common/brand-select";
|
||||
import MultiUpload from "@/components/upload/multiUpload";
|
||||
|
||||
export default {
|
||||
//import引入的组件需要注入到对象中才能使用
|
||||
components: { CategoryCascader, BrandSelect, MultiUpload },
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
catPathSub: null,
|
||||
brandIdSub: null,
|
||||
uploadDialogVisible: false,
|
||||
uploadImages: [],
|
||||
step: 0,
|
||||
//spu_name spu_description catalog_id brand_id weight publish_status
|
||||
spu: {
|
||||
//要提交的数据
|
||||
spuName: "",
|
||||
spuDescription: "",
|
||||
catalogId: 0,
|
||||
brandId: "",
|
||||
weight: "",
|
||||
publishStatus: 0,
|
||||
decript: [], //商品详情
|
||||
images: [], //商品图集,最后sku也可以新增
|
||||
bounds: {
|
||||
//积分
|
||||
buyBounds: 0,
|
||||
growBounds: 0
|
||||
},
|
||||
baseAttrs: [], //基本属性
|
||||
skus: [] //所有sku信息
|
||||
},
|
||||
spuBaseInfoRules: {
|
||||
spuName: [
|
||||
{ required: true, message: "请输入商品名字", trigger: "blur" }
|
||||
],
|
||||
spuDescription: [
|
||||
{ required: true, message: "请编写一个简单描述", trigger: "blur" }
|
||||
],
|
||||
catalogId: [
|
||||
{ required: true, message: "请选择一个分类", trigger: "blur" }
|
||||
],
|
||||
brandId: [
|
||||
{ required: true, message: "请选择一个品牌", trigger: "blur" }
|
||||
],
|
||||
decript: [
|
||||
{ required: true, message: "请上传商品详情图集", trigger: "blur" }
|
||||
],
|
||||
images: [
|
||||
{ required: true, message: "请上传商品图片集", trigger: "blur" }
|
||||
],
|
||||
weight: [
|
||||
{
|
||||
type: "number",
|
||||
required: true,
|
||||
message: "请填写正确的重量值",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
},
|
||||
dataResp: {
|
||||
//后台返回的所有数据
|
||||
attrGroups: [],
|
||||
baseAttrs: [],
|
||||
saleAttrs: [],
|
||||
tempSaleAttrs: [],
|
||||
tableAttrColumn: [],
|
||||
memberLevels: [],
|
||||
steped: [false, false, false, false, false]
|
||||
},
|
||||
inputVisible: [],
|
||||
inputValue: []
|
||||
};
|
||||
},
|
||||
//计算属性 类似于data概念
|
||||
computed: {},
|
||||
//监控data中的数据变化
|
||||
watch: {
|
||||
uploadImages(val) {
|
||||
//扩展每个skus里面的imgs选项
|
||||
let imgArr = Array.from(new Set(this.spu.images.concat(val)));
|
||||
|
||||
//{imgUrl:"",defaultImg:0} 由于concat每次迭代上次,有很多重复。所以我们必须得到上次+这次的总长
|
||||
|
||||
this.spu.skus.forEach((item, index) => {
|
||||
let len = imgArr.length - this.spu.skus[index].images.length; //还差这么多
|
||||
if (len > 0) {
|
||||
let imgs = new Array(len);
|
||||
imgs = imgs.fill({ imgUrl: "", defaultImg: 0 });
|
||||
this.spu.skus[index].images = item.images.concat(imgs);
|
||||
}
|
||||
});
|
||||
|
||||
this.spu.images = imgArr; //去重
|
||||
console.log("this.spu.skus", this.spu.skus);
|
||||
}
|
||||
},
|
||||
//方法集合
|
||||
methods: {
|
||||
addAgian() {
|
||||
this.step = 0;
|
||||
this.resetSpuData();
|
||||
},
|
||||
resetSpuData() {
|
||||
this.spu = {
|
||||
spuName: "",
|
||||
spuDescription: "",
|
||||
catalogId: 0,
|
||||
brandId: "",
|
||||
weight: "",
|
||||
publishStatus: 0,
|
||||
decript: [],
|
||||
images: [],
|
||||
bounds: {
|
||||
buyBounds: 0,
|
||||
growBounds: 0
|
||||
},
|
||||
baseAttrs: [],
|
||||
skus: []
|
||||
};
|
||||
},
|
||||
handlePriceChange(scope, mpidx, e) {
|
||||
this.spu.skus[scope.$index].memberPrice[mpidx].price = e;
|
||||
},
|
||||
// 查询所有会员信息
|
||||
getMemberLevels() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/member/memberlevel/list"),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
page: 1,
|
||||
limit: 500
|
||||
})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
this.dataResp.memberLevels = data.page.list;
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
},
|
||||
showInput(idx) {
|
||||
console.log("``````", this.view);
|
||||
this.inputVisible[idx].view = true;
|
||||
// this.$refs['saveTagInput'+idx].$refs.input.focus();
|
||||
},
|
||||
checkDefaultImg(row, index, img) {
|
||||
console.log("默认图片", row, index);
|
||||
//这个图片被选中了,
|
||||
row.images[index].imgUrl = img; //默认选中
|
||||
row.images[index].defaultImg = 1; //修改标志位;
|
||||
//修改其他人的标志位
|
||||
row.images.forEach((item, idx) => {
|
||||
if (idx != index) {
|
||||
row.images[idx].defaultImg = 0;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleInputConfirm(idx) {
|
||||
let inputValue = this.inputValue[idx].val;
|
||||
if (inputValue) {
|
||||
// this.dynamicTags.push(inputValue);
|
||||
if (this.dataResp.saleAttrs[idx].valueSelect == "") {
|
||||
this.dataResp.saleAttrs[idx].valueSelect = inputValue;
|
||||
} else {
|
||||
this.dataResp.saleAttrs[idx].valueSelect += ";" + inputValue;
|
||||
}
|
||||
}
|
||||
this.inputVisible[idx].view = false;
|
||||
this.inputValue[idx].val = "";
|
||||
},
|
||||
collectSpuBaseInfo() {
|
||||
//spuBaseForm
|
||||
this.$refs.spuBaseForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.step = 1;
|
||||
this.showBaseAttrs();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
generateSaleAttrs() {
|
||||
//把页面绑定的所有attr处理到spu里面,这一步都要做
|
||||
this.spu.baseAttrs = [];
|
||||
this.dataResp.baseAttrs.forEach(item => {
|
||||
item.forEach(attr => {
|
||||
// console.log("笛卡尔生成组合:" , attr);
|
||||
let { attrId, attrValues, showDesc } = attr;
|
||||
//跳过没有录入值的属性
|
||||
if (attrValues != "") {
|
||||
if (attrValues instanceof Array) {
|
||||
//多个值用;隔开
|
||||
attrValues = attrValues.join(";");
|
||||
}
|
||||
this.spu.baseAttrs.push({ attrId, attrValues, showDesc });
|
||||
}
|
||||
});
|
||||
});
|
||||
// console.log("baseAttrs", this.spu.baseAttrs);
|
||||
this.step = 2;
|
||||
this.getShowSaleAttr();
|
||||
},
|
||||
generateSkus() {
|
||||
this.step = 3;
|
||||
|
||||
//根据笛卡尔积运算进行生成sku
|
||||
let selectValues = [];
|
||||
this.dataResp.tableAttrColumn = [];
|
||||
this.dataResp.tempSaleAttrs.forEach(item => {
|
||||
if (item.attrValues.length > 0) {
|
||||
selectValues.push(item.attrValues);
|
||||
this.dataResp.tableAttrColumn.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
let descartes = this.descartes(selectValues);
|
||||
//[["黑色","6GB","移动"],["黑色","6GB","联通"],["黑色","8GB","移动"],["黑色","8GB","联通"],
|
||||
//["白色","6GB","移动"],["白色","6GB","联通"],["白色","8GB","移动"],["白色","8GB","联通"],
|
||||
//["蓝色","6GB","移动"],["蓝色","6GB","联通"],["蓝色","8GB","移动"],["蓝色","8GB","联通"]]
|
||||
// console.log("笛卡尔生成的组合", JSON.stringify(descartes));
|
||||
//有多少descartes就有多少sku
|
||||
let skus = [];
|
||||
|
||||
descartes.forEach((descar, descaridx) => {
|
||||
let attrArray = []; //sku属性组
|
||||
descar.forEach((de, index) => {
|
||||
//构造saleAttr信息
|
||||
let saleAttrItem = {
|
||||
attrId: this.dataResp.tableAttrColumn[index].attrId,
|
||||
attrName: this.dataResp.tableAttrColumn[index].attrName,
|
||||
attrValue: de
|
||||
};
|
||||
attrArray.push(saleAttrItem);
|
||||
});
|
||||
//先初始化几个images,后面的上传还要加
|
||||
let imgs = [];
|
||||
this.spu.images.forEach((img, idx) => {
|
||||
imgs.push({ imgUrl: "", defaultImg: 0 });
|
||||
});
|
||||
|
||||
//会员价,也必须在循环里面生成,否则会导致数据绑定问题
|
||||
let memberPrices = [];
|
||||
if (this.dataResp.memberLevels.length > 0) {
|
||||
for (let i = 0; i < this.dataResp.memberLevels.length; i++) {
|
||||
if (this.dataResp.memberLevels[i].priviledgeMemberPrice == 1) {
|
||||
memberPrices.push({
|
||||
id: this.dataResp.memberLevels[i].id,
|
||||
name: this.dataResp.memberLevels[i].name,
|
||||
price: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
//;descaridx,判断如果之前有就用之前的值;
|
||||
let res = this.hasAndReturnSku(this.spu.skus, descar);
|
||||
if (res === null) {
|
||||
skus.push({
|
||||
attr: attrArray,
|
||||
skuName: this.spu.spuName + " " + descar.join(" "),
|
||||
price: 0,
|
||||
skuTitle: this.spu.spuName + " " + descar.join(" "),
|
||||
skuSubtitle: "",
|
||||
images: imgs,
|
||||
descar: descar,
|
||||
fullCount: 0,
|
||||
discount: 0,
|
||||
countStatus: 0,
|
||||
fullPrice: 0.0,
|
||||
reducePrice: 0.0,
|
||||
priceStatus: 0,
|
||||
memberPrice: new Array().concat(memberPrices)
|
||||
});
|
||||
} else {
|
||||
skus.push(res);
|
||||
}
|
||||
});
|
||||
this.spu.skus = skus;
|
||||
// console.log("结果!!!", this.spu.skus, this.dataResp.tableAttrColumn);
|
||||
},
|
||||
//判断如果包含之前的sku的descar组合,就返回这个sku的详细信息;
|
||||
hasAndReturnSku(skus, descar) {
|
||||
let res = null;
|
||||
if (skus.length > 0) {
|
||||
for (let i = 0; i < skus.length; i++) {
|
||||
if (skus[i].descar.join(" ") == descar.join(" ")) {
|
||||
res = skus[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getShowSaleAttr() {
|
||||
//获取当前分类可以使用的销售属性
|
||||
if (!this.dataResp.steped[1]) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attr/sale/list/${this.spu.catalogId}`
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({
|
||||
page: 1,
|
||||
limit: 500
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
this.dataResp.saleAttrs = data.page.list;
|
||||
data.page.list.forEach(item => {
|
||||
this.dataResp.tempSaleAttrs.push({
|
||||
attrId: item.attrId,
|
||||
attrValues: [],
|
||||
attrName: item.attrName
|
||||
});
|
||||
this.inputVisible.push({ view: false });
|
||||
this.inputValue.push({ val: "" });
|
||||
});
|
||||
this.dataResp.steped[1] = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
showBaseAttrs() {
|
||||
if (!this.dataResp.steped[0]) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl(
|
||||
`/product/attrgroup/${this.spu.catalogId}/withattr`
|
||||
),
|
||||
method: "get",
|
||||
params: this.$http.adornParams({})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
//先对表单的baseAttrs进行初始化
|
||||
data.data.forEach(item => {
|
||||
// 输出基本信息
|
||||
// console.log(item)
|
||||
let attrArray = [];
|
||||
// 显示基本属性
|
||||
if (item.attrs != null) {
|
||||
item.attrs.forEach(attr => {
|
||||
attrArray.push({
|
||||
attrId: attr.attrId,
|
||||
attrValues: "",
|
||||
showDesc: attr.showDesc
|
||||
});
|
||||
});
|
||||
}
|
||||
this.dataResp.baseAttrs.push(attrArray);
|
||||
});
|
||||
this.dataResp.steped[0] = 0;
|
||||
this.dataResp.attrGroups = data.data;
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
submitSkus() {
|
||||
console.log("~~~~~", JSON.stringify(this.spu));
|
||||
this.$confirm("将要提交商品数据,需要一小段时间,是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/spuinfo/save"),
|
||||
method: "post",
|
||||
data: this.$http.adornData(this.spu, false)
|
||||
}).then(({ data }) => {
|
||||
if (data.code == 0) {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "新增商品成功!"
|
||||
});
|
||||
this.step = 4;
|
||||
} else {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: "保存失败,原因【" + data.msg + "】"
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
// console.log("已取消");
|
||||
this.$message({
|
||||
type: "info",
|
||||
message: "已取消"
|
||||
});
|
||||
});
|
||||
},
|
||||
//笛卡尔积运算
|
||||
descartes(list) {
|
||||
//parent上一级索引;count指针计数
|
||||
var point = {};
|
||||
|
||||
var result = [];
|
||||
var pIndex = null;
|
||||
var tempCount = 0;
|
||||
var temp = [];
|
||||
|
||||
//根据参数列生成指针对象
|
||||
for (var index in list) {
|
||||
if (typeof list[index] == "object") {
|
||||
point[index] = { parent: pIndex, count: 0 };
|
||||
pIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
//单维度数据结构直接返回
|
||||
if (pIndex == null) {
|
||||
return list;
|
||||
}
|
||||
|
||||
//动态生成笛卡尔积
|
||||
while (true) {
|
||||
for (var index in list) {
|
||||
tempCount = point[index]["count"];
|
||||
temp.push(list[index][tempCount]);
|
||||
}
|
||||
|
||||
//压入结果数组
|
||||
result.push(temp);
|
||||
temp = [];
|
||||
|
||||
//检查指针最大值问题
|
||||
while (true) {
|
||||
if (point[index]["count"] + 1 >= list[index].length) {
|
||||
point[index]["count"] = 0;
|
||||
pIndex = point[index]["parent"];
|
||||
if (pIndex == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//赋值parent进行再次检查
|
||||
index = pIndex;
|
||||
} else {
|
||||
point[index]["count"]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
//生命周期 - 创建完成(可以访问当前this实例)
|
||||
created() {},
|
||||
//生命周期 - 挂载完成(可以访问DOM元素)
|
||||
mounted() {
|
||||
// 当用户点击三级分类id时 准备给品牌查询
|
||||
this.catPathSub = PubSub.subscribe("catPath", (msg, val) => {
|
||||
this.spu.catalogId = val[val.length - 1];
|
||||
});
|
||||
this.brandIdSub = PubSub.subscribe("brandId", (msg, val) => {
|
||||
this.spu.brandId = val;
|
||||
});
|
||||
this.getMemberLevels();
|
||||
},
|
||||
beforeCreate() {}, //生命周期 - 创建之前
|
||||
beforeMount() {}, //生命周期 - 挂载之前
|
||||
beforeUpdate() {}, //生命周期 - 更新之前
|
||||
updated() {}, //生命周期 - 更新之后
|
||||
beforeDestroy() {
|
||||
PubSub.unsubscribe(this.catPathSub);
|
||||
PubSub.unsubscribe(this.brandIdSub);
|
||||
}, //生命周期 - 销毁之前
|
||||
destroyed() {}, //生命周期 - 销毁完成
|
||||
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
156
renren-fast-vue/src/views/modules/product/spuinfo.vue
Normal file
156
renren-fast-vue/src/views/modules/product/spuinfo.vue
Normal file
|
@ -0,0 +1,156 @@
|
|||
<template>
|
||||
<div class="mod-config">
|
||||
<el-table
|
||||
:data="dataList"
|
||||
border
|
||||
v-loading="dataListLoading"
|
||||
@selection-change="selectionChangeHandle"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
|
||||
<el-table-column prop="id" header-align="center" align="center" label="id"></el-table-column>
|
||||
<el-table-column prop="spuName" header-align="center" align="center" label="名称"></el-table-column>
|
||||
<el-table-column prop="spuDescription" header-align="center" align="center" label="描述"></el-table-column>
|
||||
<el-table-column prop="catalogId" header-align="center" align="center" label="分类"></el-table-column>
|
||||
<el-table-column prop="brandId" header-align="center" align="center" label="品牌"></el-table-column>
|
||||
<el-table-column prop="weight" header-align="center" align="center" label="重量(kg)"></el-table-column>
|
||||
<el-table-column prop="publishStatus" header-align="center" align="center" label="上架状态">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.publishStatus == 0">新建</el-tag>
|
||||
<el-tag v-if="scope.row.publishStatus == 1">已上架</el-tag>
|
||||
<el-tag v-if="scope.row.publishStatus == 2">已下架</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" header-align="center" align="center" label="创建时间"></el-table-column>
|
||||
<el-table-column prop="updateTime" header-align="center" align="center" label="修改时间"></el-table-column>
|
||||
<el-table-column fixed="right" header-align="center" align="center" width="150" label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
v-if="scope.row.publishStatus == 0"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="productUp(scope.row.id)"
|
||||
>上架</el-button>
|
||||
<el-button type="text" size="small" @click="attrUpdateShow(scope.row)">规格</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
:total="totalPage"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataSub: null,
|
||||
dataForm: {},
|
||||
dataList: [],
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
totalPage: 0,
|
||||
dataListLoading: false,
|
||||
dataListSelections: [],
|
||||
addOrUpdateVisible: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
catId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
activated() {
|
||||
this.getDataList();
|
||||
},
|
||||
methods: {
|
||||
productUp(id) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/spuinfo/" + id + "/up"),
|
||||
method: "post"
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
duration: 1500,
|
||||
onClose: () => {
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 跳转到规格
|
||||
attrUpdateShow(row) {
|
||||
// console.log(row);
|
||||
this.$router.push({
|
||||
path: "/product-attrupdate",
|
||||
query: { spuId: row.id, catalogId: row.catalogId }
|
||||
});
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
let param = {};
|
||||
Object.assign(param, this.dataForm, {
|
||||
page: this.pageIndex,
|
||||
limit: this.pageSize
|
||||
});
|
||||
this.$http({
|
||||
url: this.$http.adornUrl("/product/spuinfo/list"),
|
||||
method: "get",
|
||||
params: this.$http.adornParams(param)
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dataList = data.page.list;
|
||||
this.totalPage = data.page.totalCount;
|
||||
} else {
|
||||
this.dataList = [];
|
||||
this.totalPage = 0;
|
||||
}
|
||||
this.dataListLoading = false;
|
||||
});
|
||||
},
|
||||
// 每页数
|
||||
sizeChangeHandle(val) {
|
||||
this.pageSize = val;
|
||||
this.pageIndex = 1;
|
||||
this.getDataList();
|
||||
},
|
||||
// 当前页
|
||||
currentChangeHandle(val) {
|
||||
this.pageIndex = val;
|
||||
this.getDataList();
|
||||
},
|
||||
// 多选
|
||||
selectionChangeHandle(val) {
|
||||
this.dataListSelections = val;
|
||||
},
|
||||
// 新增 / 修改
|
||||
addOrUpdateHandle(id) {}
|
||||
},
|
||||
mounted() {
|
||||
this.dataSub = PubSub.subscribe("dataForm", (msg, val) => {
|
||||
// console.log("查询条件", val);
|
||||
this.dataForm = val;
|
||||
this.getDataList();
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
PubSub.unsubscribe(this.dataSub);
|
||||
}
|
||||
};
|
||||
</script>
|
Loading…
Reference in a new issue