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: 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" 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" 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>
|
</component>
|
||||||
</module>
|
</module>
|
|
@ -84,5 +84,10 @@
|
||||||
<version>${javax.servlet.version}</version>
|
<version>${javax.servlet.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
<version>2.0.1.Final</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</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/**
|
- Path=/api/ware/**
|
||||||
filters:
|
filters:
|
||||||
- RewritePath=/api/(?<segment>.*), /$\{segment}
|
- 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/*路径
|
#过滤器要放最下面才不会被替换路径/api/*路径
|
||||||
- id: admin_route
|
- id: admin_route
|
||||||
uri: lb://kkmall-admin
|
uri: lb://kkmall-admin
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package name.lkk.kkmall.product.controller;
|
package name.lkk.kkmall.product.controller;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import name.lkk.kkmall.product.entity.BrandEntity;
|
import name.lkk.kkmall.product.entity.BrandEntity;
|
||||||
import name.lkk.kkmall.product.service.BrandService;
|
import name.lkk.kkmall.product.service.BrandService;
|
||||||
|
@ -53,12 +54,19 @@ public class BrandController {
|
||||||
return R.ok().put("brand", brand);
|
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")
|
@RequestMapping("/save")
|
||||||
//@RequiresPermissions("product:brand:save")
|
public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand) {
|
||||||
public R save(@RequestBody BrandEntity brand){
|
|
||||||
brandService.save(brand);
|
brandService.save(brand);
|
||||||
|
|
||||||
return R.ok();
|
return R.ok();
|
||||||
|
@ -66,12 +74,20 @@ public class BrandController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改
|
* 修改
|
||||||
|
* POSTman:{"name":"aaa","logo":"abc"}
|
||||||
*/
|
*/
|
||||||
@RequestMapping("/update")
|
@RequestMapping("/update")
|
||||||
//@RequiresPermissions("product:brand:update")
|
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand) {
|
||||||
public R update(@RequestBody BrandEntity brand){
|
brandService.updateDetail(brand);
|
||||||
brandService.updateById(brand);
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改状态
|
||||||
|
*/
|
||||||
|
@RequestMapping("/update/status")
|
||||||
|
public R updateStatus(@Validated(UpdateStatusGroup.class) @RequestBody BrandEntity brand) {
|
||||||
|
brandService.updateById(brand);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,35 +2,52 @@ package name.lkk.kkmall.product.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Data;
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 品牌
|
* 品牌
|
||||||
*
|
* 自定义JSR303校验
|
||||||
* @author KirkLin
|
* 根据分组进行校验 Controller里面要进行规定
|
||||||
* @email linkirk@163.com
|
|
||||||
* @date 2021-06-07 15:14:37
|
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("pms_brand")
|
@TableName("pms_brand")
|
||||||
public class BrandEntity implements Serializable {
|
public class BrandEntity implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 品牌id
|
* 品牌id
|
||||||
|
* POSTman:{"name":"aaa","logo":"abc","brandId":1}
|
||||||
*/
|
*/
|
||||||
|
@NotNull(message = "修改必须定制品牌id", groups = {UpdateGroup.class})
|
||||||
|
@Null(message = "新增不能指定id", groups = {AddGroup.class})
|
||||||
@TableId
|
@TableId
|
||||||
private Long brandId;
|
private Long brandId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 品牌名
|
* 品牌名
|
||||||
*/
|
*/
|
||||||
|
@NotBlank(message = "品牌名必须提交", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 品牌logo地址
|
* 品牌logo地址 修改可以不带上logoURL
|
||||||
*/
|
*/
|
||||||
|
@NotBlank(groups = {AddGroup.class})
|
||||||
|
@URL(message = "logo必须是一个合法的URL地址", groups={AddGroup.class, UpdateGroup.class})
|
||||||
private String logo;
|
private String logo;
|
||||||
/**
|
/**
|
||||||
* 介绍
|
* 介绍
|
||||||
|
@ -39,14 +56,21 @@ public class BrandEntity implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 显示状态[0-不显示;1-显示]
|
* 显示状态[0-不显示;1-显示]
|
||||||
*/
|
*/
|
||||||
|
@NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})
|
||||||
|
@ListValue(vals = {0,1}, groups = {AddGroup.class, UpdateGroup.class, UpdateStatusGroup.class})
|
||||||
private Integer showStatus;
|
private Integer showStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检索首字母
|
* 检索首字母 修改可以不带, 不管是新增还是修改都必须是一个字母
|
||||||
*/
|
*/
|
||||||
|
@NotEmpty(groups = {AddGroup.class})
|
||||||
|
@Pattern(regexp = "^[a-zA-Z]$", message = "检索首字母必须是一个字母", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
private String firstLetter;
|
private String firstLetter;
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
*/
|
*/
|
||||||
|
@NotNull(groups = {AddGroup.class})
|
||||||
|
@Min(value = 0, message = "排序必须是一个正整数" , groups = {AddGroup.class, UpdateGroup.class})
|
||||||
private Integer sort;
|
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.common.utils.PageUtils;
|
||||||
import name.lkk.kkmall.product.entity.BrandEntity;
|
import name.lkk.kkmall.product.entity.BrandEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,5 +17,13 @@ import java.util.Map;
|
||||||
public interface BrandService extends IService<BrandEntity> {
|
public interface BrandService extends IService<BrandEntity> {
|
||||||
|
|
||||||
PageUtils queryPage(Map<String, Object> params);
|
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> {
|
public interface CategoryBrandRelationService extends IService<CategoryBrandRelationEntity> {
|
||||||
|
|
||||||
PageUtils queryPage(Map<String, Object> params);
|
PageUtils queryPage(Map<String, Object> params);
|
||||||
|
|
||||||
|
void updateBrand(Long brandId, String name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package name.lkk.kkmall.product.service.impl;
|
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 org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
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.dao.BrandDao;
|
||||||
import name.lkk.kkmall.product.entity.BrandEntity;
|
import name.lkk.kkmall.product.entity.BrandEntity;
|
||||||
import name.lkk.kkmall.product.service.BrandService;
|
import name.lkk.kkmall.product.service.BrandService;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
@Service("brandService")
|
@Service("brandService")
|
||||||
public class BrandServiceImpl extends ServiceImpl<BrandDao, BrandEntity> implements BrandService {
|
public class BrandServiceImpl extends ServiceImpl<BrandDao, BrandEntity> implements BrandService {
|
||||||
|
@Autowired
|
||||||
|
private CategoryBrandRelationService categoryBrandRelationService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageUtils queryPage(Map<String, Object> params) {
|
public PageUtils queryPage(Map<String, Object> params) {
|
||||||
|
@ -26,4 +34,24 @@ public class BrandServiceImpl extends ServiceImpl<BrandDao, BrandEntity> impleme
|
||||||
return new PageUtils(page);
|
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;
|
package name.lkk.kkmall.product.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
@ -26,4 +27,13 @@ public class CategoryBrandRelationServiceImpl extends ServiceImpl<CategoryBrandR
|
||||||
return new PageUtils(page);
|
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 = () => ({
|
const createLintingRule = () => ({
|
||||||
test: /\.(js|vue)$/,
|
//关闭语法检查
|
||||||
loader: 'eslint-loader',
|
// test: /\.(js|vue)$/,
|
||||||
enforce: 'pre',
|
// loader: 'eslint-loader',
|
||||||
include: [resolve('src'), resolve('test')],
|
// enforce: 'pre',
|
||||||
options: {
|
// include: [resolve('src'), resolve('test')],
|
||||||
formatter: require('eslint-friendly-formatter'),
|
// options: {
|
||||||
emitWarning: !config.dev.showEslintErrorsInOverlay
|
// formatter: require('eslint-friendly-formatter'),
|
||||||
}
|
// emitWarning: !config.dev.showEslintErrorsInOverlay
|
||||||
|
// }
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = {
|
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
|
* @param {*} key
|
||||||
*/
|
*/
|
||||||
export function isAuth (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