Commit fdb2d7339fbec1163d53ebd1bce35207aa55290b
1 parent
f122c0c5
feature(管理后台): 商品列表
Showing
8 changed files
with
536 additions
and
249 deletions
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java
| @@ -29,4 +29,19 @@ public class ProductSpuPageReqVO extends PageParam { | @@ -29,4 +29,19 @@ public class ProductSpuPageReqVO extends PageParam { | ||
| 29 | @ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)") | 29 | @ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)") |
| 30 | private Integer status; | 30 | private Integer status; |
| 31 | 31 | ||
| 32 | + @ApiModelProperty(value = "销量最小值", example = "1") | ||
| 33 | + private Integer salesCountMin; | ||
| 34 | + | ||
| 35 | + @ApiModelProperty(value = "销量最大值", example = "1024") | ||
| 36 | + private Integer salesCountMax; | ||
| 37 | + | ||
| 38 | + @ApiModelProperty(value = "市场价最小值", example = "1") | ||
| 39 | + private Integer marketPriceMin; | ||
| 40 | + | ||
| 41 | + @ApiModelProperty(value = "市场价最大值", example = "1024") | ||
| 42 | + private Integer marketPriceMax; | ||
| 43 | + | ||
| 44 | + @ApiModelProperty(value = "tab 状态 null 全部, 0:销售中(上架) 1:仓库中(下架) 2:预警中", example = "1") | ||
| 45 | + private Integer tabStatus; | ||
| 46 | + | ||
| 32 | } | 47 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
| @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReq | @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReq | ||
| 7 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; | 7 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; |
| 8 | import org.apache.ibatis.annotations.Mapper; | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 9 | ||
| 10 | +import java.util.List; | ||
| 11 | + | ||
| 10 | /** | 12 | /** |
| 11 | * 商品spu Mapper | 13 | * 商品spu Mapper |
| 12 | * | 14 | * |
| @@ -20,7 +22,32 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> { | @@ -20,7 +22,32 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> { | ||
| 20 | .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) | 22 | .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) |
| 21 | .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) | 23 | .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) |
| 22 | .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) | 24 | .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) |
| 25 | + .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) | ||
| 26 | + .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) | ||
| 27 | + .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) | ||
| 28 | + .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) | ||
| 23 | .orderByDesc(ProductSpuDO::getSort)); | 29 | .orderByDesc(ProductSpuDO::getSort)); |
| 24 | } | 30 | } |
| 25 | 31 | ||
| 32 | + default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO, List<Long> spuIds) { | ||
| 33 | + LambdaQueryWrapperX<ProductSpuDO> productSpuDOLambdaQueryWrapperX = new LambdaQueryWrapperX<ProductSpuDO>() | ||
| 34 | + .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) | ||
| 35 | + .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) | ||
| 36 | + .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) | ||
| 37 | + .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) | ||
| 38 | + .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) | ||
| 39 | + .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) | ||
| 40 | + .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) | ||
| 41 | + .orderByDesc(ProductSpuDO::getSort); | ||
| 42 | + | ||
| 43 | + if(reqVO.getTabStatus()!= null && reqVO.getTabStatus() == 2){ | ||
| 44 | + productSpuDOLambdaQueryWrapperX.inIfPresent(ProductSpuDO::getId, spuIds); | ||
| 45 | + }else{ | ||
| 46 | + productSpuDOLambdaQueryWrapperX.eqIfPresent(ProductSpuDO::getStatus, reqVO.getTabStatus()); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + return selectPage(reqVO, productSpuDOLambdaQueryWrapperX); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + | ||
| 26 | } | 53 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
| @@ -83,4 +83,11 @@ public interface ProductSkuService { | @@ -83,4 +83,11 @@ public interface ProductSkuService { | ||
| 83 | */ | 83 | */ |
| 84 | void deleteSkuBySpuId(Long spuId); | 84 | void deleteSkuBySpuId(Long spuId); |
| 85 | 85 | ||
| 86 | + /** | ||
| 87 | + * 获得商品预警中的spu集合 | ||
| 88 | + * | ||
| 89 | + * @return 商品spuId集合 | ||
| 90 | + */ | ||
| 91 | + List<Long> getRemindSpuIds(); | ||
| 92 | + | ||
| 86 | } | 93 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.service.sku; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.service.sku; | ||
| 3 | import cn.hutool.core.collection.CollectionUtil; | 3 | import cn.hutool.core.collection.CollectionUtil; |
| 4 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 6 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; | 7 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; |
| 7 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; | 8 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; |
| 8 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; | 9 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; |
| @@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; | @@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; | ||
| 14 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; | 15 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; |
| 15 | import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; | 16 | import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; |
| 16 | import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; | 17 | import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; |
| 18 | +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||
| 17 | import org.springframework.stereotype.Service; | 19 | import org.springframework.stereotype.Service; |
| 18 | import org.springframework.transaction.annotation.Transactional; | 20 | import org.springframework.transaction.annotation.Transactional; |
| 19 | import org.springframework.validation.annotation.Validated; | 21 | import org.springframework.validation.annotation.Validated; |
| @@ -132,6 +134,12 @@ public class ProductSkuServiceImpl implements ProductSkuService { | @@ -132,6 +134,12 @@ public class ProductSkuServiceImpl implements ProductSkuService { | ||
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | @Override | 136 | @Override |
| 137 | + public List<Long> getRemindSpuIds() { | ||
| 138 | + List<ProductSkuDO> productSkuDOS = productSkuMapper.selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock")); | ||
| 139 | + return productSkuDOS.stream().map(ProductSkuDO::getSpuId).distinct().collect(Collectors.toList()); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + @Override | ||
| 135 | @Transactional | 143 | @Transactional |
| 136 | public void updateProductSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) { | 144 | public void updateProductSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) { |
| 137 | // 查询 SPU 下已经存在的 SKU 的集合 | 145 | // 查询 SPU 下已经存在的 SKU 的集合 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
| @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.product.service.spu; | @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.product.service.spu; | ||
| 3 | import cn.hutool.core.bean.BeanUtil; | 3 | import cn.hutool.core.bean.BeanUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 6 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; | ||
| 7 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; | 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; |
| 7 | +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; | ||
| 8 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; | 8 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; |
| 9 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; | 9 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; |
| 10 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; | 10 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; |
| @@ -190,16 +190,15 @@ public class ProductSpuServiceImpl implements ProductSpuService { | @@ -190,16 +190,15 @@ public class ProductSpuServiceImpl implements ProductSpuService { | ||
| 190 | 190 | ||
| 191 | @Override | 191 | @Override |
| 192 | public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { | 192 | public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { |
| 193 | - PageResult<ProductSpuRespVO> spuVOs = ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO)); | ||
| 194 | - // 查询 sku 的信息 | ||
| 195 | -// List<Long> spuIds = spuVOs.getList().stream().map(ProductSpuRespVO::getId).collect(Collectors.toList()); | ||
| 196 | -// List<ProductSkuRespVO> skus = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuIds(spuIds)); | ||
| 197 | - // TODO @franky:使用 CollUtil 里的方法替代哈 | ||
| 198 | - // TODO 芋艿:临时注释 | ||
| 199 | -// Map<Long, List<ProductSkuRespVO>> skuMap = skus.stream().collect(Collectors.groupingBy(ProductSkuRespVO::getSpuId)); | ||
| 200 | -// // 将 spu 和 sku 进行组装 | ||
| 201 | -// spuVOs.getList().forEach(p -> p.setSkus(skuMap.get(p.getId()))); | ||
| 202 | - return spuVOs; | 193 | + List<Long> remindSpuIds= null; |
| 194 | + // todo @yunai 预警类型的判断应该可以优化,看下怎么处理 | ||
| 195 | + if(pageReqVO.getTabStatus() != null && pageReqVO.getTabStatus() == 2){ | ||
| 196 | + remindSpuIds= productSkuService.getRemindSpuIds(); | ||
| 197 | + if(remindSpuIds.isEmpty()){ | ||
| 198 | + remindSpuIds.add(null); | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + return ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO, remindSpuIds)); | ||
| 203 | } | 202 | } |
| 204 | 203 | ||
| 205 | @Override | 204 | @Override |
yudao-ui-admin/src/views/mall/product/property/value.vue
| @@ -24,7 +24,8 @@ | @@ -24,7 +24,8 @@ | ||
| 24 | <el-row :gutter="10" class="mb8"> | 24 | <el-row :gutter="10" class="mb8"> |
| 25 | <el-col :span="1.5"> | 25 | <el-col :span="1.5"> |
| 26 | <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" | 26 | <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" |
| 27 | - v-hasPermi="['system:dict:create']">新增</el-button> | 27 | + v-hasPermi="['system:dict:create']">新增 |
| 28 | + </el-button> | ||
| 28 | </el-col> | 29 | </el-col> |
| 29 | <!-- <el-col :span="1.5"> | 30 | <!-- <el-col :span="1.5"> |
| 30 | <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading" | 31 | <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading" |
| @@ -33,15 +34,15 @@ | @@ -33,15 +34,15 @@ | ||
| 33 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | 34 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| 34 | </el-row> | 35 | </el-row> |
| 35 | 36 | ||
| 36 | - <el-table v-loading="loading" :data="dataList" > | ||
| 37 | - <el-table-column label="规格值id" align="center" prop="id" /> | ||
| 38 | - <el-table-column label="规格值" align="center" prop="name" /> | 37 | + <el-table v-loading="loading" :data="dataList"> |
| 38 | + <el-table-column label="规格值id" align="center" prop="id"/> | ||
| 39 | + <el-table-column label="规格值" align="center" prop="name"/> | ||
| 39 | <el-table-column label="状态" align="center" prop="status"> | 40 | <el-table-column label="状态" align="center" prop="status"> |
| 40 | <template slot-scope="scope"> | 41 | <template slot-scope="scope"> |
| 41 | <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> | 42 | <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> |
| 42 | </template> | 43 | </template> |
| 43 | </el-table-column> | 44 | </el-table-column> |
| 44 | - <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" /> | 45 | + <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true"/> |
| 45 | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | 46 | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| 46 | <template slot-scope="scope"> | 47 | <template slot-scope="scope"> |
| 47 | <span>{{ parseTime(scope.row.createTime) }}</span> | 48 | <span>{{ parseTime(scope.row.createTime) }}</span> |
| @@ -50,9 +51,11 @@ | @@ -50,9 +51,11 @@ | ||
| 50 | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | 51 | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| 51 | <template slot-scope="scope"> | 52 | <template slot-scope="scope"> |
| 52 | <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | 53 | <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" |
| 53 | - v-hasPermi="['system:dict:update']">修改</el-button> | 54 | + v-hasPermi="['system:dict:update']">修改 |
| 55 | + </el-button> | ||
| 54 | <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | 56 | <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" |
| 55 | - v-hasPermi="['system:dict:delete']">删除</el-button> | 57 | + v-hasPermi="['system:dict:delete']">删除 |
| 58 | + </el-button> | ||
| 56 | </template> | 59 | </template> |
| 57 | </el-table-column> | 60 | </el-table-column> |
| 58 | </el-table> | 61 | </el-table> |
| @@ -64,10 +67,10 @@ | @@ -64,10 +67,10 @@ | ||
| 64 | <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> | 67 | <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> |
| 65 | <el-form ref="form" :model="form" :rules="rules" label-width="90px"> | 68 | <el-form ref="form" :model="form" :rules="rules" label-width="90px"> |
| 66 | <el-form-item label="规格值编码"> | 69 | <el-form-item label="规格值编码"> |
| 67 | - <el-input v-model="form.propertyId" :disabled="true" /> | 70 | + <el-input v-model="form.propertyId" :disabled="true"/> |
| 68 | </el-form-item> | 71 | </el-form-item> |
| 69 | <el-form-item label="规格值" prop="name"> | 72 | <el-form-item label="规格值" prop="name"> |
| 70 | - <el-input v-model="form.name" placeholder="请输入数据标签" /> | 73 | + <el-input v-model="form.name" placeholder="请输入数据标签"/> |
| 71 | </el-form-item> | 74 | </el-form-item> |
| 72 | <el-form-item label="状态" prop="status"> | 75 | <el-form-item label="状态" prop="status"> |
| 73 | <el-radio-group v-model="form.status"> | 76 | <el-radio-group v-model="form.status"> |
| @@ -89,8 +92,15 @@ | @@ -89,8 +92,15 @@ | ||
| 89 | </template> | 92 | </template> |
| 90 | 93 | ||
| 91 | <script> | 94 | <script> |
| 92 | -import { getPropertyList, getPropertyValuePage, createPropertyValue, updatePropertyValue, getPropertyValue, deletePropertyValue } from '@/api/mall/product/property' | ||
| 93 | -import { getProperty } from "@/api/mall/product/property"; | 95 | +import { |
| 96 | + createPropertyValue, | ||
| 97 | + deletePropertyValue, | ||
| 98 | + getProperty, | ||
| 99 | + getPropertyList, | ||
| 100 | + getPropertyValue, | ||
| 101 | + getPropertyValuePage, | ||
| 102 | + updatePropertyValue | ||
| 103 | +} from '@/api/mall/product/property' | ||
| 94 | 104 | ||
| 95 | export default { | 105 | export default { |
| 96 | name: "PropertyValue", | 106 | name: "PropertyValue", |
| @@ -127,10 +137,10 @@ export default { | @@ -127,10 +137,10 @@ export default { | ||
| 127 | // 表单校验 | 137 | // 表单校验 |
| 128 | rules: { | 138 | rules: { |
| 129 | name: [ | 139 | name: [ |
| 130 | - { required: true, message: "规格值不能为空", trigger: "blur" } | 140 | + {required: true, message: "规格值不能为空", trigger: "blur"} |
| 131 | ], | 141 | ], |
| 132 | status: [ | 142 | status: [ |
| 133 | - { required: true, message: "状态不能为空", trigger: "blur" } | 143 | + {required: true, message: "状态不能为空", trigger: "blur"} |
| 134 | ] | 144 | ] |
| 135 | }, | 145 | }, |
| 136 | 146 | ||
| @@ -210,7 +220,7 @@ export default { | @@ -210,7 +220,7 @@ export default { | ||
| 210 | }); | 220 | }); |
| 211 | }, | 221 | }, |
| 212 | /** 提交按钮 */ | 222 | /** 提交按钮 */ |
| 213 | - submitForm: function() { | 223 | + submitForm: function () { |
| 214 | this.$refs["form"].validate(valid => { | 224 | this.$refs["form"].validate(valid => { |
| 215 | if (valid) { | 225 | if (valid) { |
| 216 | if (this.form.id !== undefined) { | 226 | if (this.form.id !== undefined) { |
| @@ -232,23 +242,25 @@ export default { | @@ -232,23 +242,25 @@ export default { | ||
| 232 | /** 删除按钮操作 */ | 242 | /** 删除按钮操作 */ |
| 233 | handleDelete(row) { | 243 | handleDelete(row) { |
| 234 | const ids = row.id; | 244 | const ids = row.id; |
| 235 | - this.$modal.confirm('是否确认删除字典编码为"' + ids + '"的数据项?').then(function() { | ||
| 236 | - return deletePropertyValue(ids); | ||
| 237 | - }).then(() => { | ||
| 238 | - this.getList(); | ||
| 239 | - this.$modal.msgSuccess("删除成功"); | ||
| 240 | - }).catch(() => {}); | 245 | + this.$modal.confirm('是否确认删除字典编码为"' + ids + '"的数据项?').then(function () { |
| 246 | + return deletePropertyValue(ids); | ||
| 247 | + }).then(() => { | ||
| 248 | + this.getList(); | ||
| 249 | + this.$modal.msgSuccess("删除成功"); | ||
| 250 | + }).catch(() => { | ||
| 251 | + }); | ||
| 241 | }, | 252 | }, |
| 242 | /** 导出按钮操作 */ | 253 | /** 导出按钮操作 */ |
| 243 | handleExport() { | 254 | handleExport() { |
| 244 | const queryParams = this.queryParams; | 255 | const queryParams = this.queryParams; |
| 245 | this.$modal.confirm('是否确认导出所有数据项?').then(() => { | 256 | this.$modal.confirm('是否确认导出所有数据项?').then(() => { |
| 246 | - this.exportLoading = true; | ||
| 247 | - return exportData(queryParams); | ||
| 248 | - }).then(response => { | ||
| 249 | - this.$download.excel(response, '字典数据.xls'); | ||
| 250 | - this.exportLoading = false; | ||
| 251 | - }).catch(() => {}); | 257 | + this.exportLoading = true; |
| 258 | + return exportData(queryParams); | ||
| 259 | + }).then(response => { | ||
| 260 | + this.$download.excel(response, '字典数据.xls'); | ||
| 261 | + this.exportLoading = false; | ||
| 262 | + }).catch(() => { | ||
| 263 | + }); | ||
| 252 | } | 264 | } |
| 253 | } | 265 | } |
| 254 | }; | 266 | }; |
yudao-ui-admin/src/views/mall/product/spu/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="app-container"> | 2 | <div class="app-container"> |
| 3 | - <!-- 搜索工作栏 --> | ||
| 4 | - <!-- TODO @Luowenfeng:参考界面;https://v5.niuteam.cn/shop/goods/lists.html | ||
| 5 | - 商品名称、商品编码、商品分类、商品品牌 | ||
| 6 | - 商品销量、商品价格 | ||
| 7 | - --> | ||
| 8 | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> | 3 | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| 9 | <el-form-item label="商品名称" prop="name"> | 4 | <el-form-item label="商品名称" prop="name"> |
| 10 | <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/> | 5 | <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/> |
| 11 | </el-form-item> | 6 | </el-form-item> |
| 12 | 7 | ||
| 13 | <el-form-item label="商品编码" prop="code"> | 8 | <el-form-item label="商品编码" prop="code"> |
| 14 | - <el-input v-model="queryParams.code" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/> | 9 | + <el-input v-model="queryParams.code" placeholder="请输入商品编码" clearable @keyup.enter.native="handleQuery"/> |
| 15 | </el-form-item> | 10 | </el-form-item> |
| 16 | 11 | ||
| 17 | - <el-form-item label="商品分类" prop="categoryId"> | 12 | + <el-form-item label="商品分类" prop="categoryIds"> |
| 18 | <el-cascader v-model="queryParams.categoryIds" placeholder="请输入商品分类" | 13 | <el-cascader v-model="queryParams.categoryIds" placeholder="请输入商品分类" |
| 19 | - :options="categoryList" :props="propName" clearable ref="category" /> | 14 | + :options="categoryList" :props="propName" clearable ref="category"/> |
| 20 | </el-form-item> | 15 | </el-form-item> |
| 21 | 16 | ||
| 22 | <el-form-item label="商品品牌" prop="brandId"> | 17 | <el-form-item label="商品品牌" prop="brandId"> |
| 23 | <el-select v-model="queryParams.brandId" placeholder="请输入商品品牌" clearable @keyup.enter.native="handleQuery"> | 18 | <el-select v-model="queryParams.brandId" placeholder="请输入商品品牌" clearable @keyup.enter.native="handleQuery"> |
| 24 | - <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id" /> | 19 | + <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"/> |
| 25 | </el-select> | 20 | </el-select> |
| 26 | </el-form-item> | 21 | </el-form-item> |
| 27 | 22 | ||
| 23 | + <el-form-item label="商品销量"> | ||
| 24 | + <el-col | ||
| 25 | + :span="6" | ||
| 26 | + style="padding-left:0" | ||
| 27 | + > | ||
| 28 | + <el-form-item prop="salesCountMin"> | ||
| 29 | + <el-input v-model="queryParams.salesCountMin" placeholder="最小值" clearable | ||
| 30 | + @keyup.enter.native="handleQuery"/> | ||
| 31 | + </el-form-item> | ||
| 32 | + </el-col> | ||
| 33 | + <el-col | ||
| 34 | + :span="1" | ||
| 35 | + > | ||
| 36 | + - | ||
| 37 | + </el-col> | ||
| 38 | + <el-col | ||
| 39 | + :span="6" | ||
| 40 | + style="padding-left:0" | ||
| 41 | + > | ||
| 42 | + <el-form-item prop="salesCountMax"> | ||
| 43 | + <el-input v-model="queryParams.salesCountMax" placeholder="最大值" clearable | ||
| 44 | + @keyup.enter.native="handleQuery"/> | ||
| 45 | + </el-form-item> | ||
| 46 | + </el-col> | ||
| 47 | + </el-form-item> | ||
| 48 | + | ||
| 49 | + <el-form-item label="商品价格" prop="code"> | ||
| 50 | + <el-col | ||
| 51 | + :span="6" | ||
| 52 | + style="padding-left:0" | ||
| 53 | + > | ||
| 54 | + <el-form-item prop="marketPriceMin"> | ||
| 55 | + <el-input v-model="queryParams.marketPriceMin" placeholder="最小值" clearable | ||
| 56 | + @keyup.enter.native="handleQuery"/> | ||
| 57 | + </el-form-item> | ||
| 58 | + </el-col> | ||
| 59 | + <el-col | ||
| 60 | + :span="1" | ||
| 61 | + > | ||
| 62 | + - | ||
| 63 | + </el-col> | ||
| 64 | + <el-col | ||
| 65 | + :span="6" | ||
| 66 | + style="padding-left:0" | ||
| 67 | + > | ||
| 68 | + <el-form-item prop="marketPriceMax"> | ||
| 69 | + <el-input v-model="queryParams.marketPriceMax" placeholder="最大值" clearable | ||
| 70 | + @keyup.enter.native="handleQuery"/> | ||
| 71 | + </el-form-item> | ||
| 72 | + </el-col> | ||
| 73 | + </el-form-item> | ||
| 74 | + | ||
| 28 | <el-form-item> | 75 | <el-form-item> |
| 29 | <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> | 76 | <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> |
| 30 | <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> | 77 | <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> |
| @@ -35,77 +82,211 @@ | @@ -35,77 +82,211 @@ | ||
| 35 | <el-row :gutter="10" class="mb8"> | 82 | <el-row :gutter="10" class="mb8"> |
| 36 | <el-col :span="1.5"> | 83 | <el-col :span="1.5"> |
| 37 | <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" | 84 | <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" |
| 38 | - v-hasPermi="['product:spu:create']">新增</el-button> | 85 | + v-hasPermi="['product:spu:create']">新增 |
| 86 | + </el-button> | ||
| 39 | </el-col> | 87 | </el-col> |
| 40 | - <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" /> | 88 | + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"/> |
| 41 | </el-row> | 89 | </el-row> |
| 42 | 90 | ||
| 43 | - <!-- 列表 --> | ||
| 44 | - <el-table v-loading="loading" :data="list"> | ||
| 45 | - <!-- | ||
| 46 | - TODO @Luowenfeng:参考界面; | ||
| 47 | - https://v5.niuteam.cn/shop/goods/lists.html | ||
| 48 | - 1. 字段:商品信息、价格、库存、销量、排序、创建时间、状态、操作; | ||
| 49 | - 2. tab 分成全部、销售中、仓库中、预警中 | ||
| 50 | - --> | ||
| 51 | - <el-table-column label="商品信息" align="center" width="260"> | 91 | + <el-tabs v-model="activeTabs" type="card" @tab-click="handleClick"> |
| 92 | + <!-- 全部 --> | ||
| 93 | + <el-tab-pane label="全部" name="all"> | ||
| 94 | + <!-- 列表 --> | ||
| 95 | + <el-table v-loading="loading" :data="list"> | ||
| 96 | + <el-table-column label="商品信息" align="center" width="260"> | ||
| 97 | + <template slot-scope="scope"> | ||
| 98 | + <div class="product-info"> | ||
| 99 | + <img | ||
| 100 | + v-if="scope.row.picUrls" | ||
| 101 | + :src="scope.row.picUrls[0]" | ||
| 102 | + alt="分类图片" | ||
| 103 | + class="img-height" | ||
| 104 | + /> | ||
| 105 | + <div class="message">{{ scope.row.name }}</div> | ||
| 106 | + </div> | ||
| 107 | + </template> | ||
| 108 | + </el-table-column> | ||
| 109 | + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> | ||
| 110 | + <el-table-column label="库存" align="center" prop="totalStock"/> | ||
| 111 | + <el-table-column label="销量" align="center" prop="salesCount"/> | ||
| 112 | + <el-table-column label="排序" align="center" prop="sort"/> | ||
| 113 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 114 | + <template slot-scope="scope"> | ||
| 115 | + <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 116 | + </template> | ||
| 117 | + </el-table-column> | ||
| 118 | + <el-table-column label="状态" align="center" prop="status"> | ||
| 119 | + <template slot-scope="scope"> | ||
| 120 | + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> | ||
| 121 | + </template> | ||
| 122 | + </el-table-column> | ||
| 123 | + | ||
| 124 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 125 | + <template slot-scope="scope"> | ||
| 126 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | ||
| 127 | + v-hasPermi="['product:spu:update']">修改 | ||
| 128 | + </el-button> | ||
| 129 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | ||
| 130 | + v-hasPermi="['product:spu:delete']">删除 | ||
| 131 | + </el-button> | ||
| 132 | + </template> | ||
| 133 | + </el-table-column> | ||
| 134 | + </el-table> | ||
| 135 | + </el-tab-pane> | ||
| 136 | + | ||
| 137 | + <!-- 销售中 --> | ||
| 138 | + <el-tab-pane label="销售中" name="on"> | ||
| 139 | + <!-- 列表 --> | ||
| 140 | + <el-table v-loading="loading" :data="list"> | ||
| 141 | + <el-table-column label="商品信息" align="center" width="260"> | ||
| 142 | + <template slot-scope="scope"> | ||
| 143 | + <div class="product-info"> | ||
| 144 | + <img | ||
| 145 | + v-if="scope.row.picUrls" | ||
| 146 | + :src="scope.row.picUrls[0]" | ||
| 147 | + alt="分类图片" | ||
| 148 | + class="img-height" | ||
| 149 | + /> | ||
| 150 | + <div class="message">{{ scope.row.name }}</div> | ||
| 151 | + </div> | ||
| 152 | + </template> | ||
| 153 | + </el-table-column> | ||
| 154 | + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> | ||
| 155 | + <el-table-column label="库存" align="center" prop="totalStock"/> | ||
| 156 | + <el-table-column label="销量" align="center" prop="salesCount"/> | ||
| 157 | + <el-table-column label="排序" align="center" prop="sort"/> | ||
| 158 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 159 | + <template slot-scope="scope"> | ||
| 160 | + <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 161 | + </template> | ||
| 162 | + </el-table-column> | ||
| 163 | + <el-table-column label="状态" align="center" prop="status"> | ||
| 164 | + <template slot-scope="scope"> | ||
| 165 | + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> | ||
| 166 | + </template> | ||
| 167 | + </el-table-column> | ||
| 168 | + | ||
| 169 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 170 | + <template slot-scope="scope"> | ||
| 171 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | ||
| 172 | + v-hasPermi="['product:spu:update']">修改 | ||
| 173 | + </el-button> | ||
| 174 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | ||
| 175 | + v-hasPermi="['product:spu:delete']">删除 | ||
| 176 | + </el-button> | ||
| 177 | + </template> | ||
| 178 | + </el-table-column> | ||
| 179 | + </el-table> | ||
| 180 | + </el-tab-pane> | ||
| 52 | 181 | ||
| 53 | - <template slot-scope="scope" > | ||
| 54 | - <div class="product-info"> | ||
| 55 | - <img | ||
| 56 | - v-if="scope.row.picUrls" | ||
| 57 | - :src="scope.row.picUrls[0]" | ||
| 58 | - alt="分类图片" | ||
| 59 | - class="img-height" | ||
| 60 | - /> | ||
| 61 | - <div class="message">{{scope.row.name}}</div> | ||
| 62 | - </div> | ||
| 63 | - </template> | ||
| 64 | - </el-table-column> | ||
| 65 | - <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> | ||
| 66 | - <el-table-column label="库存" align="center" prop="totalStock" /> | ||
| 67 | - <el-table-column label="销量" align="center" prop="salesCount" /> | ||
| 68 | - <el-table-column label="排序" align="center" prop="sort" /> | ||
| 69 | - <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 70 | - <template slot-scope="scope"> | ||
| 71 | - <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 72 | - </template> | ||
| 73 | - </el-table-column> | ||
| 74 | - <el-table-column label="状态" align="center" prop="status"> | ||
| 75 | - <template slot-scope="scope"> | ||
| 76 | - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> | ||
| 77 | - </template> | ||
| 78 | - </el-table-column> | 182 | + <!-- 仓库中 --> |
| 183 | + <el-tab-pane label="仓库中" name="off"> | ||
| 184 | + <!-- 列表 --> | ||
| 185 | + <el-table v-loading="loading" :data="list"> | ||
| 186 | + <el-table-column label="商品信息" align="center" width="260"> | ||
| 187 | + <template slot-scope="scope"> | ||
| 188 | + <div class="product-info"> | ||
| 189 | + <img | ||
| 190 | + v-if="scope.row.picUrls" | ||
| 191 | + :src="scope.row.picUrls[0]" | ||
| 192 | + alt="分类图片" | ||
| 193 | + class="img-height" | ||
| 194 | + /> | ||
| 195 | + <div class="message">{{ scope.row.name }}</div> | ||
| 196 | + </div> | ||
| 197 | + </template> | ||
| 198 | + </el-table-column> | ||
| 199 | + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> | ||
| 200 | + <el-table-column label="库存" align="center" prop="totalStock"/> | ||
| 201 | + <el-table-column label="销量" align="center" prop="salesCount"/> | ||
| 202 | + <el-table-column label="排序" align="center" prop="sort"/> | ||
| 203 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 204 | + <template slot-scope="scope"> | ||
| 205 | + <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 206 | + </template> | ||
| 207 | + </el-table-column> | ||
| 208 | + <el-table-column label="状态" align="center" prop="status"> | ||
| 209 | + <template slot-scope="scope"> | ||
| 210 | + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> | ||
| 211 | + </template> | ||
| 212 | + </el-table-column> | ||
| 79 | 213 | ||
| 80 | - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 81 | - <template slot-scope="scope"> | ||
| 82 | - <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | ||
| 83 | - v-hasPermi="['product:spu:update']">修改</el-button> | ||
| 84 | - <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | ||
| 85 | - v-hasPermi="['product:spu:delete']">删除</el-button> | ||
| 86 | - </template> | ||
| 87 | - </el-table-column> | ||
| 88 | - </el-table> | 214 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| 215 | + <template slot-scope="scope"> | ||
| 216 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | ||
| 217 | + v-hasPermi="['product:spu:update']">修改 | ||
| 218 | + </el-button> | ||
| 219 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | ||
| 220 | + v-hasPermi="['product:spu:delete']">删除 | ||
| 221 | + </el-button> | ||
| 222 | + </template> | ||
| 223 | + </el-table-column> | ||
| 224 | + </el-table> | ||
| 225 | + </el-tab-pane> | ||
| 226 | + | ||
| 227 | + <!-- 预警中 --> | ||
| 228 | + <el-tab-pane label="预警中" name="remind"> | ||
| 229 | + <!-- 列表 --> | ||
| 230 | + <el-table v-loading="loading" :data="list"> | ||
| 231 | + <el-table-column label="商品信息" align="center" width="260"> | ||
| 232 | + <template slot-scope="scope"> | ||
| 233 | + <div class="product-info"> | ||
| 234 | + <img | ||
| 235 | + v-if="scope.row.picUrls" | ||
| 236 | + :src="scope.row.picUrls[0]" | ||
| 237 | + alt="分类图片" | ||
| 238 | + class="img-height" | ||
| 239 | + /> | ||
| 240 | + <div class="message">{{ scope.row.name }}</div> | ||
| 241 | + </div> | ||
| 242 | + </template> | ||
| 243 | + </el-table-column> | ||
| 244 | + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> | ||
| 245 | + <el-table-column label="库存" align="center" prop="totalStock"/> | ||
| 246 | + <el-table-column label="销量" align="center" prop="salesCount"/> | ||
| 247 | + <el-table-column label="排序" align="center" prop="sort"/> | ||
| 248 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 249 | + <template slot-scope="scope"> | ||
| 250 | + <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 251 | + </template> | ||
| 252 | + </el-table-column> | ||
| 253 | + <el-table-column label="状态" align="center" prop="status"> | ||
| 254 | + <template slot-scope="scope"> | ||
| 255 | + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> | ||
| 256 | + </template> | ||
| 257 | + </el-table-column> | ||
| 258 | + | ||
| 259 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 260 | + <template slot-scope="scope"> | ||
| 261 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | ||
| 262 | + v-hasPermi="['product:spu:update']">修改 | ||
| 263 | + </el-button> | ||
| 264 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | ||
| 265 | + v-hasPermi="['product:spu:delete']">删除 | ||
| 266 | + </el-button> | ||
| 267 | + </template> | ||
| 268 | + </el-table-column> | ||
| 269 | + </el-table> | ||
| 270 | + </el-tab-pane> | ||
| 271 | + </el-tabs> | ||
| 89 | <!-- 分页组件 --> | 272 | <!-- 分页组件 --> |
| 90 | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | 273 | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" |
| 91 | @pagination="getList"/> | 274 | @pagination="getList"/> |
| 92 | 275 | ||
| 93 | - <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body destroy-on-close :close-on-click-modal="false" > | ||
| 94 | - <save @closeDialog="closeDialog" :obj="dialogObj" v-if="open" /> | 276 | + <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body destroy-on-close |
| 277 | + :close-on-click-modal="false"> | ||
| 278 | + <save @closeDialog="closeDialog" :obj="dialogObj" v-if="open"/> | ||
| 95 | </el-dialog> | 279 | </el-dialog> |
| 96 | </div> | 280 | </div> |
| 97 | </template> | 281 | </template> |
| 98 | 282 | ||
| 99 | <script> | 283 | <script> |
| 100 | -import { | ||
| 101 | - deleteSpu, | ||
| 102 | - getSpuPage, | ||
| 103 | -} from "@/api/mall/product/spu"; | 284 | +import {deleteSpu, getSpuPage,} from "@/api/mall/product/spu"; |
| 104 | import {getProductCategoryList} from "@/api/mall/product/category"; | 285 | import {getProductCategoryList} from "@/api/mall/product/category"; |
| 105 | import {getBrandList} from "@/api/mall/product/brand"; | 286 | import {getBrandList} from "@/api/mall/product/brand"; |
| 106 | import Editor from "@/components/Editor"; | 287 | import Editor from "@/components/Editor"; |
| 107 | import ImageUpload from "@/components/ImageUpload"; | 288 | import ImageUpload from "@/components/ImageUpload"; |
| 108 | -import save from "./save"; | 289 | +import save from "./save"; |
| 109 | 290 | ||
| 110 | // 1. TODO @Luowenfeng:商品的添加、修改,走一个单独的页面,不走弹窗;https://v5.niuteam.cn/shop/goods/addgoods.html | 291 | // 1. TODO @Luowenfeng:商品的添加、修改,走一个单独的页面,不走弹窗;https://v5.niuteam.cn/shop/goods/addgoods.html |
| 111 | // 2. TODO | 292 | // 2. TODO |
| @@ -119,6 +300,7 @@ export default { | @@ -119,6 +300,7 @@ export default { | ||
| 119 | }, | 300 | }, |
| 120 | data() { | 301 | data() { |
| 121 | return { | 302 | return { |
| 303 | + activeTabs: "all", | ||
| 122 | propName: { | 304 | propName: { |
| 123 | checkStrictly: true, | 305 | checkStrictly: true, |
| 124 | label: "name", | 306 | label: "name", |
| @@ -141,7 +323,7 @@ export default { | @@ -141,7 +323,7 @@ export default { | ||
| 141 | // 是否显示弹出层 | 323 | // 是否显示弹出层 |
| 142 | open: false, | 324 | open: false, |
| 143 | // 弹出层参数 | 325 | // 弹出层参数 |
| 144 | - dialogObj:{}, | 326 | + dialogObj: {}, |
| 145 | dateRangeCreateTime: [], | 327 | dateRangeCreateTime: [], |
| 146 | // 查询参数 | 328 | // 查询参数 |
| 147 | queryParams: { | 329 | queryParams: { |
| @@ -153,6 +335,11 @@ export default { | @@ -153,6 +335,11 @@ export default { | ||
| 153 | categoryId: null, | 335 | categoryId: null, |
| 154 | brandId: null, | 336 | brandId: null, |
| 155 | status: null, | 337 | status: null, |
| 338 | + salesCountMin: null, | ||
| 339 | + salesCountMax: null, | ||
| 340 | + marketPriceMin: null, | ||
| 341 | + marketPriceMax: null, | ||
| 342 | + tabStatus: null, | ||
| 156 | }, | 343 | }, |
| 157 | tagIndex: 0, | 344 | tagIndex: 0, |
| 158 | }; | 345 | }; |
| @@ -181,13 +368,15 @@ export default { | @@ -181,13 +368,15 @@ export default { | ||
| 181 | getList() { | 368 | getList() { |
| 182 | this.loading = true; | 369 | this.loading = true; |
| 183 | // 处理查询参数 | 370 | // 处理查询参数 |
| 184 | - let params = { ...this.queryParams }; | ||
| 185 | - params.categoryId = this.queryParams.categoryIds[ this.queryParams.categoryIds.length - 1]; | 371 | + let params = {...this.queryParams}; |
| 372 | + params.marketPriceMin = this.queryParams.marketPriceMin === null ? null : params.marketPriceMin * 100; | ||
| 373 | + params.marketPriceMax = this.queryParams.marketPriceMax === null ? null : params.marketPriceMax * 100; | ||
| 374 | + params.categoryId = this.queryParams.categoryIds[this.queryParams.categoryIds.length - 1]; | ||
| 186 | this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime"); | 375 | this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime"); |
| 187 | // 执行查询 | 376 | // 执行查询 |
| 188 | getSpuPage(params).then((response) => { | 377 | getSpuPage(params).then((response) => { |
| 189 | response.data.list.forEach(element => { | 378 | response.data.list.forEach(element => { |
| 190 | - element.price = this.divide(element.minPrice, 100)+"~"+this.divide(element.maxPrice, 100) | 379 | + element.price = this.divide(element.minPrice, 100) + "~" + this.divide(element.maxPrice, 100) |
| 191 | }); | 380 | }); |
| 192 | this.list = response.data.list; | 381 | this.list = response.data.list; |
| 193 | this.total = response.data.total; | 382 | this.total = response.data.total; |
| @@ -209,15 +398,14 @@ export default { | @@ -209,15 +398,14 @@ export default { | ||
| 209 | resetQuery() { | 398 | resetQuery() { |
| 210 | this.dateRangeCreateTime = []; | 399 | this.dateRangeCreateTime = []; |
| 211 | this.$refs.category.$refs.panel.checkedValue = [];//也可以是指定的值,默认返回值是数组,也可以返回单个值 | 400 | this.$refs.category.$refs.panel.checkedValue = [];//也可以是指定的值,默认返回值是数组,也可以返回单个值 |
| 212 | - this.$refs.category.$refs.panel.activePath = []; | ||
| 213 | - this.$refs.category.$refs.panel.syncActivePath(); | ||
| 214 | - this.queryParams.categoryIds = []; | 401 | + this.$refs.category.$refs.panel.activePath = []; |
| 402 | + this.$refs.category.$refs.panel.syncActivePath(); | ||
| 215 | this.resetForm("queryForm"); | 403 | this.resetForm("queryForm"); |
| 216 | this.handleQuery(); | 404 | this.handleQuery(); |
| 217 | }, | 405 | }, |
| 218 | /** 新增按钮操作 */ | 406 | /** 新增按钮操作 */ |
| 219 | handleAdd() { | 407 | handleAdd() { |
| 220 | - this.dialogObj={}; | 408 | + this.dialogObj = {}; |
| 221 | this.open = true; | 409 | this.open = true; |
| 222 | this.title = "添加商品spu"; | 410 | this.title = "添加商品spu"; |
| 223 | }, | 411 | }, |
| @@ -227,8 +415,8 @@ export default { | @@ -227,8 +415,8 @@ export default { | ||
| 227 | this.open = true; | 415 | this.open = true; |
| 228 | this.title = "修改商品spu"; | 416 | this.title = "修改商品spu"; |
| 229 | }, | 417 | }, |
| 230 | - closeDialog(){ | ||
| 231 | - this.dialogObj={}; | 418 | + closeDialog() { |
| 419 | + this.dialogObj = {}; | ||
| 232 | this.open = false; | 420 | this.open = false; |
| 233 | this.getList() | 421 | this.getList() |
| 234 | }, | 422 | }, |
| @@ -244,10 +432,26 @@ export default { | @@ -244,10 +432,26 @@ export default { | ||
| 244 | this.getList(); | 432 | this.getList(); |
| 245 | this.$modal.msgSuccess("删除成功"); | 433 | this.$modal.msgSuccess("删除成功"); |
| 246 | }) | 434 | }) |
| 247 | - .catch(() => {}); | 435 | + .catch(() => { |
| 436 | + }); | ||
| 248 | }, | 437 | }, |
| 249 | - unitConversion(row, column, cellValue){ | 438 | + unitConversion(row, column, cellValue) { |
| 250 | return this.divide(cellValue, 100); | 439 | return this.divide(cellValue, 100); |
| 440 | + }, | ||
| 441 | + // 选中tab | ||
| 442 | + handleClick(val) { | ||
| 443 | + if (val.name === "all") { | ||
| 444 | + this.queryParams.tabStatus = null; | ||
| 445 | + } else if (val.name === "on") { | ||
| 446 | + this.queryParams.tabStatus = 0; | ||
| 447 | + } else if (val.name === "off") { | ||
| 448 | + this.queryParams.tabStatus = 1; | ||
| 449 | + } else if (val.name === "remind") { | ||
| 450 | + this.queryParams.tabStatus = 2; | ||
| 451 | + } else { | ||
| 452 | + this.queryParams.tabStatus = null; | ||
| 453 | + } | ||
| 454 | + this.getList(); | ||
| 251 | } | 455 | } |
| 252 | }, | 456 | }, |
| 253 | }; | 457 | }; |
| @@ -272,13 +476,15 @@ export default { | @@ -272,13 +476,15 @@ export default { | ||
| 272 | vertical-align: bottom; | 476 | vertical-align: bottom; |
| 273 | } | 477 | } |
| 274 | 478 | ||
| 275 | - .product-info{ | 479 | + .product-info { |
| 276 | display: flex; | 480 | display: flex; |
| 481 | + | ||
| 277 | .img-height { | 482 | .img-height { |
| 278 | height: 50px; | 483 | height: 50px; |
| 279 | width: 50px; | 484 | width: 50px; |
| 280 | } | 485 | } |
| 281 | - .message{ | 486 | + |
| 487 | + .message { | ||
| 282 | margin-left: 10px; | 488 | margin-left: 10px; |
| 283 | text-overflow: ellipsis; | 489 | text-overflow: ellipsis; |
| 284 | display: -webkit-box; | 490 | display: -webkit-box; |
yudao-ui-admin/src/views/mall/product/spu/save.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="container"> | 2 | <div class="container"> |
| 3 | - <el-tabs v-model="activeName" class="tabs" > | 3 | + <el-tabs v-model="activeName" class="tabs"> |
| 4 | <!-- 基础设置 --> | 4 | <!-- 基础设置 --> |
| 5 | <el-tab-pane label="基础设置" name="base"> | 5 | <el-tab-pane label="基础设置" name="base"> |
| 6 | <el-form ref="base" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%"> | 6 | <el-form ref="base" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%"> |
| @@ -11,20 +11,20 @@ | @@ -11,20 +11,20 @@ | ||
| 11 | <el-input type="textarea" v-model="baseForm.sellPoint" placeholder="请输入商品卖点"/> | 11 | <el-input type="textarea" v-model="baseForm.sellPoint" placeholder="请输入商品卖点"/> |
| 12 | </el-form-item> | 12 | </el-form-item> |
| 13 | <el-form-item label="商品主图" prop="picUrls"> | 13 | <el-form-item label="商品主图" prop="picUrls"> |
| 14 | - <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10" class="mall-image" /> | 14 | + <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10" class="mall-image"/> |
| 15 | </el-form-item> | 15 | </el-form-item> |
| 16 | <el-form-item label="商品视频" prop="videoUrl"> | 16 | <el-form-item label="商品视频" prop="videoUrl"> |
| 17 | - <VideoUpload v-model="baseForm.videoUrl" :value="baseForm.videoUrl" /> | 17 | + <VideoUpload v-model="baseForm.videoUrl" :value="baseForm.videoUrl"/> |
| 18 | </el-form-item> | 18 | </el-form-item> |
| 19 | 19 | ||
| 20 | <el-form-item label="商品品牌" prop="brandId"> | 20 | <el-form-item label="商品品牌" prop="brandId"> |
| 21 | <el-select v-model="baseForm.brandId" placeholder="请选择商品品牌"> | 21 | <el-select v-model="baseForm.brandId" placeholder="请选择商品品牌"> |
| 22 | - <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id" /> | 22 | + <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"/> |
| 23 | </el-select> | 23 | </el-select> |
| 24 | </el-form-item> | 24 | </el-form-item> |
| 25 | <el-form-item label="商品分类" prop="categoryIds"> | 25 | <el-form-item label="商品分类" prop="categoryIds"> |
| 26 | <el-cascader v-model="baseForm.categoryIds" placeholder="商品分类" style="width: 100%" | 26 | <el-cascader v-model="baseForm.categoryIds" placeholder="商品分类" style="width: 100%" |
| 27 | - :options="categoryList" :props="propName" clearable /> | 27 | + :options="categoryList" :props="propName" clearable/> |
| 28 | </el-form-item> | 28 | </el-form-item> |
| 29 | <el-form-item label="是否上架" prop="status"> | 29 | <el-form-item label="是否上架" prop="status"> |
| 30 | <el-radio-group v-model="baseForm.status"> | 30 | <el-radio-group v-model="baseForm.status"> |
| @@ -46,11 +46,11 @@ | @@ -46,11 +46,11 @@ | ||
| 46 | <div v-show="ratesForm.spec === 2"> | 46 | <div v-show="ratesForm.spec === 2"> |
| 47 | <div v-for="(specs, index) in dynamicSpec" :key="index" class="dynamic-spec"> | 47 | <div v-for="(specs, index) in dynamicSpec" :key="index" class="dynamic-spec"> |
| 48 | <!-- 删除按钮 --> | 48 | <!-- 删除按钮 --> |
| 49 | - <el-button type="danger" icon="el-icon-delete" circle class="spec-delete" @click="removeSpec(index)" /> | 49 | + <el-button type="danger" icon="el-icon-delete" circle class="spec-delete" @click="removeSpec(index)"/> |
| 50 | <div class="spec-header"> | 50 | <div class="spec-header"> |
| 51 | 规格项: | 51 | 规格项: |
| 52 | <el-select v-model="specs.specId" filterable placeholder="请选择" @change="changeSpec"> | 52 | <el-select v-model="specs.specId" filterable placeholder="请选择" @change="changeSpec"> |
| 53 | - <el-option v-for="item in propertyPageList" :key="item.id" :label="item.name" :value="item.id" /> | 53 | + <el-option v-for="item in propertyPageList" :key="item.id" :label="item.name" :value="item.id"/> |
| 54 | </el-select> | 54 | </el-select> |
| 55 | </div> | 55 | </div> |
| 56 | <div class="spec-values"> | 56 | <div class="spec-values"> |
| @@ -59,7 +59,8 @@ | @@ -59,7 +59,8 @@ | ||
| 59 | </template> | 59 | </template> |
| 60 | </div> | 60 | </div> |
| 61 | </div> | 61 | </div> |
| 62 | - <el-button type="primary" @click="dynamicSpec.push({specValue: []}); ratesForm.rates = []">添加规格项目</el-button> | 62 | + <el-button type="primary" @click="dynamicSpec.push({specValue: []}); ratesForm.rates = []">添加规格项目 |
| 63 | + </el-button> | ||
| 63 | </div> | 64 | </div> |
| 64 | 65 | ||
| 65 | <!-- 规格明细 --> | 66 | <!-- 规格明细 --> |
| @@ -69,53 +70,59 @@ | @@ -69,53 +70,59 @@ | ||
| 69 | <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)" | 70 | <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)" |
| 70 | :label="item.specName"> | 71 | :label="item.specName"> |
| 71 | <template slot-scope="scope"> | 72 | <template slot-scope="scope"> |
| 72 | - <el-input v-if="scope.row.spec" v-model="scope.row.spec[index]" disabled /> | 73 | + <el-input v-if="scope.row.spec" v-model="scope.row.spec[index]" disabled/> |
| 73 | </template> | 74 | </template> |
| 74 | </el-table-column> | 75 | </el-table-column> |
| 75 | </template> | 76 | </template> |
| 76 | <el-table-column label="规格图片" width="120px" :render-header="addRedStar" key="90"> | 77 | <el-table-column label="规格图片" width="120px" :render-header="addRedStar" key="90"> |
| 77 | <template slot-scope="scope"> | 78 | <template slot-scope="scope"> |
| 78 | - <ImageUpload v-model="scope.row.picUrl" :limit="1" :isShowTip="false" | 79 | + <ImageUpload v-model="scope.row.picUrl" :limit="1" :isShowTip="false" |
| 79 | style="width: 100px; height: 50px"/> | 80 | style="width: 100px; height: 50px"/> |
| 80 | </template> | 81 | </template> |
| 81 | </el-table-column> | 82 | </el-table-column> |
| 82 | <template v-if="this.activeSwitch"> | 83 | <template v-if="this.activeSwitch"> |
| 83 | - <el-table-column label="sku名称" :render-header="addRedStar" key="91"> | 84 | + <el-table-column label="sku名称" :render-header="addRedStar" key="91"> |
| 84 | <template slot-scope="scope"> | 85 | <template slot-scope="scope"> |
| 85 | - <el-form-item :prop="'rates.'+ scope.$index + '.name'" :rules="[{required: true, trigger: 'change'}]"> | ||
| 86 | - <el-input v-model="scope.row.name" /> | 86 | + <el-form-item :prop="'rates.'+ scope.$index + '.name'" |
| 87 | + :rules="[{required: true, trigger: 'change'}]"> | ||
| 88 | + <el-input v-model="scope.row.name"/> | ||
| 87 | </el-form-item> | 89 | </el-form-item> |
| 88 | </template> | 90 | </template> |
| 89 | </el-table-column> | 91 | </el-table-column> |
| 90 | </template> | 92 | </template> |
| 91 | <el-table-column label="市场价(元)" :render-header="addRedStar" key="92"> | 93 | <el-table-column label="市场价(元)" :render-header="addRedStar" key="92"> |
| 92 | <template slot-scope="scope"> | 94 | <template slot-scope="scope"> |
| 93 | - <el-form-item :prop="'rates.'+ scope.$index + '.marketPrice'" :rules="[{required: true, trigger: 'change'}]"> | 95 | + <el-form-item :prop="'rates.'+ scope.$index + '.marketPrice'" |
| 96 | + :rules="[{required: true, trigger: 'change'}]"> | ||
| 94 | <el-input v-model="scope.row.marketPrice" | 97 | <el-input v-model="scope.row.marketPrice" |
| 95 | - oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"/> | 98 | + oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"/> |
| 96 | </el-form-item> | 99 | </el-form-item> |
| 97 | </template> | 100 | </template> |
| 98 | </el-table-column> | 101 | </el-table-column> |
| 99 | <el-table-column label="销售价(元)" :render-header="addRedStar" key="93"> | 102 | <el-table-column label="销售价(元)" :render-header="addRedStar" key="93"> |
| 100 | <template slot-scope="scope"> | 103 | <template slot-scope="scope"> |
| 101 | - <el-form-item :prop="'rates.'+ scope.$index + '.price'" :rules="[{required: true, trigger: 'change'}]"> | ||
| 102 | - <el-input v-model="scope.row.price" oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"></el-input> | 104 | + <el-form-item :prop="'rates.'+ scope.$index + '.price'" |
| 105 | + :rules="[{required: true, trigger: 'change'}]"> | ||
| 106 | + <el-input v-model="scope.row.price" | ||
| 107 | + oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"></el-input> | ||
| 103 | </el-form-item> | 108 | </el-form-item> |
| 104 | </template> | 109 | </template> |
| 105 | </el-table-column> | 110 | </el-table-column> |
| 106 | <el-table-column label="成本价" :render-header="addRedStar" key="94"> | 111 | <el-table-column label="成本价" :render-header="addRedStar" key="94"> |
| 107 | <template slot-scope="scope"> | 112 | <template slot-scope="scope"> |
| 108 | - <el-form-item :prop="'rates.'+ scope.$index + '.costPrice'" :rules="[{required: true, trigger: 'change'}]"> | ||
| 109 | - <el-input | ||
| 110 | - v-model="scope.row.costPrice" | ||
| 111 | - oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''" | ||
| 112 | - ></el-input> | 113 | + <el-form-item :prop="'rates.'+ scope.$index + '.costPrice'" |
| 114 | + :rules="[{required: true, trigger: 'change'}]"> | ||
| 115 | + <el-input | ||
| 116 | + v-model="scope.row.costPrice" | ||
| 117 | + oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''" | ||
| 118 | + ></el-input> | ||
| 113 | </el-form-item> | 119 | </el-form-item> |
| 114 | </template> | 120 | </template> |
| 115 | </el-table-column> | 121 | </el-table-column> |
| 116 | <el-table-column label="库存" :render-header="addRedStar" key="95"> | 122 | <el-table-column label="库存" :render-header="addRedStar" key="95"> |
| 117 | <template slot-scope="scope"> | 123 | <template slot-scope="scope"> |
| 118 | - <el-form-item :prop="'rates.'+ scope.$index + '.stock'" :rules="[{required: true, trigger: 'change'}]"> | 124 | + <el-form-item :prop="'rates.'+ scope.$index + '.stock'" |
| 125 | + :rules="[{required: true, trigger: 'change'}]"> | ||
| 119 | <el-input v-model="scope.row.stock" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"></el-input> | 126 | <el-input v-model="scope.row.stock" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"></el-input> |
| 120 | </el-form-item> | 127 | </el-form-item> |
| 121 | </template> | 128 | </template> |
| @@ -127,12 +134,12 @@ | @@ -127,12 +134,12 @@ | ||
| 127 | </el-table-column> | 134 | </el-table-column> |
| 128 | <el-table-column label="体积" key="97"> | 135 | <el-table-column label="体积" key="97"> |
| 129 | <template slot-scope="scope"> | 136 | <template slot-scope="scope"> |
| 130 | - <el-input v-model="scope.row.volume" ></el-input> | 137 | + <el-input v-model="scope.row.volume"></el-input> |
| 131 | </template> | 138 | </template> |
| 132 | </el-table-column> | 139 | </el-table-column> |
| 133 | <el-table-column label="重量" key="98"> | 140 | <el-table-column label="重量" key="98"> |
| 134 | <template slot-scope="scope"> | 141 | <template slot-scope="scope"> |
| 135 | - <el-input v-model="scope.row.weight" ></el-input> | 142 | + <el-input v-model="scope.row.weight"></el-input> |
| 136 | </template> | 143 | </template> |
| 137 | </el-table-column> | 144 | </el-table-column> |
| 138 | <el-table-column label="条码" key="99"> | 145 | <el-table-column label="条码" key="99"> |
| @@ -140,29 +147,34 @@ | @@ -140,29 +147,34 @@ | ||
| 140 | <el-input v-model="scope.row.barCode"></el-input> | 147 | <el-input v-model="scope.row.barCode"></el-input> |
| 141 | </template> | 148 | </template> |
| 142 | </el-table-column> | 149 | </el-table-column> |
| 143 | - <template v-if="this.activeSwitch"> | 150 | + <template v-if="this.activeSwitch"> |
| 144 | <el-table-column fixed="right" label="操作" width="50" key="100"> | 151 | <el-table-column fixed="right" label="操作" width="50" key="100"> |
| 145 | <template slot-scope="scope"> | 152 | <template slot-scope="scope"> |
| 146 | - <el-button @click="scope.row.status = 1" type="text" size="small" v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用</el-button> | ||
| 147 | - <el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status == 1">启用</el-button> | 153 | + <el-button @click="scope.row.status = 1" type="text" size="small" |
| 154 | + v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用 | ||
| 155 | + </el-button> | ||
| 156 | + <el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status == 1"> | ||
| 157 | + 启用 | ||
| 158 | + </el-button> | ||
| 148 | </template> | 159 | </template> |
| 149 | </el-table-column> | 160 | </el-table-column> |
| 150 | </template> | 161 | </template> |
| 151 | </el-table> | 162 | </el-table> |
| 152 | </el-form-item> | 163 | </el-form-item> |
| 153 | - <el-form-item label="虚拟销量" prop="virtualSalesCount" > | ||
| 154 | - <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/> | 164 | + <el-form-item label="虚拟销量" prop="virtualSalesCount"> |
| 165 | + <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" | ||
| 166 | + oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/> | ||
| 155 | </el-form-item> | 167 | </el-form-item> |
| 156 | </el-form> | 168 | </el-form> |
| 157 | </el-tab-pane> | 169 | </el-tab-pane> |
| 158 | 170 | ||
| 159 | <!-- 商品详情 --> | 171 | <!-- 商品详情 --> |
| 160 | <el-tab-pane label="商品详情" name="third"> | 172 | <el-tab-pane label="商品详情" name="third"> |
| 161 | - <el-form ref="third" :model="baseForm" :rules="rules"> | ||
| 162 | - <el-form-item prop="description"> | ||
| 163 | - <editor v-model="baseForm.description" :min-height="380"/> | ||
| 164 | - </el-form-item> | ||
| 165 | - </el-form> | 173 | + <el-form ref="third" :model="baseForm" :rules="rules"> |
| 174 | + <el-form-item prop="description"> | ||
| 175 | + <editor v-model="baseForm.description" :min-height="380"/> | ||
| 176 | + </el-form-item> | ||
| 177 | + </el-form> | ||
| 166 | </el-tab-pane> | 178 | </el-tab-pane> |
| 167 | 179 | ||
| 168 | <!-- 销售设置 --> | 180 | <!-- 销售设置 --> |
| @@ -171,8 +183,8 @@ | @@ -171,8 +183,8 @@ | ||
| 171 | <el-form-item label="排序字段"> | 183 | <el-form-item label="排序字段"> |
| 172 | <el-input v-model="baseForm.sort" placeholder="请输入排序字段" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/> | 184 | <el-input v-model="baseForm.sort" placeholder="请输入排序字段" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/> |
| 173 | </el-form-item> | 185 | </el-form-item> |
| 174 | - <el-form-item label="是否展示库存" prop="showStock"> | ||
| 175 | - <el-radio-group v-model="baseForm.showStock"> | 186 | + <el-form-item label="是否展示库存" prop="showStock"> |
| 187 | + <el-radio-group v-model="baseForm.showStock"> | ||
| 176 | <el-radio :label="true">是</el-radio> | 188 | <el-radio :label="true">是</el-radio> |
| 177 | <el-radio :label="false">否</el-radio> | 189 | <el-radio :label="false">否</el-radio> |
| 178 | </el-radio-group> | 190 | </el-radio-group> |
| @@ -193,7 +205,7 @@ | @@ -193,7 +205,7 @@ | ||
| 193 | 205 | ||
| 194 | import {getBrandList} from "@/api/mall/product/brand"; | 206 | import {getBrandList} from "@/api/mall/product/brand"; |
| 195 | import {getProductCategoryList} from "@/api/mall/product/category"; | 207 | import {getProductCategoryList} from "@/api/mall/product/category"; |
| 196 | -import {createSpu, updateSpu, getSpuDetail} from "@/api/mall/product/spu"; | 208 | +import {createSpu, getSpuDetail, updateSpu} from "@/api/mall/product/spu"; |
| 197 | import {getPropertyListAndValue,} from "@/api/mall/product/property"; | 209 | import {getPropertyListAndValue,} from "@/api/mall/product/property"; |
| 198 | import Editor from "@/components/Editor"; | 210 | import Editor from "@/components/Editor"; |
| 199 | import ImageUpload from "@/components/ImageUpload"; | 211 | import ImageUpload from "@/components/ImageUpload"; |
| @@ -205,7 +217,7 @@ export default { | @@ -205,7 +217,7 @@ export default { | ||
| 205 | ImageUpload, | 217 | ImageUpload, |
| 206 | VideoUpload | 218 | VideoUpload |
| 207 | }, | 219 | }, |
| 208 | - props:{ | 220 | + props: { |
| 209 | obj: Object | 221 | obj: Object |
| 210 | }, | 222 | }, |
| 211 | data() { | 223 | data() { |
| @@ -256,7 +268,7 @@ export default { | @@ -256,7 +268,7 @@ export default { | ||
| 256 | 268 | ||
| 257 | // 表单校验 | 269 | // 表单校验 |
| 258 | rules: { | 270 | rules: { |
| 259 | - name:[{required: true, message: "商品名称不能为空", trigger: "blur"},], | 271 | + name: [{required: true, message: "商品名称不能为空", trigger: "blur"},], |
| 260 | description: [{required: true, message: "描述不能为空", trigger: "blur"},], | 272 | description: [{required: true, message: "描述不能为空", trigger: "blur"},], |
| 261 | categoryIds: [{required: true, message: "分类id不能为空", trigger: "blur"},], | 273 | categoryIds: [{required: true, message: "分类id不能为空", trigger: "blur"},], |
| 262 | status: [{required: true, message: "商品状态不能为空", trigger: "blur"}], | 274 | status: [{required: true, message: "商品状态不能为空", trigger: "blur"}], |
| @@ -269,24 +281,24 @@ export default { | @@ -269,24 +281,24 @@ export default { | ||
| 269 | this.getListBrand(); | 281 | this.getListBrand(); |
| 270 | this.getListCategory(); | 282 | this.getListCategory(); |
| 271 | this.getPropertyPageList(); | 283 | this.getPropertyPageList(); |
| 272 | - if(this.obj.id != null){ | 284 | + if (this.obj.id != null) { |
| 273 | this.updateType(this.obj.id) | 285 | this.updateType(this.obj.id) |
| 274 | } | 286 | } |
| 275 | }, | 287 | }, |
| 276 | methods: { | 288 | methods: { |
| 277 | - removeSpec(index){ | ||
| 278 | - this.dynamicSpec.splice(index, 1); | ||
| 279 | - this.changeRadio() | 289 | + removeSpec(index) { |
| 290 | + this.dynamicSpec.splice(index, 1); | ||
| 291 | + this.changeRadio() | ||
| 280 | }, | 292 | }, |
| 281 | // 必选标识 | 293 | // 必选标识 |
| 282 | - addRedStar(h, { column }) { | 294 | + addRedStar(h, {column}) { |
| 283 | return [ | 295 | return [ |
| 284 | - h('span', { style: 'color: #F56C6C' }, '*'), | 296 | + h('span', {style: 'color: #F56C6C'}, '*'), |
| 285 | h('span', ' ' + column.label) | 297 | h('span', ' ' + column.label) |
| 286 | ]; | 298 | ]; |
| 287 | }, | 299 | }, |
| 288 | changeRadio() { | 300 | changeRadio() { |
| 289 | - this.activeSwitch ? this.ratesForm.spec = 2: this.ratesForm.spec = 1; | 301 | + this.activeSwitch ? this.ratesForm.spec = 2 : this.ratesForm.spec = 1; |
| 290 | this.$refs.ratesTable.doLayout(); | 302 | this.$refs.ratesTable.doLayout(); |
| 291 | if (this.ratesForm.spec == 1) { | 303 | if (this.ratesForm.spec == 1) { |
| 292 | this.ratesForm.rates = [{}] | 304 | this.ratesForm.rates = [{}] |
| @@ -334,7 +346,7 @@ export default { | @@ -334,7 +346,7 @@ export default { | ||
| 334 | this.categoryList = this.handleTree(response.data, "id", "parentId"); | 346 | this.categoryList = this.handleTree(response.data, "id", "parentId"); |
| 335 | }); | 347 | }); |
| 336 | }, | 348 | }, |
| 337 | - /** 查询品牌列表 */ | 349 | + /** 查询品牌列表 */ |
| 338 | getListBrand() { | 350 | getListBrand() { |
| 339 | // 执行查询 | 351 | // 执行查询 |
| 340 | getBrandList().then((response) => { | 352 | getBrandList().then((response) => { |
| @@ -345,30 +357,30 @@ export default { | @@ -345,30 +357,30 @@ export default { | ||
| 345 | this.$emit("closeDialog"); | 357 | this.$emit("closeDialog"); |
| 346 | }, | 358 | }, |
| 347 | submit() { | 359 | submit() { |
| 348 | - this.$refs[this.activeName].validate((valid) => { | 360 | + this.$refs[this.activeName].validate((valid) => { |
| 349 | if (!valid) { | 361 | if (!valid) { |
| 350 | return; | 362 | return; |
| 351 | } | 363 | } |
| 352 | - let rates = this.ratesForm.rates; | 364 | + let rates = this.ratesForm.rates; |
| 353 | 365 | ||
| 354 | - // 价格元转分 | ||
| 355 | - rates.forEach(r=>{ | ||
| 356 | - r.marketPrice = r.marketPrice*100; | ||
| 357 | - r.price = r.price*100; | ||
| 358 | - r.costPrice = r.costPrice*100; | ||
| 359 | - }) | ||
| 360 | - | ||
| 361 | - // 动态规格调整字段 | ||
| 362 | - if (this.activeSwitch) { | 366 | + // 价格元转分 |
| 363 | rates.forEach(r => { | 367 | rates.forEach(r => { |
| 364 | - let properties = [] | 368 | + r.marketPrice = r.marketPrice * 100; |
| 369 | + r.price = r.price * 100; | ||
| 370 | + r.costPrice = r.costPrice * 100; | ||
| 371 | + }) | ||
| 372 | + | ||
| 373 | + // 动态规格调整字段 | ||
| 374 | + if (this.activeSwitch) { | ||
| 375 | + rates.forEach(r => { | ||
| 376 | + let properties = [] | ||
| 365 | Array.of(r.spec).forEach(s => { | 377 | Array.of(r.spec).forEach(s => { |
| 366 | let obj; | 378 | let obj; |
| 367 | - if (s instanceof Array) { | ||
| 368 | - obj = s; | ||
| 369 | - }else{ | ||
| 370 | - obj = Array.of(s); | ||
| 371 | - } | 379 | + if (s instanceof Array) { |
| 380 | + obj = s; | ||
| 381 | + } else { | ||
| 382 | + obj = Array.of(s); | ||
| 383 | + } | ||
| 372 | obj.forEach((v, i) => { | 384 | obj.forEach((v, i) => { |
| 373 | let specValue = this.dynamicSpec[i].specValue.find(o => o.name == v); | 385 | let specValue = this.dynamicSpec[i].specValue.find(o => o.name == v); |
| 374 | let propertie = {}; | 386 | let propertie = {}; |
| @@ -377,35 +389,35 @@ export default { | @@ -377,35 +389,35 @@ export default { | ||
| 377 | properties.push(propertie); | 389 | properties.push(propertie); |
| 378 | }) | 390 | }) |
| 379 | }) | 391 | }) |
| 380 | - r.properties = properties; | ||
| 381 | - }) | ||
| 382 | - }else{ | ||
| 383 | - rates[0].name = this.baseForm.name; | ||
| 384 | - rates[0].status = this.baseForm.status; | ||
| 385 | - } | ||
| 386 | - let form = this.baseForm | ||
| 387 | - if(form.picUrls instanceof Array){ | ||
| 388 | - form.picUrls = form.picUrls.flatMap(m=>m.split(',')) | ||
| 389 | - }else if(form.picUrls.split(',') instanceof Array){ | ||
| 390 | - form.picUrls = form.picUrls.split(',').flatMap(m=>m.split(',')) | ||
| 391 | - }else{ | ||
| 392 | - form.picUrls = Array.of(form.picUrls) | ||
| 393 | - } | ||
| 394 | - form.skus = rates; | ||
| 395 | - form.specType = this.ratesForm.spec; | ||
| 396 | - form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1]; | ||
| 397 | - | ||
| 398 | - if(form.id == null){ | ||
| 399 | - createSpu(form).then((response) => { | ||
| 400 | - this.$modal.msgSuccess("新增成功"); | ||
| 401 | - this.$emit("closeDialog"); | ||
| 402 | - }) | ||
| 403 | - }else{ | ||
| 404 | - updateSpu(form).then((response) => { | ||
| 405 | - this.$modal.msgSuccess("修改成功"); | ||
| 406 | - this.$emit("closeDialog"); | ||
| 407 | - }) | ||
| 408 | - } | 392 | + r.properties = properties; |
| 393 | + }) | ||
| 394 | + } else { | ||
| 395 | + rates[0].name = this.baseForm.name; | ||
| 396 | + rates[0].status = this.baseForm.status; | ||
| 397 | + } | ||
| 398 | + let form = this.baseForm | ||
| 399 | + if (form.picUrls instanceof Array) { | ||
| 400 | + form.picUrls = form.picUrls.flatMap(m => m.split(',')) | ||
| 401 | + } else if (form.picUrls.split(',') instanceof Array) { | ||
| 402 | + form.picUrls = form.picUrls.split(',').flatMap(m => m.split(',')) | ||
| 403 | + } else { | ||
| 404 | + form.picUrls = Array.of(form.picUrls) | ||
| 405 | + } | ||
| 406 | + form.skus = rates; | ||
| 407 | + form.specType = this.ratesForm.spec; | ||
| 408 | + form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1]; | ||
| 409 | + | ||
| 410 | + if (form.id == null) { | ||
| 411 | + createSpu(form).then((response) => { | ||
| 412 | + this.$modal.msgSuccess("新增成功"); | ||
| 413 | + this.$emit("closeDialog"); | ||
| 414 | + }) | ||
| 415 | + } else { | ||
| 416 | + updateSpu(form).then((response) => { | ||
| 417 | + this.$modal.msgSuccess("修改成功"); | ||
| 418 | + this.$emit("closeDialog"); | ||
| 419 | + }) | ||
| 420 | + } | ||
| 409 | }); | 421 | }); |
| 410 | 422 | ||
| 411 | }, | 423 | }, |
| @@ -425,46 +437,46 @@ export default { | @@ -425,46 +437,46 @@ export default { | ||
| 425 | spec.specValue = obj.values; | 437 | spec.specValue = obj.values; |
| 426 | this.buildRatesFormRates(); | 438 | this.buildRatesFormRates(); |
| 427 | }, | 439 | }, |
| 428 | - updateType(id){ | ||
| 429 | - getSpuDetail(id).then((response) =>{ | ||
| 430 | - let data = response.data; | ||
| 431 | - this.baseForm.id=data.id; | ||
| 432 | - this.baseForm.name=data.name; | ||
| 433 | - this.baseForm.sellPoint=data.sellPoint; | ||
| 434 | - this.baseForm.categoryIds=data.categoryIds; | ||
| 435 | - this.baseForm.videoUrl = data.videoUrl; | ||
| 436 | - this.baseForm.sort=data.sort; | ||
| 437 | - this.baseForm.description=data.description; | ||
| 438 | - this.baseForm.picUrls=data.picUrls; | ||
| 439 | - this.baseForm.status=data.status; | ||
| 440 | - this.baseForm.virtualSalesCount=data.virtualSalesCount; | ||
| 441 | - this.baseForm.showStock=data.showStock; | ||
| 442 | - this.baseForm.brandId=data.brandId; | ||
| 443 | - this.ratesForm.spec=data.specType; | ||
| 444 | - data.skus.forEach(r=>{ | ||
| 445 | - r.marketPrice = this.divide(r.marketPrice, 100) | ||
| 446 | - r.price = this.divide(r.price, 100) | ||
| 447 | - r.costPrice = this.divide(r.costPrice, 100) | ||
| 448 | - }) | ||
| 449 | - if(this.ratesForm.spec == 2){ | ||
| 450 | - this.activeSwitch = true; | ||
| 451 | - data.productPropertyViews.forEach(p=>{ | ||
| 452 | - let obj = {}; | ||
| 453 | - obj.specId = p.propertyId; | ||
| 454 | - obj.specName = p.name; | ||
| 455 | - obj.specValue = p.propertyValues; | ||
| 456 | - this.dynamicSpec.push(obj); | ||
| 457 | - }) | ||
| 458 | - data.skus.forEach(s=>{ | ||
| 459 | - s.spec = []; | ||
| 460 | - s.properties.forEach(sp=>{ | ||
| 461 | - let spec = data.productPropertyViews.find(o=>o.propertyId == sp.propertyId).propertyValues.find(v=>v.id == sp.valueId).name; | ||
| 462 | - s.spec.push(spec) | ||
| 463 | - }) | ||
| 464 | - }) | ||
| 465 | - } | ||
| 466 | - this.ratesForm.rates=data.skus | 440 | + updateType(id) { |
| 441 | + getSpuDetail(id).then((response) => { | ||
| 442 | + let data = response.data; | ||
| 443 | + this.baseForm.id = data.id; | ||
| 444 | + this.baseForm.name = data.name; | ||
| 445 | + this.baseForm.sellPoint = data.sellPoint; | ||
| 446 | + this.baseForm.categoryIds = data.categoryIds; | ||
| 447 | + this.baseForm.videoUrl = data.videoUrl; | ||
| 448 | + this.baseForm.sort = data.sort; | ||
| 449 | + this.baseForm.description = data.description; | ||
| 450 | + this.baseForm.picUrls = data.picUrls; | ||
| 451 | + this.baseForm.status = data.status; | ||
| 452 | + this.baseForm.virtualSalesCount = data.virtualSalesCount; | ||
| 453 | + this.baseForm.showStock = data.showStock; | ||
| 454 | + this.baseForm.brandId = data.brandId; | ||
| 455 | + this.ratesForm.spec = data.specType; | ||
| 456 | + data.skus.forEach(r => { | ||
| 457 | + r.marketPrice = this.divide(r.marketPrice, 100) | ||
| 458 | + r.price = this.divide(r.price, 100) | ||
| 459 | + r.costPrice = this.divide(r.costPrice, 100) | ||
| 467 | }) | 460 | }) |
| 461 | + if (this.ratesForm.spec == 2) { | ||
| 462 | + this.activeSwitch = true; | ||
| 463 | + data.productPropertyViews.forEach(p => { | ||
| 464 | + let obj = {}; | ||
| 465 | + obj.specId = p.propertyId; | ||
| 466 | + obj.specName = p.name; | ||
| 467 | + obj.specValue = p.propertyValues; | ||
| 468 | + this.dynamicSpec.push(obj); | ||
| 469 | + }) | ||
| 470 | + data.skus.forEach(s => { | ||
| 471 | + s.spec = []; | ||
| 472 | + s.properties.forEach(sp => { | ||
| 473 | + let spec = data.productPropertyViews.find(o => o.propertyId == sp.propertyId).propertyValues.find(v => v.id == sp.valueId).name; | ||
| 474 | + s.spec.push(spec) | ||
| 475 | + }) | ||
| 476 | + }) | ||
| 477 | + } | ||
| 478 | + this.ratesForm.rates = data.skus | ||
| 479 | + }) | ||
| 468 | }, | 480 | }, |
| 469 | 481 | ||
| 470 | }, | 482 | }, |
| @@ -557,13 +569,14 @@ export default { | @@ -557,13 +569,14 @@ export default { | ||
| 557 | } | 569 | } |
| 558 | } | 570 | } |
| 559 | 571 | ||
| 560 | -.mall-image{ | ||
| 561 | - .el-upload--picture-card{ | 572 | +.mall-image { |
| 573 | + .el-upload--picture-card { | ||
| 562 | width: 80px; | 574 | width: 80px; |
| 563 | height: 80px; | 575 | height: 80px; |
| 564 | line-height: 90px; | 576 | line-height: 90px; |
| 565 | } | 577 | } |
| 566 | - .el-upload-list__item{ | 578 | + |
| 579 | + .el-upload-list__item { | ||
| 567 | width: 80px; | 580 | width: 80px; |
| 568 | height: 80px; | 581 | height: 80px; |
| 569 | } | 582 | } |