taotao 商城 -4美高梅4858官方网站

作者:编程技术

makemigrations创建迁移失败错误如下:

数据库设计

分为如下几个模块:

  • tb_area:存储地址,主键为area_id
  • tb_head_line:存储首页轮播图,主键为line_id
  • tb_person_info:存储用户信息,主键为user_id
  • tb_product:存储商品信息,主键为product_id,表结构如下所示:

    美高梅4858官方网站 1

    tb_productbiaojieg

这张表中外键的信息是这样的:

CONSTRAINT fk_product_procate FOREIGN KEY (product_category_id) REFERENCES tb_product_category (product_category_id),
CONSTRAINT fk_product_shop FOREIGN KEY (shop_id) REFERENCES tb_shop (shop_id)

分别表明这个商品属于哪个商品类别以及属于哪个店铺下面。

  • tb_product_category:商品种类信息,主键为product_category_id,表结构如下:

    美高梅4858官方网站 2

    tb_product_category表结构

  • tb_product_img:商品图片

  • tb_shop:店铺信息,表结构如下所示:

    美高梅4858官方网站 3

    tb_shop的表结构

在创建这个表的时候有如下创建语句:

CONSTRAINT fk_shop_area FOREIGN KEY (area_id) REFERENCES tb_area (area_id),
CONSTRAINT fk_shop_profile FOREIGN KEY (owner_id) REFERENCES tb_person_info (user_id),
CONSTRAINT fk_shop_shopcate FOREIGN KEY (shop_category_id) REFERENCES tb_shop_category (shop_category_id)

分别有三个外键与tb_area,tb_person_info,tb_shop_category中的主键相关联,那第一个问题是什么是外键呢?可以查看这篇文章:mysql中的外键 那这三个外键的作用是什么呢?在创建店铺的时候可以相应地确定店铺的地址,店铺的店铺种类(该店铺应该划分到哪一类下面),店铺的创建者(只能让创建者看到自己创建的店铺,别人创建的店铺看不到)。

  • tb_shop_category:店铺种类信息,主键为shop_category_id,表结构如下所示:

    美高梅4858官方网站 4

    tb_shop_category的表结构

当parent_id为null时,表示店铺为一级店铺类别;当parent_id等于shop_category_id时,表明它是一级店铺类别下的二级店铺类别

2.2 内容分类管理

Trackingfilebyfolderpattern:migrationsTraceback(mostrecentcalllast):File"/home/pyvip/.pycharm_helpers/pycharm/django_manage.py",line52,inmodulerun_command()File"/home/pyvip/.pycharm_helpers/pycharm/django_manage.py",line46,inrun_commandrun_module(manage_file,None,'__main__',True)File"/usr/lib/python3.6/runpy.py",line205,inrun_modulereturn_run_module_code(code,init_globals,run_name,mod_spec)File"/usr/lib/python3.6/runpy.py",line96,in_run_module_codemod_name,mod_spec,pkg_name,script_name)File"/usr/lib/python3.6/runpy.py",line85,in_run_codeexec(code,run_globals)File"/home/pyvip/project/study/newssite/manage.py",line15,inmoduleexecute_from_command_line(sys.argv)File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/core/management/__init__.py",line381,inexecute_from_command_lineutility.execute()File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/core/management/__init__.py",line375,inexecuteself.fetch_command(subcommand).run_from_argv(self.argv)File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/core/management/base.py",line316,inrun_from_argvself.execute(*args,**cmd_options)File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/core/management/base.py",line353,inexecuteoutput=self.handle(*args,**options)File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/core/management/base.py",line83,inwrappedres=handle_func(*args,**kwargs)File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/core/management/commands/makemigrations.py",line143,inhandleloader.project_state(),File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/db/migrations/loader.py",line322,inproject_statereturnself.graph.make_state(nodes=nodes,at_end=at_end,real_apps=list(self.unmigrated_apps))File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/db/migrations/graph.py",line378,inmake_stateproject_state=self.nodes[node].mutate_state(project_state,preserve=False)File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/db/migrations/migration.py",line87,inmutate_stateoperation.state_forwards(self.app_label,new_state)File"/home/pyvip/.virtualenvs/pro_django/lib/python3.6/site-packages/django/db/migrations/operations/fields.py",line70,instate_forwardsstate.models[app_label,self.model_name_lower].fields.append((self.name,field))KeyError:('news','hot_news')

2.2.3 新增内容

功能分析
提交表单请求的url:/content/save
参数:表单的数据。使用pojo接收TbContent
返回值:TaotaoResult(json数据)
业务逻辑:
1、把TbContent对象属性补全。
2、向tb_content表中插入数据。
3、返回TaotaoResult

//content.jsp中,指定工具栏事件 toolbar:contentListToolbar
...
    <div data-options="region:'center'" style="padding:5px">
            <table class="easyui-datagrid" id="contentList" data-options="toolbar:contentListToolbar,singleSelect:false,collapsible:true,pagination:true,method:'get',pageSize:20,url:'/content/query/list',queryParams:{categoryId:0}">
            <thead>
                <tr>
                    <th data-options="field:'id',width:30">ID</th>
...

var contentListToolbar = [{
    text:'新增',
    iconCls:'icon-add',
    handler:function(){
        var node = $("#contentCategoryTree").tree("getSelected");
        if(!node || !$("#contentCategoryTree").tree("isLeaf",node.target)){
            $.messager.alert('提示','新增内容必须选择一个内容分类!');
            return ;
        }
        TT.createWindow({
            url : "/content-add"
        }); 
    }
},{
    text:'编辑',
    iconCls:'icon-edit',
    handler:function(){
...

//content-add.jsp中提交表单
    var contentAddPage  = {
            submitForm : function (){
                if(!$('#contentAddForm').form('validate')){
                    $.messager.alert('提示','表单还未填写完成!');
                    return ;
                }
                contentAddEditor.sync();

                $.post("/content/save",$("#contentAddForm").serialize(), function(data){
                    if(data.status == 200){
                        $.messager.alert('提示','新增内容成功!');
                        $("#contentList").datagrid("reload");
                        TT.closeCurrentWindow();
                    }
                });
            },

DAO层
使用逆向工程
Service层
创建ContentServiceImpl类,添加addContent方法,参数:TbContent,返回值:TaotaoResult

@Service
public class ContentServiceImpl implements ContentService {
    @Autowired
    private TbContentMapper contentMapper;  
    @Override
    public TaotaoResult addContent(TbContent content) {
        //补全属性
        content.setCreated(new Date());
        content.setUpdated(new Date());
        //插入数据
        contentMapper.insert(content);
        return TaotaoResult.ok();
    }

}

发布服务<dubbo:service interface="com.taotao.content.service.ContentService" ref="contentServiceImpl" timeout="300000"/>
表现层
引用服务<dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" />
创建ContentController

@Controller
public class ContentController {
    @Autowired
    private ContentService contentService;
    @RequestMapping("/content/save")
    @ResponseBody
    public TaotaoResult addContent(TbContent content) {
        TaotaoResult result = contentService.addContent(content);
        return result;
    }
}

美高梅4858官方网站 5

2.2.1 内容分类展示

功能分析
请求的url:/content/category/list
请求的参数:id,当前节点的id(第一次请求是没有参数,需要给默认值“0”)
响应数据:List<EasyUITreeNode>(@ResponseBody)

Json数据。
[{id:1,text:节点名称,state:open(closed)},
{id:2,text:节点名称2,state:open(closed)},
{id:3,text:节点名称3,state:open(closed)}]

<div>
     <ul id="contentCategory" class="easyui-tree"></ul>
</div>
...
<script type="text/javascript">
$(function(){
    $("#contentCategory").tree({
        url : '/content/category/list',
        animate: true,
        method : "GET",
        onContextMenu: function(e,node){
            e.preventDefault();
            $(this).tree('select',node.target);
            $('#contentCategoryMenu').menu('show',{
                left: e.pageX,
                top: e.pageY
            });
        },

业务逻辑:
1、取查询参数id,parentId
2、根据parentId查询tb_content_category,查询子节点列表。
3、得到List<TbContentCategory>
4、把列表转换成List<EasyUITreeNode>
DAO层
使用逆向工程
在common项目中创建返回结构的POJO EasyUITreeNode

public class EasyUITreeNode implements Serializable{
    private long id;
    private String text;
    private String state;
    public long getId() {
        return id;
    }
  ...   
}

Service层
创建ContentCategoryServiceImpl,参数:long parentId,返回值:List<EasyUITreeNode>

@Service
public class ContentCategoryServiceImpl implements ContentCategoryService {

    @Autowired
    private TbContentCategoryMapper contentCategoryMapper;

    @Override
    public List<EasyUITreeNode> getContentCategoryList(long parentId) {
        // 1、取查询参数id,parentId
        // 2、根据parentId查询tb_content_category,查询子节点列表。
        TbContentCategoryExample example = new TbContentCategoryExample();
        //设置查询条件
        Criteria criteria = example.createCriteria();
        criteria.andParentIdEqualTo(parentId);
        //执行查询
        // 3、得到List<TbContentCategory>
        List<TbContentCategory> list = contentCategoryMapper.selectByExample(example);
        // 4、把列表转换成List<EasyUITreeNode>ub
        List<EasyUITreeNode> resultList = new ArrayList<>();
        for (TbContentCategory tbContentCategory : list) {
            EasyUITreeNode node = new EasyUITreeNode();
            node.setId(tbContentCategory.getId());
            node.setText(tbContentCategory.getName());
            node.setState(tbContentCategory.getIsParent()?"closed":"open");
            //添加到列表
            resultList.add(node);
        }
        return resultList;
    }
}

使用dubbo发布服务,注意端口要与common-service项目区分开

    <!-- 配置包扫描器,扫描所有带@Service注解的类 -->
    <context:component-scan base-package="com.taotao.content.service"/>
    <!-- 发布dubbo服务 -->
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="taotao-content" />
    <!-- 注册中心的地址 -->
    <dubbo:registry protocol="zookeeper" address="192.168.25.175:2181" />
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20881" />
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.taotao.content.service.ContentCategoryService" ref="contentCategoryServiceImpl" timeout="300000"/>

表现层
引用服务:taotao-manager-web项目添加依赖taotao-content-interface,在springmvc.xml文件中,添加服务引用<dubbo:reference interface="com.taotao.content.service.ContentCategoryService" id="contentCategoryService" />
创建ContentCategoryController

@Controller
@RequestMapping("/content/category")
public class ContentCategoryController {
    @Autowired
    private ContentCategoryService contentCategoryService;  
    @RequestMapping("/list")
    @ResponseBody
    public List<EasyUITreeNode> getContentCatList(
            @RequestParam(value="id", defaultValue="0") Long parentId) {        
        List<EasyUITreeNode> list = contentCategoryService.getContentCategoryList(parentId);
        return list;
    }
}

除了上面的错误之外,有两个与`tb_banner`和`tb_hotnews`不能执行写操作(即修改添加数据)错误背景:项目时新闻博客网站,使用django mysql通过模型字段创建了:新闻表`tb_news`,轮播图表`tb_banner`,热门新闻表`tb_hotnews`轮播图表和热门新闻表与新闻表是一对一关系这三个表的结构和关系如下图:求助各位大佬帮忙分析一下大概原因和解决方法!

1 商城首页

2 CMS系统实现

1.2 首页展示

一般不直接展示,通过controller forward到jsp上。web.xml中配置首页<welcome-file>index.html</welcome-file>,如果只访问域名不加后缀,系统找不到该文件,将被拦截器拦截

@Controller
public class IndexController {
    @RequestMapping("/index")
    public String showIndex(Model model) {
        return "index";
    }
}

1.1 工程搭建

创建taotao-portal-web工程,web.xml拦截<url-pattern>*.html</url-pattern>,css/js等文件放到webapp下将不被拦截,因此不需要在springmvc.xml中配拦截器

2.2.2 新增节点

功能分析
请求的url:/content/category/list
请求的参数:parentId name
响应的结果: json数据,TaotaoResult,其中包含一个对象,对象有id属性,新生产的内容分类id

<div>
     <ul id="contentCategory" class="easyui-tree">
    </ul>
</div>
<div id="contentCategoryMenu" class="easyui-menu" style="width:120px;" data-options="onClick:menuHandler"> //添加onClick事件
    <div data-options="iconCls:'icon-add',name:'add'">添加</div>    //右击菜单内容
    <div data-options="iconCls:'icon-remove',name:'rename'">重命名</div>
    <div class="menu-sep"></div>
    <div data-options="iconCls:'icon-remove',name:'delete'">删除</div>
</div>
<script type="text/javascript">
$(function(){
    $("#contentCategory").tree({
        url : '/content/category/list',
        animate: true,
        method : "GET",
        onContextMenu: function(e,node){        //右击展示菜单事件,传入事件及该节点
            e.preventDefault();
            $(this).tree('select',node.target);     //当前节点变成选中状态
            $('#contentCategoryMenu').menu('show',{  //菜单的位置
                left: e.pageX,
                top: e.pageY
            });
        },
        onAfterEdit : function(node){       //编辑结束触发事件
            var _tree = $(this);
            if(node.id == 0){
                // 新增节点id为0
                $.post("/content/category/create",{parentId:node.parentId,name:node.text},function(data){
                    if(data.status == 200){  //返回结果中包含status
                        _tree.tree("update",{
                            target : node.target,
                            id : data.data.id
                        });
                    }else{
                        $.messager.alert('提示','创建' node.text ' 分类失败!');
                    }
                });
            }else{
                $.post("/content/category/update",{id:node.id,name:node.text});
            }
        }
    });
});
function menuHandler(item){             //item表示选中哪一项
    var tree = $("#contentCategory");
    var node = tree.tree("getSelected");
    if(item.name === "add"){
        tree.tree('append', {           //{}中内容为新节点定义
            parent: (node?node.target:null),
            data: [{
                text: '新建分类',
                id : 0,
                parentId : node.id
            }]
        }); 
        var _node = tree.tree('find',0);    //找id为0的节点
        tree.tree("select",_node.target).tree('beginEdit',_node.target);    //选中节点,变成可编辑状态
    }else if(item.name === "rename"){
        tree.tree('beginEdit',node.target);
    }else if(item.name === "delete"){
        $.messager.confirm('确认','确定删除名为 ' node.text ' 的分类吗?',function(r){
            if(r){
                $.post("/content/category/delete/",{parentId:node.parentId,id:node.id},function(){
                    tree.tree("remove",node.target);
                }); 
            }
        });
    }
}
</script>

业务逻辑:
1、接收两个参数:parentId、name
2、向tb_content_category表中插入数据。
a) 创建一个TbContentCategory对象
b) 补全TbContentCategory对象的属性
c) 向tb_content_category表中插入数据
3、判断父节点的isparent是否为true,不是true需要改为true。
4、需要主键返回。
5、返回TaotaoResult,其中包装TbContentCategory对象
DAO层
可以使用逆向工程。需要添加主键返回,在TbContentCategoryMapper.xml中,在inser及insertSelctive中添加<selectKey>标签

  <insert id="insert" parameterType="com.taotao.pojo.TbContentCategory" >
    <selectKey keyProperty="id" resultType="long" order="AFTER">
        SELECT LAST_INSERT_ID();
    </selectKey>

Service层
ContentCategoryServiceImpl类添加addContentCategory方法,参数:parentId/name,返回值:TaotaoResult,其中包装TbContentCategory对象

    @Override
    public TaotaoResult addContentCategory(Long parentId, String name) {
        //创建一个pojo对象
        TbContentCategory contentCategory = new TbContentCategory();
        //补全对象的属性
        contentCategory.setParentId(parentId);
        contentCategory.setName(name);
        //状态。可选值:1(正常),2(删除)
        contentCategory.setStatus(1);
        //排序,默认为1
        contentCategory.setSortOrder(1);
        contentCategory.setIsParent(false);
        contentCategory.setCreated(new Date());
        contentCategory.setUpdated(new Date());
        //插入到数据库
        contentCategoryMapper.insert(contentCategory);
        //判断父节点的状态
        TbContentCategory parent = contentCategoryMapper.selectByPrimaryKey(parentId);
        if (!parent.getIsParent()) {
            //如果父节点为叶子节点应该改为父节点
            parent.setIsParent(true);
            //更新父节点
            contentCategoryMapper.updateByPrimaryKey(parent);
        }       
        //返回结果
        return TaotaoResult.ok(contentCategory);
    }

表现层
请求的url:/content/category/create
请求的参数: parentId/name
响应的结果:json数据,TaotaoResult
ContentCategoryController类添加addContentCategory方法

    @RequestMapping("/content/category/create")
    @ResponseBody
    public TaotaoResult addContentCategory(Long parentId, String name) {
        TaotaoResult result = contentCategoryService.addContentCategory(parentId, name);
        return result;
    }

2.1 项目分析

内容信息从数据库中获得,需要一个内容分类表和一个内容表,内容分类表存储树形结构的数据,内容表存储图片/链接/标题/价格/大文本类型。
创建一个内容服务系统

Taotao-content:聚合工程打包方式pom
|--taotao-content-interface jar
|--taotao-content-Service  war

2.2.4 首页轮播图展示

功能分析
只需要动态生成一个json数据,轮播图就可以动态展示,Json数据格式:

[
    {
        "srcB": "http://image.taotao.com/03/03/2015030304360302109345.jpg",
        "height": 240,
        "alt": "",
        "width": 670,
        "src": "http://image.taotao.com/03/03/2015030304360302109345.jpg",
        "widthB": 550,
        "href": "http://sale.jd.com/act/e0FMkuDhJz35CNt.html?cpdad=1DLSUE",
        "heightB": 240
}
]

DAO层
从tb_content表中取数据,根据内容分类id查询列表。可以使用逆向工程。
web项目创建一个pojo转换成页面需要的json数据格式

public class Ad1Node {
    private String srcB;
    private String height;
    private String alt;
    private String width;
    private String src;
    private String widthB;
    private String href;
    private String heightB;
}

Service层
ContentServiceImpl类添加getContentByCid方法,参数:long categoryId,返回值:List<TbContent>。

@Override
    public List<TbContent> getContentList(long cid) {
        //根据cid查询内容列表
        TbContentExample example = new TbContentExample();
        //设置查询条件
        Criteria criteria = example.createCriteria();
        criteria.andCategoryIdEqualTo(cid);
        //执行查询
        List<TbContent> list = contentMapper.selectByExample(example);
        return list;
    }

表现层
Taotao-portal-web中实现,引用服务<dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" />
在resource.properties文件中添加内容

AD1_CATEGORY_ID=89
AD1_WIDTH=670
AD1_WIDTH_B=550
AD1_HEIGHT=240
AD1_HEIGHT_B=240

在首页展示之前,对数据进行处理,然后展示首页,需要在IndexController中实现。

@Controller
public class IndexController {

    @Autowired
    private ContentService contentService;

    @Value("${AD1_CID}")
    private Long AD1_CID;
    @Value("${AD1_HEIGHT}")
    private Integer AD1_HEIGHT;
    @Value("${AD1_WIDTH}")
    private Integer AD1_WIDTH;
    @Value("${AD1_HEIGHT_B}")
    private Integer AD1_HEIGHT_B;
    @Value("${AD1_WIDTH_B}")
    private Integer AD1_WIDTH_B;

    @RequestMapping("/index")
    public String showIndex(Model model) {
        //取轮播图的内容信息
        List<TbContent> contentList = contentService.getContentList(AD1_CID);
        //转换成Ad1NodeList
        List<Ad1Node> ad1List = new ArrayList<>();
        for (TbContent tbContent : contentList) {
            Ad1Node node = new Ad1Node();
            node.setAlt(tbContent.getTitle());
            node.setHeight(AD1_HEIGHT);
            node.setHeightB(AD1_HEIGHT_B);
            node.setWidth(AD1_WIDTH);
            node.setWidthB(AD1_WIDTH_B);
            node.setHref(tbContent.getUrl());
            node.setSrc(tbContent.getPic());
            node.setSrcB(tbContent.getPic2());
            //添加到列表
            ad1List.add(node);
        }
        //把数据传递给页面。
        model.addAttribute("ad1", JsonUtils.objectToJson(ad1List));

        return "index";
    }
}

本文由美高梅4858官方网站发布,转载请注明来源

关键词: 错误 大佬 图表 热门新闻