商品分类维护

pull/2/head
JeromeSoar 2022-04-24 17:01:10 +08:00
parent 4e67b6bbcf
commit d3edaec2b1
7 changed files with 137 additions and 58 deletions

View File

@ -26,10 +26,10 @@ CREATE TABLE `product_category`
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '', `id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`pid` bigint NOT NULL COMMENT '', `pid` bigint NOT NULL COMMENT '',
`name` varchar(255) NOT NULL COMMENT '', `name` varchar(255) NOT NULL COMMENT '',
`icon` varchar(100) DEFAULT '#' COMMENT '', `icon` varchar(100) NOT NULL DEFAULT '#' COMMENT '',
`banner_url` varchar(255) NOT NULL COMMENT '', `banner_url` varchar(255) NOT NULL COMMENT '',
`sort` int NOT NULL DEFAULT '0' COMMENT '', `sort` int DEFAULT '0' COMMENT '',
`description` varchar(1024) NOT NULL COMMENT '', `description` varchar(1024) DEFAULT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '', `status` tinyint NOT NULL COMMENT '',
`creator` varchar(64) DEFAULT '' COMMENT '', `creator` varchar(64) DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',

View File

@ -1,30 +1,29 @@
package cn.iocoder.yudao.module.product.controller.admin.category; package cn.iocoder.yudao.module.product.controller.admin.category;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
import cn.iocoder.yudao.module.product.service.category.CategoryService; import cn.iocoder.yudao.module.product.service.category.CategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Api(tags = "管理后台 - 商品分类") @Api(tags = "管理后台 - 商品分类")
@RestController @RestController
@ -68,15 +67,22 @@ public class CategoryController {
return success(CategoryConvert.INSTANCE.convert(category)); return success(CategoryConvert.INSTANCE.convert(category));
} }
@GetMapping("/list") @GetMapping("/listByIds")
@ApiOperation("获得商品分类列表") @ApiOperation("获得商品分类列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('product:category:query')") @PreAuthorize("@ss.hasPermission('product:category:query')")
public CommonResult<List<CategoryRespVO>> getCategoryList(@RequestParam("ids") Collection<Long> ids) { public CommonResult<List<CategoryRespVO>> getCategoryList(@RequestParam("ids") Collection<Long> ids) {
List<CategoryDO> list = categoryService.getCategoryList(ids); List<CategoryDO> list = categoryService.getCategoryList(ids);
return success(CategoryConvert.INSTANCE.convertList(list)); return success(CategoryConvert.INSTANCE.convertList(list));
} }
@GetMapping("/listByQuery")
@ApiOperation("获得商品分类列表")
@PreAuthorize("@ss.hasPermission('product:category:query')")
public CommonResult<List<CategoryRespVO>> listByQuery() {
List<CategoryDO> list = categoryService.listByQuery();
return success(CategoryConvert.INSTANCE.convertList(list));
}
@GetMapping("/page") @GetMapping("/page")
@ApiOperation("获得商品分类分页") @ApiOperation("获得商品分类分页")
@PreAuthorize("@ss.hasPermission('product:category:query')") @PreAuthorize("@ss.hasPermission('product:category:query')")

View File

@ -1,9 +1,10 @@
package cn.iocoder.yudao.module.product.controller.admin.category.vo; package cn.iocoder.yudao.module.product.controller.admin.category.vo;
import lombok.*; import io.swagger.annotations.ApiModelProperty;
import java.util.*; import lombok.Data;
import io.swagger.annotations.*;
import javax.validation.constraints.*; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/** /**
* Base VO VO 使 * Base VO VO 使
@ -17,22 +18,21 @@ public class CategoryBaseVO {
private Long pid; private Long pid;
@ApiModelProperty(value = "分类名称", required = true, example = "办公文具") @ApiModelProperty(value = "分类名称", required = true, example = "办公文具")
@NotNull(message = "分类名称不能为空") @NotBlank(message = "分类名称不能为空")
private String name; private String name;
@ApiModelProperty(value = "分类图标") @ApiModelProperty(value = "分类图标")
@NotBlank(message = "分类图标不能为空")
private String icon; private String icon;
@ApiModelProperty(value = "分类图片", required = true) @ApiModelProperty(value = "分类图片", required = true)
@NotNull(message = "分类图片不能为空") @NotBlank(message = "分类图片不能为空")
private String bannerUrl; private String bannerUrl;
@ApiModelProperty(value = "分类排序", required = true, example = "1") @ApiModelProperty(value = "分类排序", required = true, example = "1")
@NotNull(message = "分类排序不能为空")
private Integer sort; private Integer sort;
@ApiModelProperty(value = "分类描述", required = true, example = "描述") @ApiModelProperty(value = "分类描述", required = true, example = "描述")
@NotNull(message = "分类描述不能为空")
private String description; private String description;
@ApiModelProperty(value = "开启状态", required = true, example = "0") @ApiModelProperty(value = "开启状态", required = true, example = "0")

View File

@ -1,10 +1,15 @@
package cn.iocoder.yudao.module.product.service.category; package cn.iocoder.yudao.module.product.service.category;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/** /**
* Service * Service
@ -67,4 +72,10 @@ public interface CategoryService {
*/ */
List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO); List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO);
/**
*
*
* @return
*/
List<CategoryDO> listByQuery();
} }

View File

@ -1,19 +1,22 @@
package cn.iocoder.yudao.module.product.service.category; package cn.iocoder.yudao.module.product.service.category;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO;
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.util.*; import javax.annotation.Resource;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; import java.util.Collection;
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; import java.util.List;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;
/** /**
* Service * Service
@ -79,4 +82,9 @@ public class CategoryServiceImpl implements CategoryService {
return categoryMapper.selectList(exportReqVO); return categoryMapper.selectList(exportReqVO);
} }
@Override
public List<CategoryDO> listByQuery() {
return categoryMapper.selectList();
}
} }

View File

@ -34,6 +34,15 @@ export function getCategory(id) {
}) })
} }
// 获得商品分类
export function listCategory(query) {
return request({
url: '/product/category/listByQuery',
method: 'get',
params: query
})
}
// 获得商品分类分页 // 获得商品分类分页
export function getCategoryPage(query) { export function getCategoryPage(query) {
return request({ return request({

View File

@ -40,13 +40,18 @@
<!-- 列表 --> <!-- 列表 -->
<el-table v-loading="loading" :data="list"> <el-table v-loading="loading" :data="list">
<el-table-column label="分类编号" align="center" prop="id"/>
<el-table-column label="父分类编号" align="center" prop="pid"/>
<el-table-column label="分类名称" align="center" prop="name"/> <el-table-column label="分类名称" align="center" prop="name"/>
<el-table-column label="分类图标" align="center" prop="icon"/> <el-table-column label="分类图标" align="center" prop="icon">
<el-table-column label="分类图片" align="center" prop="bannerUrl"/> <template slot-scope="scope">
<svg-icon :icon-class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column label="分类图片" align="center" prop="bannerUrl">
<template slot-scope="scope">
<img v-if="scope.row.bannerUrl" :src="scope.row.bannerUrl" alt="分类图片"/>
</template>
</el-table-column>
<el-table-column label="分类排序" align="center" prop="sort"/> <el-table-column label="分类排序" align="center" prop="sort"/>
<el-table-column label="分类描述" align="center" prop="description"/>
<el-table-column label="开启状态" align="center" prop="status"> <el-table-column label="开启状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
@ -75,20 +80,28 @@
<!-- 对话框(添加 / 修改) --> <!-- 对话框(添加 / 修改) -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="父分类编号" prop="pid"> <el-form-item label="上级分类" prop="pid">
<el-input v-model="form.pid" placeholder="请输入父分类编号"/> <Treeselect v-model="form.pid" :options="parentCategoryOptions" :normalizer="normalizer" :show-count="true"
placeholder="上级分类"/>
</el-form-item> </el-form-item>
<el-form-item label="分类名称" prop="name"> <el-form-item label="分类名称" prop="name">
<el-input v-model="form.name" placeholder="请输入分类名称"/> <el-input v-model="form.name" placeholder="请输入分类名称"/>
</el-form-item> </el-form-item>
<el-form-item label="分类图标" prop="icon"> <el-form-item label="分类图标" prop="icon">
<el-input v-model="form.icon" placeholder="请输入分类图标"/> <el-popover placement="bottom-start" width="460" trigger="click" @show="$refs['iconSelect'].reset()">
<IconSelect ref="iconSelect" @selected="iconSelected"/>
<el-input slot="reference" v-model="form.icon" placeholder="点击选择分类图标" readonly>
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon"
style="height: 32px;width: 16px;"/>
<i v-else slot="prefix" class="el-icon-search el-input__icon"/>
</el-input>
</el-popover>
</el-form-item> </el-form-item>
<el-form-item label="分类图片" prop="bannerUrl"> <el-form-item label="分类图片" prop="bannerUrl">
<el-input v-model="form.bannerUrl" placeholder="请输入分类图片"/> <el-input v-model="form.bannerUrl" placeholder="请输入分类图片"/>
</el-form-item> </el-form-item>
<el-form-item label="分类排序" prop="sort"> <el-form-item label="分类排序" prop="sort">
<el-input v-model="form.sort" placeholder="请输入分类排序"/> <el-input-number v-model="form.sort" controls-position="right" :min="0" />
</el-form-item> </el-form-item>
<el-form-item label="分类描述"> <el-form-item label="分类描述">
<editor v-model="form.description" :min-height="192"/> <editor v-model="form.description" :min-height="192"/>
@ -116,14 +129,19 @@ import {
exportCategoryExcel, exportCategoryExcel,
getCategory, getCategory,
getCategoryPage, getCategoryPage,
listCategory,
updateCategory updateCategory
} from "@/api/mall/product/category"; } from "@/api/mall/product/category";
import Editor from '@/components/Editor'; import Editor from '@/components/Editor';
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import IconSelect from "@/components/IconSelect";
import ImageUpload from '@/components/ImageUpload';
export default { export default {
name: "Category", name: "Category",
components: { components: {
Editor, Editor, Treeselect, IconSelect, ImageUpload
}, },
data() { data() {
return { return {
@ -137,6 +155,8 @@ export default {
total: 0, total: 0,
// //
list: [], list: [],
//
parentCategoryOptions: [],
// //
title: "", title: "",
// //
@ -153,11 +173,10 @@ export default {
form: {}, form: {},
// //
rules: { rules: {
pid: [{required: true, message: "父分类编号不能为空", trigger: "blur"}], pid: [{required: true, message: "请选择上级分类", trigger: "blur"}],
name: [{required: true, message: "分类名称不能为空", trigger: "blur"}], name: [{required: true, message: "分类名称不能为空", trigger: "blur"}],
icon: [{required: true, message: "分类图标不能为空", trigger: "blur"}],
bannerUrl: [{required: true, message: "分类图片不能为空", trigger: "blur"}], bannerUrl: [{required: true, message: "分类图片不能为空", trigger: "blur"}],
sort: [{required: true, message: "分类排序不能为空", trigger: "blur"}],
description: [{required: true, message: "分类描述不能为空", trigger: "blur"}],
status: [{required: true, message: "开启状态不能为空", trigger: "blur"}], status: [{required: true, message: "开启状态不能为空", trigger: "blur"}],
} }
}; };
@ -179,6 +198,30 @@ export default {
this.loading = false; this.loading = false;
}); });
}, },
//
iconSelected(name) {
this.form.icon = name;
},
/** 转换菜单数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.name,
children: node.children
};
},
/** 查询分类下拉树结构 */
getTreeselect() {
listCategory().then(response => {
this.parentCategoryOptions = [];
const menu = {id: 0, name: '主分类', children: []};
menu.children = this.handleTree(response.data, "id", "pid");
this.parentCategoryOptions.push(menu);
});
},
/** 取消按钮 */ /** 取消按钮 */
cancel() { cancel() {
this.open = false; this.open = false;
@ -212,12 +255,14 @@ export default {
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.getTreeselect();
this.open = true; this.open = true;
this.title = "添加商品分类"; this.title = "添加商品分类";
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset(); this.reset();
this.getTreeselect();
const id = row.id; const id = row.id;
getCategory(id).then(response => { getCategory(id).then(response => {
this.form = response.data; this.form = response.data;