[TOC]
# 步骤1 : 先运行,看到效果,再学习
先将完整的项目(向老师要相关资料),配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
# 步骤2 : 模仿和排错
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较**正确答案** ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,**学习有效果,排错有效率**,可以较为明显地提升学习速度,跨过学习路上的各个槛。
# 步骤3 : 效果
重启tomcat,通过访问地址
`http://localhost:8080/tmall_ssm/admin_property_list?categoryId=30`
可以看到属性管理的界面
注: 这categoryId=12是分类的id,根据你的实际运行情况,采取不同的id值
![](https://box.kancloud.cn/3269896e366aca2f284690f1254f93d0_1822x461.png)
# 步骤4:在分类管理页面上添加属性管理的超链
接下来讲, 基于 分类管理可运行项目 做了哪些工作以支持属性管理的操作。
首先,在listCategory.jsp里,加上属性管理这一列
```
<th>属性管理</th>
```
```
<td><a href="admin_property_list?cid=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td>
```
![](https://box.kancloud.cn/6e5c3489a6eb639922fc9a86cecffaf2_95x202.png)
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.jsp"%>
<%@include file="../include/admin/adminNavigator.jsp"%>
<script>
$(function(){
$("#addForm").submit(function(){
if(!checkEmpty("name","分类名称"))
return false;
if(!checkEmpty("categoryPic","分类图片"))
return false;
return true;
});
});
</script>
<title>分类管理</title>
<div class="workingArea">
<h1 class="label label-info" >分类管理</h1>
<br>
<br>
<div class="listDataTableDiv">
<table class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr class="success">
<th>ID</th>
<th>图片</th>
<th>分类名称</th>
<th>属性管理</th>
<!-- <th>产品管理</th> -->
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody>
<c:forEach items="${thecs}" var="c">
<tr>
<td>${c.id}</td>
<td><img height="40px" src="img/category/${c.id}.jpg"></td>
<td>${c.name}</td>
<td><a href="admin_property_list?cid=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td>
<%-- <td><a href="admin_product_list?cid=${c.id}"><span class="glyphicon glyphicon-shopping-cart"></span></a></td> --%>
<td><a href="admin_category_edit?id=${c.id}"><span class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true" href="admin_category_delete?id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="pageDiv">
<%@include file="../include/admin/adminPage.jsp" %>
</div>
<div class="panel panel-warning addDiv">
<div class="panel-heading">新增分类</div>
<div class="panel-body">
<form method="post" id="addForm" action="admin_category_add" enctype="multipart/form-data">
<table class="addTable">
<tr>
<td>分类名称</td>
<td><input id="name" name="name" type="text" class="form-control"></td>
</tr>
<tr>
<td>分类圖片</td>
<td>
<input id="categoryPic" accept="image/*" type="file" name="filepath" />
</td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<%@include file="../include/admin/adminFooter.jsp"%>
```
# 步骤5:修改实体类Property.java
1. 与Category的多对一关系
如图所示,这些属性,都属于平板电视这个分类。
![](https://box.kancloud.cn/962d5a5f718d7fc1c885c0e9796c1522_306x251.png)
```
package com.dodoke.bean;
/*******************************************************************************
* javaBeans t_property --> TProperty <table explanation>
*
* @author 2019-01-17 08:35:28
*
*/
public class Property {
// field
/** ID **/
private int id;
/** 名称 **/
private String name;
/** 所属分类 **/
private Category categroy;
// method
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Category getCategroy() {
return categroy;
}
public void setCategroy(Category categroy) {
this.categroy = categroy;
}
@Override
public String toString() {
return "Property [id=" + id + ", name=" + name + ", categroy=" + categroy + "]";
}
}
```
# 步骤6:PropertyDao和PropertyDaoImpl
PropertyDao:
```
package com.dodoke.dao.inter;
import java.util.List;
import com.dodoke.bean.Property;
public interface PropertyDao {
/**
* 增加
*
* @param property
*/
public void add(Property property);
/**
* 删除
*
* @param id
*/
public void delete(int id);
/**
* 修改
*
* @param property
*/
public void update(Property property);
/**
* 根据id获取
*
* @param id
* @return
*/
public Property get(int id);
/**
* 某个分类下的属性分页查询
* @param cid
* @param start
* @param count
* @return
*/
public List<Property> list(int cid,int start, int count);
/**
* 查询某个分类下的所有属性
*
* @return
*/
public List<Property> list(int cid);
/**
* 获取某个分类下的属性总数
*
* @return
*/
public int getTotal(int cid);
}
```
PropertyDaoImpl:
```
package com.dodoke.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.dodoke.bean.Category;
import com.dodoke.bean.Property;
import com.dodoke.dao.inter.CategoryDao;
import com.dodoke.dao.inter.PropertyDao;
import com.dodoke.util.DBUtil;
public class PropertyDaoImpl implements PropertyDao {
private CategoryDao categoryDao = new CategoryDaoImpl();
@Override
public void add(Property property) {
String sql = "insert into t_property(name, category_id) values(?,?)";
try (Connection c = DBUtil.getConnection();
PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);) {
ps.setString(1, property.getName());
ps.setInt(2, property.getCategory().getId());
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
int id = rs.getInt(1);
property.setId(id);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void delete(int id) {
String sql = "delete from t_property where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void update(Property property) {
String sql = "update t_property set category_id= ?, name=? where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, property.getCategory().getId());
ps.setString(2, property.getName());
ps.setInt(3, property.getId());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public Property get(int id) {
Property bean = new Property();
String sql = "select * from t_property where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
String name = rs.getString("name");
int cid = rs.getInt("category_id");
bean.setName(name);
Category category = categoryDao.get(cid);
bean.setCategory(category);
bean.setId(id);
}
} catch (SQLException e) {
e.printStackTrace();
}
return bean;
}
@Override
public List<Property> list(int cid, int start, int count) {
List<Property> beans = new ArrayList<Property>();
String sql = "select * from t_property where category_id = ? order by id desc limit ?,? ";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, cid);
ps.setInt(2, start);
ps.setInt(3, count);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Property bean = new Property();
int id = rs.getInt("id");
String name = rs.getString("name");
Category category = categoryDao.get(cid);
bean.setId(id);
bean.setName(name);
bean.setCategory(category);
beans.add(bean);
}
} catch (SQLException e) {
e.printStackTrace();
}
return beans;
}
@Override
public List<Property> list(int cid) {
return list(cid, 0, Short.MAX_VALUE);
}
@Override
public int getTotal(int cid) {
int total = 0;
String sql = "select count(*) from t_property where category_id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, cid);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
total = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return total;
}
}
```
# 步骤7:PropertyServlet类
```
package com.dodoke.controller;
import java.util.List;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dodoke.bean.Category;
import com.dodoke.bean.Property;
import com.dodoke.util.Page;
/**
* Servlet implementation class PropertyServlet
*/
@WebServlet("/PropertyServlet")
public class PropertyServlet extends BaseBackServlet {
private static final long serialVersionUID = 1L;
@Override
public String add(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
String name = request.getParameter("name");
Property p = new Property();
p.setCategory(c);
p.setName(name);
propertyDao.add(p);
return "@admin_property_list?cid=" + cid;
}
@Override
public String delete(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Property p = propertyDao.get(id);
propertyDao.delete(id);
return "@admin_property_list?cid=" + p.getCategory().getId();
}
@Override
public String edit(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Property p = propertyDao.get(id);
request.setAttribute("p", p);
return "admin/editProperty.jsp";
}
@Override
public String update(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
Property p = new Property();
p.setCategory(c);
p.setId(id);
p.setName(name);
propertyDao.update(p);
return "@admin_property_list?cid=" + p.getCategory().getId();
}
@Override
public String list(HttpServletRequest request, HttpServletResponse response, Page page) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
List<Property> ps = propertyDao.list(cid, page.getStart(), page.getCount());
int total = propertyDao.getTotal(cid);
page.setTotal(total);
page.setParam("&cid=" + c.getId());
request.setAttribute("ps", ps);
request.setAttribute("c", c);
request.setAttribute("page", page);
return "admin/listProperty.jsp";
}
}
```
# 步骤8:修改BaseBackServlet
添加dao对象,以便在子类中调用。
```
public PropertyDao propertyDao = new PropertyDaoImpl();
```
# 步骤 9 : listProperty.jsp+editProperty.jsp
listProperty.jsp:
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.jsp"%>
<%@include file="../include/admin/adminNavigator.jsp"%>
<script>
$(function() {
$("#addForm").submit(function() {
if (checkEmpty("name", "属性名称"))
return true;
return false;
});
});
</script>
<title>属性管理</title>
<div class="workingArea">
<ol class="breadcrumb">
<li><a href="admin_category_list">所有分类</a></li>
<li><a href="admin_property_list?cid=${c.id}">${c.name}</a></li>
<li class="active">属性管理</li>
</ol>
<div class="listDataTableDiv">
<table
class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr class="success">
<th>ID</th>
<th>属性名称</th>
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody>
<c:forEach items="${ps}" var="p">
<tr>
<td>${p.id}</td>
<td>${p.name}</td>
<td><a href="admin_property_edit?id=${p.id}"><span
class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true"
href="admin_property_delete?id=${p.id}"><span
class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="pageDiv">
<%@include file="../include/admin/adminPage.jsp"%>
</div>
<div class="panel panel-warning addDiv">
<div class="panel-heading">新增属性</div>
<div class="panel-body">
<form method="post" id="addForm" action="admin_property_add">
<table class="addTable">
<tr>
<td>属性名称</td>
<td><input id="name" name="name" type="text"
class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="cid" value="${c.id}">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<%@include file="../include/admin/adminFooter.jsp"%>
```
editProperty.jsp:
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.jsp"%>
<%@include file="../include/admin/adminNavigator.jsp"%>
<title>编辑属性</title>
<div class="workingArea">
<ol class="breadcrumb">
<li><a href="admin_category_list">所有分类</a></li>
<li><a href="admin_property_list?cid=${p.category.id}">${p.category.name}</a></li>
<li class="active">编辑属性</li>
</ol>
<div class="panel panel-warning editDiv">
<div class="panel-heading">编辑属性</div>
<div class="panel-body">
<form method="post" id="editForm" action="admin_property_update">
<table class="editTable">
<tr>
<td>属性名称</td>
<td><input id="name" name="name" value="${p.name}"
type="text" class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="id" value="${p.id}">
<input type="hidden" name="cid" value="${p.category.id}">
<button type="submit" class="btn btn-success">提 交</button></td>
</tr>
</table>
</form>
</div>
</div>
</div>
```
# 步骤10: 查询功能讲解
查询访问的是PropertyServlet的list()方法
1\. 获取分类 cid
2\. 基于cid,获取当前分类下的属性集合
3\. 获取当前分类下的属性总数,并且设置给分页page对象
4\. 拼接字符串"&cid="+c.getId(),设置给page对象的Param值。 因为属性分页都是基于当前分类下的分页,所以分页的时候需要传递这个cid
5\. 把属性集合设置到 request的 "ps" 属性上
6\. 把分类对象设置到 request的 "c" 属性上
7\. 把分页对象设置到 request的 "page" 对象上
8\. 服务端跳转到admin/listProperty.jsp页面
9\. 在listProperty.jsp页面上使用c:forEach 遍历ps集合,并显示
![](https://box.kancloud.cn/fcc16b5bb3b9573480cfb9720da78913_1813x313.png)
PropertyServlet片段:
```
@Override
public String list(HttpServletRequest request, HttpServletResponse response, Page page) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
List<Property> ps = propertyDao.list(cid, page.getStart(), page.getCount());
int total = propertyDao.getTotal(cid);
page.setTotal(total);
page.setParam("&cid=" + c.getId());
request.setAttribute("ps", ps);
request.setAttribute("c", c);
request.setAttribute("page", page);
return "admin/listProperty.jsp";
}
```
listPropety.jsp
```
<c:forEach items="${ps}" var="p">
<tr>
<td>${p.id}</td>
<td>${p.name}</td>
<td><a href="admin_property_edit?id=${p.id}"><span
class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true"
href="admin_property_delete?id=${p.id}"><span
class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
```
# 步骤 11 : 增加功能讲解
1\. 在listProperty.jsp页面提交数据的时候,除了提交属性名称,还会提交cid
2\. 在PropertyServlet中根据获取到的cid,name参数,创建新的Property对象,并插入到数据库
3\. 客户端跳转到admin\_property\_list,并带上参数cid
![](https://box.kancloud.cn/07df94a4e9ff883ffe602e435de1e3e3_518x211.png)
PropertyServlet片段:
```
public String add(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
String name = request.getParameter("name");
Property p = new Property();
p.setCategory(c);
p.setName(name);
propertyDao.add(p);
return "@admin_property_list?cid=" + cid;
}
```
listPropety.jsp:
```
<form method="post" id="addForm" action="admin_property_add">
<table class="addTable">
<tr>
<td>属性名称</td>
<td><input id="name" name="name" type="text"
class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="cid" value="${c.id}">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
```
# 步骤12: 编辑功能讲解
1\. 在PropertyServlet的edit方法中,根据id获取Property对象
2\. 把Property对象放在request的 "p" 属性中
3\. 服务端跳转到admin/editProperty.jsp
4\. 在editProperty.jsp中显示属性名称
5\. 在editProperty.jsp中隐式提供id和cid
```
<input type="hidden" name="id" value="${p.id}">
<input type="hidden" name="cid" value="${p.category.id}">
```
PropertyServlet片段:
```
public String edit(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Property p = propertyDao.get(id);
request.setAttribute("p", p);
return "admin/editProperty.jsp";
}
```
editPropety.jsp:
```
<form method="post" id="editForm" action="admin_property_update">
<table class="editTable">
<tr>
<td>属性名称</td>
<td><input id="name" name="name" value="${p.name}"
type="text" class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="id" value="${p.id}">
<input type="hidden" name="cid" value="${p.category.id}">
<button type="submit" class="btn btn-success">提 交</button></td>
</tr>
</table>
</form>
```
# 步骤 13 : 修改功能讲解
1\. 在PropertyServlet的update方法中获取cid,id, name等参数
2\. 根据这些参数创建Property对象
3\. 借助propertyDAO更新这个对象到数据库
4\. 客户端跳转到admin\_property\_list,并带上参数cid
![](https://box.kancloud.cn/bbccb3f273c3ea7470141f2204ba600c_481x200.png)
```
public String update(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
int id = Integer.parseInt(request.getParameter("id"));
String name = request.getParameter("name");
Property p = new Property();
p.setCategory(c);
p.setId(id);
p.setName(name);
propertyDao.update(p);
return "@admin_property_list?cid=" + p.getCategory().getId();
}
```
# 步骤 14 : 删除功能讲解
1. 在PropertyController的delete方法中获取id
2. 根据id获取Property对象
3. 借助propertyService删除这个对象对应的数据
4. 客户端跳转到`admin_property_list`,并带上参数categoryId
![](https://box.kancloud.cn/6e5c3489a6eb639922fc9a86cecffaf2_95x202.png)
```
public String delete(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Property p = propertyDao.get(id);
propertyDao.delete(id);
return "@admin_property_list?cid=" + p.getCategory().getId();
}
```
# 步骤 15 : 其他-面包屑导航
在属性管理页面的页头,有一个面包屑导航
第一个连接跳转到`admin_category_list`
第二个连接跳转到`admin_property_list?cid=`
``
样式用的是Bootstrap面包屑导航
![](../images/Image125.png)
```
<ol class="breadcrumb">
<li><a href="admin_category_list">所有分类</a></li>
<li><a href="admin_property_list?categoryId=${c.id}">${c.name}-属性</a></li>
<li class="active">属性管理</li>
</ol>
```
# 步骤 16 : 其他-分页
这里的分页比起分类管理中的分页多了一个参数categoryId
1. 在`PropertyController.list()` 方法中,把`&cid=` 参数设置到在page对象的param属性上
```
page.setParam("&cid=" + c.getId());
```
2. 在adminPage.jsp页面中通过`${page.param}`取出这个参数
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<script>
$(function(){
$("ul.pagination li.disabled a").click(function(){
return false;
});
});
</script>
<nav>
<ul class="pagination">
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=0${page.param}" aria-label="Previous" >
<span aria-hidden="true">«</span>
</a>
</li>
<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
<a href="?page.start=${page.start-page.count}${page.param}" aria-label="Previous" >
<span aria-hidden="true">‹</span>
</a>
</li>
<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">
<c:if test="${status.count*page.count-page.start<=20 && status.count*page.count-page.start>=-10}">
<li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>
<a
href="?page.start=${status.index*page.count}${page.param}"
<c:if test="${status.index*page.count==page.start}">class="current"</c:if>
>${status.count}</a>
</li>
</c:if>
</c:forEach>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.start+page.count}${page.param}" aria-label="Next">
<span aria-hidden="true">›</span>
</a>
</li>
<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>
<a href="?page.start=${page.last}${page.param}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
```
- 项目简介
- 功能一览
- 前台
- 后台
- 开发流程
- 需求分析-展示
- 首页
- 产品页
- 分类页
- 搜索结果页
- 购物车查看页
- 结算页
- 确认支付页
- 支付成功页
- 我的订单页
- 确认收货页
- 评价页
- 页头信息展示
- 需求分析-交互
- 分类页排序
- 立即购买
- 加入购物车
- 调整订单项数量
- 删除订单项
- 生成订单
- 订单页功能
- 确认付款
- 确认收货
- 提交评价信息
- 登录
- 注册
- 退出
- 搜索
- 前台需求列表
- 需求分析后台
- 分类管理
- 属性管理
- 产品管理
- 产品图片管理
- 产品属性设置
- 用户管理
- 订单管理
- 后台需求列表
- 表结构设计
- 数据建模
- 表与表之间的关系
- 实体类设计
- DAO类设计
- 工具类
- CategoryDao设计
- Service业务类设计
- 后台-分类管理
- 可运行的项目
- 静态资源
- FILTER配合SERVLET
- JSP包含关系
- 查询
- 分页
- 增加
- 删除
- 编辑
- 修改
- 后台其他管理
- 属性管理
- 产品管理
- 产品图片管理
- 产品属性值设置
- 用户管理
- 订单管理