Browse Source

mall:完善商品分类的管理后台界面

YunaiV 2 years ago
parent
commit
969c387764

+ 1 - 19
sql/optional/mall/mall.sql

@@ -20,25 +20,6 @@ SET NAMES utf8mb4;
 -- ----------------------------
 -- Table structure for product_category
 -- ----------------------------
-DROP TABLE IF EXISTS `product_category`;
-CREATE TABLE `product_category`
-(
-    `id`          bigint       NOT NULL AUTO_INCREMENT COMMENT '分类编号',
-    `parent_id`   bigint       NOT NULL COMMENT '父分类编号',
-    `name`        varchar(255) NOT NULL COMMENT '分类名称',
-    `icon`        varchar(100) NOT NULL DEFAULT '#' COMMENT '分类图标',
-    `banner_url`  varchar(255) NOT NULL COMMENT '分类图片',
-    `sort`        int                   DEFAULT '0' COMMENT '分类排序',
-    `description` varchar(1024)         DEFAULT NULL COMMENT '分类描述',
-    `status`      tinyint      NOT NULL COMMENT '开启状态',
-    `creator`     varchar(64)           DEFAULT '' COMMENT '创建者',
-    `create_time` datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-    `updater`     varchar(64)           DEFAULT '' COMMENT '更新者',
-    `update_time` datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-    `deleted`     bit(1)       NOT NULL DEFAULT b'0' COMMENT '是否删除',
-    `tenant_id`   bigint       NOT NULL DEFAULT '0' COMMENT '租户编号',
-    PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB COMMENT='商品分类';
 
 -- ----------------------------
 -- Table structure for product_brand
@@ -83,6 +64,7 @@ INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `pa
 VALUES ('分类删除', 'product:category:delete', 3, 4, @parentId, '', '', '', 0);
 INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
 VALUES ('分类导出', 'product:category:export', 3, 5, @parentId, '', '', '', 0);
+
 -- 品牌管理 菜单 SQL
 INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
 VALUES ('品牌管理', '', 2, 1, 2001, 'brand', '', 'mall/product/brand/index', 0);

+ 0 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java

@@ -35,6 +35,4 @@ public class AppCategoryController {
         return success(CategoryConvert.INSTANCE.convertList03(list));
     }
 
-
-
 }

+ 2 - 11
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryListRespVO.java

@@ -8,7 +8,7 @@ import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 
 @Data
-@ApiModel(value = "App - 商品分类 列表 Request VO", description = "参数和 CategoryBaseVO 是一致的")
+@ApiModel(value = "App - 商品分类 Response VO")
 public class AppCategoryListRespVO {
 
     @ApiModelProperty(value = "分类编号", required = true, example = "2")
@@ -22,17 +22,8 @@ public class AppCategoryListRespVO {
     @NotBlank(message = "分类名称不能为空")
     private String name;
 
-    @ApiModelProperty(value = "分类图标")
-    @NotBlank(message = "分类图标不能为空")
-    private String icon;
-
     @ApiModelProperty(value = "分类图片", required = true)
     @NotBlank(message = "分类图片不能为空")
-    private String bannerUrl;
-
-    @ApiModelProperty(value = "分类排序", required = true, example = "1")
-    private Integer sort;
+    private String picUrl;
 
-    @ApiModelProperty(value = "分类描述", required = true, example = "描述")
-    private String description;
 }

+ 7 - 26
yudao-ui-admin/src/api/mall/product/category.js

@@ -1,7 +1,7 @@
 import request from '@/utils/request'
 
 // 创建商品分类
-export function createCategory(data) {
+export function createProductCategory(data) {
   return request({
     url: '/product/category/create',
     method: 'post',
@@ -10,7 +10,7 @@ export function createCategory(data) {
 }
 
 // 更新商品分类
-export function updateCategory(data) {
+export function updateProductCategory(data) {
   return request({
     url: '/product/category/update',
     method: 'put',
@@ -19,7 +19,7 @@ export function updateCategory(data) {
 }
 
 // 删除商品分类
-export function deleteCategory(id) {
+export function deleteProductCategory(id) {
   return request({
     url: '/product/category/delete?id=' + id,
     method: 'delete'
@@ -27,37 +27,18 @@ export function deleteCategory(id) {
 }
 
 // 获得商品分类
-export function getCategory(id) {
+export function getProductCategory(id) {
   return request({
     url: '/product/category/get?id=' + id,
     method: 'get'
   })
 }
 
-// 获得商品分类
-export function listCategory(query) {
-  return request({
-    url: '/product/category/listByQuery',
-    method: 'get',
-    params: query
-  })
-}
-
-// 获得商品分类分页
-export function getCategoryPage(query) {
+// 获得商品分类列表
+export function getProductCategoryList(query) {
   return request({
-    url: '/product/category/page',
+    url: '/product/category/list',
     method: 'get',
     params: query
   })
 }
-
-// 导出商品分类 Excel
-export function exportCategoryExcel(query) {
-  return request({
-    url: '/product/category/export-excel',
-    method: 'get',
-    params: query,
-    responseType: 'blob'
-  })
-}

+ 2 - 2
yudao-ui-admin/src/views/mall/product/brand/index.vue

@@ -118,7 +118,7 @@ import {
   getBrandPage,
   updateBrand
 } from "@/api/mall/product/brand";
-import {listCategory} from "@/api/mall/product/category";
+import {getProductCategoryList} from "@/api/mall/product/category";
 import ImageUpload from '@/components/ImageUpload';
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
@@ -194,7 +194,7 @@ export default {
     },
     /** 查询分类下拉树结构 */
     getTreeselect() {
-      listCategory().then(response => {
+      getProductCategoryList().then(response => {
         this.categoryOptions = [];
         const menu = {id: 0, name: '商品分类', children: []};
         menu.children = this.handleTree(response.data, "id", "pid");

+ 30 - 110
yudao-ui-admin/src/views/mall/product/category/index.vue

@@ -6,12 +6,6 @@
       <el-form-item label="分类名称" prop="name">
         <el-input v-model="queryParams.name" placeholder="请输入分类名称" clearable @keyup.enter.native="handleQuery"/>
       </el-form-item>
-      <el-form-item label="开启状态" prop="status">
-        <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small">
-          <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
-                     :key="dict.value" :label="dict.label" :value="dict.value"/>
-        </el-select>
-      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
@@ -28,27 +22,16 @@
       <el-col :span="1.5">
         <el-button type="info" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">展开/折叠</el-button>
       </el-col>
-      <el-col :span="1.5">
-        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
-                   :loading="exportLoading"
-                   v-hasPermi="['product:category:export']">导出
-        </el-button>
-      </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
     <!-- 列表 -->
     <el-table v-if="refreshTable" v-loading="loading" :data="list"  row-key="id" :default-expand-all="isExpandAll"
               :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
-      <el-table-column label="分类名称" align="center" prop="name"/>
-      <el-table-column label="分类图标" align="center" prop="icon">
-        <template slot-scope="scope">
-          <svg-icon :icon-class="scope.row.icon" />
-        </template>
-      </el-table-column>
-      <el-table-column label="分类图片" align="center" prop="bannerUrl">
+      <el-table-column label="分类名称" prop="name"/>
+      <el-table-column label="分类图片" align="center" prop="picUrl">
         <template slot-scope="scope">
-          <img v-if="scope.row.bannerUrl" :src="scope.row.bannerUrl" alt="分类图片" class="img-height"/>
+          <img v-if="scope.row.picUrl" :src="scope.row.picUrl" alt="分类图片" style="height: 100px"/>
         </template>
       </el-table-column>
       <el-table-column label="分类排序" align="center" prop="sort"/>
@@ -78,32 +61,22 @@
     <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-item label="上级分类" prop="parentId">
-          <Treeselect v-model="form.parentId" :options="parentCategoryOptions" :normalizer="normalizer"
-                      :show-count="true"
-                      placeholder="上级分类"/>
+          <el-select v-model="form.parentId" placeholder="请选择上级分类" clearable size="small">
+            <el-option :key="0" label="顶级分类" :value="0"/>
+            <el-option v-for="item in list.filter(v => v.parentId === 0)" :key="item.id" :label="item.name" :value="item.id"/>
+          </el-select>
         </el-form-item>
         <el-form-item label="分类名称" prop="name">
           <el-input v-model="form.name" placeholder="请输入分类名称"/>
         </el-form-item>
-        <el-form-item label="分类图标" prop="icon">
-          <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 label="分类图片" prop="bannerUrl">
-          <ImageUpload v-model="form.bannerUrl" :limit="1"/>
+          <ImageUpload v-model="form.picUrl" :limit="1" :is-show-tip="false" />
+          <div v-if="form.parentId === 0" style="font-size: 10px">推荐 200x100 图片分辨率</div>
+          <div v-else style="font-size: 10px">推荐 100x100 图片分辨率</div>
         </el-form-item>
         <el-form-item label="分类排序" prop="sort">
           <el-input-number v-model="form.sort" controls-position="right" :min="0" />
         </el-form-item>
-        <el-form-item label="分类描述">
-          <editor v-model="form.description" :min-height="192"/>
-        </el-form-item>
         <el-form-item label="开启状态" prop="status">
           <el-radio-group v-model="form.status">
             <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
@@ -111,6 +84,9 @@
             </el-radio>
           </el-radio-group>
         </el-form-item>
+        <el-form-item label="分类描述">
+          <el-input v-model="form.description" type="textarea" placeholder="请输入分类描述" />
+        </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -122,34 +98,31 @@
 
 <script>
 import {
-  createCategory,
-  deleteCategory,
+  createProductCategory,
+  deleteProductCategory,
   exportCategoryExcel,
-  getCategory,
-  listCategory,
-  updateCategory
+  getProductCategory,
+  getProductCategoryList,
+  updateProductCategory
 } from "@/api/mall/product/category";
 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';
+import {CommonStatusEnum} from "@/utils/constants";
 
 export default {
   name: "Category",
   components: {
-    Editor, Treeselect, IconSelect, ImageUpload
+    Editor, Treeselect, ImageUpload
   },
   data() {
     return {
       // 遮罩层
       loading: true,
-      // 导出遮罩层
-      exportLoading: false,
       // 显示搜索条件
       showSearch: true,
-      // 总条数
-      total: 0,
       // 商品分类列表
       list: [],
       // 商品分类树选项
@@ -164,10 +137,7 @@ export default {
       refreshTable: true,
       // 查询参数
       queryParams: {
-        pageNo: 1,
-        pageSize: 10,
         name: null,
-        status: null,
       },
       // 表单参数
       form: {},
@@ -175,8 +145,8 @@ export default {
       rules: {
         parentId: [{required: true, message: "请选择上级分类", trigger: "blur"}],
         name: [{required: true, message: "分类名称不能为空", trigger: "blur"}],
-        icon: [{required: true, message: "分类图标不能为空", trigger: "blur"}],
-        bannerUrl: [{required: true, message: "分类图片不能为空", trigger: "blur"}],
+        picUrl: [{required: true, message: "分类图片不能为空", trigger: "blur"}],
+        sort: [{required: true, message: "分类排序不能为空", trigger: "blur"}],
         status: [{required: true, message: "开启状态不能为空", trigger: "blur"}],
       }
     };
@@ -191,35 +161,11 @@ export default {
       // 处理查询参数
       let params = {...this.queryParams};
       // 执行查询
-      listCategory(params).then(response => {
+      getProductCategoryList(params).then(response => {
         this.list = this.handleTree(response.data, "id", "parentId");
         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", "parentId");
-        this.parentCategoryOptions.push(menu);
-      });
-    },
     /** 取消按钮 */
     cancel() {
       this.open = false;
@@ -231,11 +177,10 @@ export default {
         id: undefined,
         parentId: undefined,
         name: undefined,
-        icon: undefined,
-        bannerUrl: undefined,
-        sort: undefined,
+        pirUrl: undefined,
+        sort: 0,
         description: undefined,
-        status: undefined,
+        status: CommonStatusEnum.ENABLE,
       };
       this.resetForm("form");
     },
@@ -260,16 +205,14 @@ export default {
     /** 新增按钮操作 */
     handleAdd() {
       this.reset();
-      this.getTreeselect();
       this.open = true;
       this.title = "添加商品分类";
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
-      this.getTreeselect();
       const id = row.id;
-      getCategory(id).then(response => {
+      getProductCategory(id).then(response => {
         this.form = response.data;
         this.open = true;
         this.title = "修改商品分类";
@@ -283,7 +226,7 @@ export default {
         }
         // 修改的提交
         if (this.form.id != null) {
-          updateCategory(this.form).then(response => {
+          updateProductCategory(this.form).then(response => {
             this.$modal.msgSuccess("修改成功");
             this.open = false;
             this.getList();
@@ -291,7 +234,7 @@ export default {
           return;
         }
         // 添加的提交
-        createCategory(this.form).then(response => {
+        createProductCategory(this.form).then(response => {
           this.$modal.msgSuccess("新增成功");
           this.open = false;
           this.getList();
@@ -302,36 +245,13 @@ export default {
     handleDelete(row) {
       const id = row.id;
       this.$modal.confirm('是否确认删除商品分类编号为"' + id + '"的数据项?').then(function () {
-        return deleteCategory(id);
+        return deleteProductCategory(id);
       }).then(() => {
         this.getList();
         this.$modal.msgSuccess("删除成功");
       }).catch(() => {
       });
-    },
-    /** 导出按钮操作 */
-    handleExport() {
-      // 处理查询参数
-      let params = {...this.queryParams};
-      params.pageNo = undefined;
-      params.pageSize = undefined;
-      // 执行导出
-      this.$modal.confirm('是否确认导出所有商品分类数据项?').then(() => {
-        this.exportLoading = true;
-        return exportCategoryExcel(params);
-      }).then(response => {
-        this.$download.excel(response, '商品分类.xls');
-        this.exportLoading = false;
-      }).catch(() => {
-      });
     }
   }
 };
 </script>
-
-<style scoped lang="scss">
-//
-.img-height {
-  height: 150px;
-}
-</style>

+ 6 - 6
yudao-ui-admin/src/views/mall/product/spu/index.vue

@@ -283,12 +283,12 @@
 <script>
 import {createSpu, updateSpu, deleteSpu, getSpu, getSpuPage, exportSpuExcel} from "@/api/mall/product/spu";
 import {
-  createCategory,
-  deleteCategory,
+  createProductCategory,
+  deleteProductCategory,
   exportCategoryExcel,
-  getCategory,
-  listCategory,
-  updateCategory
+  getProductCategory,
+  getProductCategoryList,
+  updateProductCategory
 } from "@/api/mall/product/category";
 import {
   createProperty,
@@ -585,7 +585,7 @@ export default {
     /** 查询分类 */
     getListCategory() {
       // 执行查询
-      listCategory().then(response => {
+      getProductCategoryList().then(response => {
         this.categoryList = this.handleTree(response.data, "id", "parentId");
 
       });