FastDFS,Redis,Solr,ActiveMQ核心技术整合四

2023-11-11

02.商品分类选择-分析-前端js_

03.商品分类选择-分析-数据库_

(JJTree渲染过程解析(parent_id为0就是父节点,is_parent为1说明下面有子节点,state1正常2删除。tree组件有ztree,异步控件树每个节点都有id,展开节点向服务端发送请求,请求检索子节点列表,参数当前节点的id,服务端响应json数据,)&)

04.商品分类选择-Service_

05.商品分类选型实现_

(使用@RequestParam获取参数(@RequestParam(name=”id”,defaultValue=”0” )第一次请求不带参数,给一个默认值确保肯定有值)&)

06.图片上传分析及图片服务器配置_

(Socket选项 HTTP服务器(开启虚拟机,选择已移动该虚拟机保留原来网路配置不发生变化,复制重新生成网卡原来配置不生效,如果要使用虚拟机通过设置为NAT模式,并设置子网网段)&高可用的分布式文件系统构建(只有一个工程把图片放在工程目录下,在1000并发的时候到达tomcat集群,通过Nginx转发每一个tomcat部署一个应用程序,通过轮询把请求平均分给不同服务器,为了能够保证在不同服务器都能找到目标图片需要专门有一个分布式文件服务器FastDFS(软件分布式文件系统,允许横向扩容与负载均衡保证高性能与高可用)负责图片存放与http图片访问(http服务器可以使tomcat或者是nginx(用于访问静态资源性能较好)))&Nginx 安装及负载均衡配置&)

07.FastDFS上传图片测试_

(跟踪服务器配置(fastDFS没法从中央仓库获取,通过maven工程导入,)&存储节点配置(创建一个资源文件client.conf 配置fastDFS中央仓库服务器地址,后缀与源数据详情)&上传文件测试&)

08.FastDFSClient的使用_

(加载资源文件中的图片(this.getClass.getResource(“/”).getPath()取完还是绝对路径,使用全路径复制会有隐藏字符需要去除格式即可。不以’/'开头时,默认是从此类所在的包下取资源,以’/'开头时,则是从ClassPath根下获取。)&)

package testpackage;
public class TestMain {
    public static void main(String[] args) {
        System.out.println(TestMain.class.getResource(""));
        System.out.println(TestMain.class.getResource("/"));
    }
}
file:/E:/workspace/Test/bin/testpackage/
file:/E:/workspace/Test/bin/

上面说到的【path以’/'开头时,则是从ClassPath根下获取;】在这里就是相当于bin目录(Eclipse环境下)。

如果我们想在TestMain.java中分别取到1~3.properties文件,该怎么写路径呢?代码如下:

package testpackage;

public class TestMain {

    public static void main(String[] args) {
        // 当前类(class)所在的包目录
        System.out.println(TestMain.class.getResource(""));
        // class path根目录
        System.out.println(TestMain.class.getResource("/"));
        
        // TestMain.class在<bin>/testpackage包中
        // 2.properties  在<bin>/testpackage包中
        System.out.println(TestMain.class.getResource("2.properties"));
        
        // TestMain.class在<bin>/testpackage包中
        // 3.properties  在<bin>/testpackage.subpackage包中
        System.out.println(TestMain.class.getResource("subpackage/3.properties"));
        
        // TestMain.class在<bin>/testpackage包中
        // 1.properties  在bin目录(class根目录)
        System.out.println(TestMain.class.getResource("/1.properties"));
    }
}

※Class.getResource和Class.getResourceAsStream在使用时,路径选择上是一样的。

Class.getClassLoader().getResource(String path)

path不能以’/'开头时;
path是从ClassPath根下获取;

还是先看一下下面这段代码的输出:

package testpackage;
public class TestMain {
    public static void main(String[] args) {
        TestMain t = new TestMain();
        System.out.println(t.getClass());
        System.out.println(t.getClass().getClassLoader());
        System.out.println(t.getClass().getClassLoader().getResource(""));
        System.out.println(t.getClass().getClassLoader().getResource("/"));//null
    }
}

输出结果:

class testpackage.TestMain
sun.misc.Launcher$AppClassLoader@1fb8ee3
file:/E:/workspace/Test/bin/
null

从结果来看【TestMain.class.getResource("/") == t.getClass().getClassLoader().getResource("")】

如果有同样的Project结构

使用Class.getClassLoader().getResource(String path)可以这么写:

package testpackage;

public class TestMain {
    public static void main(String[] args) {
        TestMain t = new TestMain();
        System.out.println(t.getClass().getClassLoader().getResource(""));
        
        System.out.println(t.getClass().getClassLoader().getResource("1.properties"));
        System.out.println(t.getClass().getClassLoader().getResource("testpackage/2.properties"));
        System.out.println(t.getClass().getClassLoader().getResource("testpackage/subpackage/3.properties"));
    }
}

※Class.getClassLoader().getResource和Class.getClassLoader().getResourceAsStream在使用时,路径选择上也是一样的。

09.图片上传功能分析_

10.图片上传功能实现_

(多文件上传1:使用MultipartHttpServletRequest(springMVC需要把commonsi-fileupload两个jar包加到项目中,前端控制器需要配置多媒体解析器MultipartResolver设置默认编码与最大文件大小,通过MultipartFile接收参数,通过@Value加载配置文件的资源,通过Map返回json数据)&单文件上传3:使用MultipartFile结合实体类&通过IOC容器注入Properties类型&placeholder属性&)

11.上传图片功能测试_

12.解决上传图片浏览器兼容性问题_

(使用jackson在服务端将JSON字符串转换成各种Java数据类型(SpringMvc会把对象转为字符串响应浏览器,直接把Map转为json返回String即可)&)

13.富文本编辑器的使用_

(富文本UEditor(富文本编辑器有UEditor、KindEditor、CKEditor都是纯js开发的)&)

14.商品添加功能分析_

15.商品添加-service_

16.商品添加-完成_

02.工程搭建分析_

03.前台系统工程搭建_

(使用URL Rewrite实现网站伪静态(在web.xml中 url-pattern拦截所有*.html 请求网页伪静态,所有url后缀全部改为html,@RequestMapping(“/index”) 通过index.html进行访问。只访问localhost:8080会默认找welcome-file欢迎页index.html 带html后缀去controller匹配)&)

04.首页展示_

05.首页内容管理-数据库分析_

06.内容服务工程搭建_

07.内容分类查询-service_

08.内容分类列表展示_

(@RequestParam注解(与参数名对不上号,使用@RequestParam(“id” ,defaultValue=””)Integer parentId。使用脚本启动服务Maven build clean tomcat7:run )&)

09.内容分类添加-js分析_

10.内容分类添加-mapper_

11.内容分类添加-service_

12.内容分类添加-完成_

13.内容分类修改、删除-作业_

14.内容添加-功能分析_

15.内容添加-service_

16.内容添加-完成_

17.内容编辑、删除_

01.课程计划

(Redis缓存穿透和雪崩(首页并发量最高,每次都查询数据库压力比较大,通过缓存读取内存数据减轻数据库压力,Reids可以把内容持久化到磁盘数据不会丢,内容不会丢失否则瞬时请求会造成数据库雪崩,Redis缓存同步问题)&)

02.首页大广告位实现分析_

 04.首页大广告位实现-表现层_

05.首页大广告-测试_

06.redis的安装及启动_

(gcc的简易用法(编译、参数与连接)(编译环境对c语言编译后为可二进制可执行文件,需要按照gcc编译环境,yum install gcc-c++)&用make进行宏编译&makefile的基本语法与变量&RPM安装(install)&Redis安装和配置(rm -rf * 删除所有安装包 ,rm -rf /user/local/redis* )&Redis客户端命令(tar zxf redis-3.0.0.tar.gz 进行解压缩,C语言编译必须有Makefile文件夹,直接使用make命令编译,编译后进行通过make install进行安装 make install PREFIX=/usr/local/redis到指定目录,进入安装目录的bin文件夹,通过./redis-server启动前端启动模式占用一个终端,通过配置文件cp ~/redis-3.0.0/redis.conf 复制到当前文件夹下,进行后端启动不占端口号,修改daemonize yes即可,通过./redis-server redis.conf 后端启动,通过ps aux|grep redis查看进程判断是否启动。 ./redis-cli默认连接6379端口,客户端通过ping pang检测服务器健康状态,连接其他redis服务 ./redis-cli -h 192.168 -p 6379)&Redis基础配置文件&)

sftp是Secure File Transfer Protocol的缩写,安全文件传送协议。它类似于ftp, 但是它提供一种更为安全的网络的加密方法。

如何进行远程连接,进行文件的上传和下载。

在命令行模式下,输入: 

sftp 用户名@ip地址  eg: sftp lzy@202.206.64.33

sftp>

如果登陆远程机器不是为了上传下载文件,而是要修改远程主机上的某些文件。可以

ssh  lzy@202.206.64.33 (其实sftp就是ssh 的一个程式。)

sftp> get /var/index.php  /home/libai/

这条语句将从远程主机的  /var目录下将 index.php 下载到本地  /home/libai/目录下。
     sftp> put /home/libai/downloads/linuxgl.pdf  /var/
     这条语句将把本地 /home/libai/downloads/目录下的 linuxgl.pdf文件上传至远程主机/var 目录下。

要查看远端机器的一些信息,可以直接使用平时的linux命令

比如:pwd 远端机器的当前路径  cd 改变远端机器的路径 ,ls, rm, mkdir,rmdir 都可以用

要查看本机的一些信息,要在平时的linux命令上,加上l

比如:lpwd 本机当前工作目录  lcd 改变本机的路径, lls ,lrm,lmkdir,lrmdir

要离开sftp,用exit 或quit、 bye 均可。详细情况可以查阅 man  sftp.

如果觉得在命令行模式下不太方便,可以 sudo apt-get install gftp。在图形界面下操作就简便多了。

07.redis常用命令复_

(Redis数据结构常用命令(Redis一共提供5种数据类型,String普通key-value Hash一个key对应一个hash集,LIST集合 set集合 zset有序集合。String数据类型 set添加一个值 set str1 12345 get str1 incr str1自增,decr减1,Hash命令hset添加一个key hset hash1 field1 abc hget hash1 field1,ttl str1查看key的有效期-1永久保存,ttl str2 -2key不存在,正数正在倒计时,expire str1 100设置过期时间为100秒,key *查看数据库有多少key)&Redis数据结构——哈希&Redis数据结构——链表(linked-list)&Redis数据结构——集合&Redis数据结构——有序集合&INCRBY、DECRBY:对整数值执行加法操作和减法操作& HSET:为字段设置值&)

08.Jedis的使用方法_

(使用Jedis客户端操作Redis(Java客户端通过Jedis,每次创建都有一个连接耗费资源,通过redis连接池JedisPool 节约资源,jedis.getResource()获取jedis来操作数据库)&)

09.redis的使用方法_

(单线程与多线程客户端(持久化RDB和AOF默认开启RDB快照(当前时刻数据)定期操作磁盘,AOF保存对数据库操作的命令频繁操作磁盘性能下降,数据完整性高一点,可以同时开启。Redis有可能丢数据,Mysql或者Oracle关系型数据库不会丢数据,Redis不适合保存大数据适合存储小数据(单线程的顺次处理单个命令尽快完成,通过集群横向扩容),基于Hadoop的Hbase还有MongoDB支持存储海量数据)&)

10.redis集群架构讲解_

(使用Redis集群实现数据水平化存储(Redis集群没有统一的入口,可以连接任何客户端进入集群,集群内部客户端可以相互通讯,检测检点的监控状态通过投票容错实现,redis集群有0-16383个slot为了均匀分布key到不同服务器,每个节点分配一定数量的槽,一般集群分布在3个节点上,每个集群主从同步槽挂了包装高可用,需要6台服务器(一台服务器运行在不同端口6个实例,搭建集群要把dump.rdb快照文件删除,修改redis.conf改变端口号,/cluster-enabled yes集群节点。通过批处理批量执行启动命令 vim start-all.sh cd redis01 ./redis-server redis.conf) cd.. 通过chmod +x start-all.sh增加可执行权限,TCC最大权限 ,./start-all.sh执行)&对文章进行投票&Redis集群容错&Redis集群中的主从复制&Redis主从复制模式&)

11.redis集群搭建01_

(Redis主从架构的缺点&Redis哨兵模式& Redis集群架构& Redis集群环境搭建&mongodump 和mongorestore&批处理和任务&权限设置&)

12.redis集群搭建02_

(RPM、SRPM与YUM&)

13.使用redis-cli连接集群_

14.使用JedisCluster连接集群_

(使用Jedis客户端操作Redis(Java通过JedisCluster连接到集群,自带连接池,构造参数是set类型集合每个元素是HostAndPort类型)&)

15.JedisClient连接单机版_

(使用Annotation注解法创建对象(<context:component-scan base-package=””>注解既包括了开启注解<context:annotation-config>也包括了扫描包)&组件扫描注解&)

16.jedisClient连接集群_

17.向业务逻辑中添加缓存_

18.添加缓存测试_

19.缓存同步处理_

(消息发送和同步接收&HDEL:删除字段&)

day06

01.课程计划_

02.solr服务搭建_

(catalina.sh脚本&Redis基础配置文件&Tomcat启动&复制、删除与移动:cp、rm、mv &配置web.xml文件&)

03.业务域的定义_

(中文分词安装&IK分词器安装&内部类——InnerClasses属性 &基于XML Schema的简化配置方式&使用th:field属性&语言区域&使用服务提供业务逻辑&)

04.业务数据sql语句编写_

05.搜索工程搭建_

(覆盖起步依赖引入的传递依赖&)

06.导入商品数据到索引库-dao_

07.solrj实现索引库维护_

(在Sping Boot中集成Solr,实现数据的增、删、改和查&)

08.导入商品数据-Service_

( constructor方法&)

09.导入商品数据-jsp_

10.商品数据导入成功_

11.首页跳转到搜索页面_

12.商品实现分析_

13.使用solrJ查询索引库_

(Solr——搜索应用服务器&)

14.搜索服务-dao实现_

day07

01.课程计划_

02.商品搜索功能-Service_

03.商品搜索功能-Controller_

04.搜索功能测试_

05.什么是SolrCloud_

06.solr集群架构讲解_

(并发&分片简介&)

07.zookeeper集群讲解_

08.zookeeper集群搭建_

(配置ZooKeeper集群&Data Server简介&修改文件时间或创建新文件:touch&变量的使用与设置:echo、变量设置规则、unset &vim的额外功能&)

09.solr集群的配置_

10.SolrCloud中管理Collection_

11.闲扯_

12.使用SolrJ管理SolrCloud_

13.搜索功能切换到集群_

14.全局异常处理器的应用_

day08

01.课程计划_

02.同步索引库功能分析_

03.什么是ActiveMQ_

04.activemq的安装_

(vim的额外功能&)

05.Activemq发送queue消息_

(Topic 和 Queue&)

06.接收queue消息_

07.发送topic消息_

08.接收topic消息_

09.spring整合Activemq_

(使用JmsTemplate 发送&)

10.使用JMSTemplate发送消息_

11.Activemq整合Spring接收消息_

12.添加商品同步索引库-发送消息_

13.添加商品同步索引库-mapper_

14.添加商品同步索引库-MessageListener_

15.添加商品同步索引库-测试_

16.小结_

day09

01.课程计划_

02.商品详情页面工程搭建_

03.商品详情页面展示分析_

04.商品详情页面展示-代码实现_

05.商品详情页面展示-测试_

06.商品详情页面添加缓存分析_

07.redis添加缓存的使用方法_

08.向业务逻辑中添加缓存_

09.添加缓存测试_

10.freemarker的使用方法_

11.freemarker语法-取pojo的属性_

12.freemarker语法-list_

13.freemarker语法-if_

14.freemarker语法-日期类型处理_

15freemarker语法-null值的处理_

16.freemarker语法-include_

17.freemarker整合Spring_

18.网页静态化方案分析_

19.网页静态化-freemarker模板改造_

20.网页静态化-业务逻辑_

21.网页静态化-测试_

day10

01.课程计划_

(构建HTTP服务器&)

02.什么是nginx_

03.nginx的应用场景_

04.nginx的安装及启动_

( v-pre&)

05.nginx的配置文件介绍_

06.通过端口区分虚拟主机_

(shift&使用fetchType属性设置局部加载策略&ngx_http_upstream_t结构体&)

07.什么是域名及hosts文件的作用_

08.通过域名区分虚拟主机_

09.使用nginx配置反向代理_

(proxy_pass请求代理规则&)

10.使用nginx实现负载均衡_

11.nginx小结_

12.keepalived+nginx实现高可用_

13.lvs实现高并发处理_

14.sso系统分析_

15.sso工程搭建_

16.sso系统接口分析_

day11_单点登录&js跨域

01.课程计划_

02.检查数据是否可用-接口分析_

03.检查数据是否可用-Service_

04.检查数据是否可用-Controller_

05.用户注册-Service_

06.用户注册-表现层_

07.用户登录流程分析_

08.用户登录-Service_

(使用Redis保存token令牌&全局唯一标识符UUID&)

09.用户登录表现层_

10.用户登录测试_

11.根据token查询用户信息-Service_

(使用Redis保存token令牌&)

12.根据token查询用户信息-表现层层_

13.安全退出-作业_

14.登录、注册页面展示_

15.用户注册页面实现_

16.用户登页面实现_

17.js跨域分析_

(跨域AJAX&)

  1. jsonp的原理_

(活用模板方法模式及Callback&callback调用&JSONP&media query语法&)

19.jsonp服务端处理_

20.jsonp处理第二种方法_

day12

01.课程计划_

02.购物车实现分析_

03.购物车工程搭建_

04.商品详情页面加入购物车改造_

05.添加购物车功能分析_

06.添加购物车实现_

07.添加购物车测试_

08.展示购物车列表_

09.修改购物车商品数量_

10.修改购物车商品数量测试_

11.删除购物车商品_

12.购物车小结_

13.订单系统工程搭建_

14.订单确认页面展示_

15.登录拦截器实现分析_

(HandlerInterceptor接口&Handler实例&)

16.拦截器业务逻辑实现_

17.拦截器测试及登录成功回调_

(Interceptor&)

18.拦截器测试取用户信息_

19.订单生成-数据库分析_

20.订单生成-页面分析_

day13

01.课程计划_

02.订单提交-分析回顾_

03.生成订单业务逻辑_

04.订单生成表现层_

05.订单生成-测试_

06.系统架构讲解_

07.系统部署规划_

(安装RPM包&)

08.tomcat热部署_

09.系统部署演示_

10.项目总结01_

11.项目总结02_

12.面试中的问题_

部分代码

taotao-manager-web

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.taotao</groupId>
		<artifactId>taotao-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>com.taotao</groupId>
	<artifactId>taotao-manager-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>com.taotao</groupId>
			<artifactId>taotao-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.taotao</groupId>
			<artifactId>taotao-manager-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.taotao</groupId>
			<artifactId>taotao-content-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.taotao</groupId>
			<artifactId>taotao-search-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
		</dependency>
		<!-- JSP相关 -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- dubbo相关的jar包 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<exclusions>
				<exclusion>
					<artifactId>spring</artifactId>
					<groupId>org.springframework</groupId>
				</exclusion>
				<exclusion>
					<artifactId>netty</artifactId>
					<groupId>org.jboss.netty</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
		</dependency>
		<!-- 添加FastDFS客户端的引用 -->
		<dependency>
			<groupId>fastdfs_client</groupId>
			<artifactId>fastdfs_client</artifactId>
			<version>1.25</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<!-- 文件上传组件 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<configuration>
					<path>/</path>
					<port>8081</port>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>taotao-manager-web</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<!-- post乱码过滤器 -->
	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 前端控制器 -->
	<servlet>
		<servlet-name>taotao-manager-web</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>taotao-manager-web</servlet-name>
		<!-- 拦截所有请求jsp除外 -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
</web-app>

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>管理员登录</title>
</head>
<body style="background-color: #F3F3F3">
    <div class="easyui-dialog" title="管理员登录" data-options="closable:false,draggable:false" style="width:400px;height:300px;padding:10px;">
       	<div style="margin-left: 50px;margin-top: 50px;">
       		<div style="margin-bottom:20px;">
	            <div>
	            	用户名: <input name="username" class="easyui-textbox" data-options="required:true" style="width:200px;height:32px" value="admin"/>
	            </div>
	        </div>
	        <div style="margin-bottom:20px">
	            <div>
	            	密&nbsp;&nbsp;码: <input name="password" class="easyui-textbox" type="password" style="width:200px;height:32px" data-options="" value="admin"/>
	            </div>
	        </div>
	        <div>
	            <a id="login" class="easyui-linkbutton" iconCls="icon-ok" style="width:100px;height:32px;margin-left: 50px">登录</a>
	        </div>
       	</div>
    </div>
    
    <script type="text/javascript">
    	$("#login").click(function(){
    		var username = $("[name=username]").val();
    		var password = $("[name=password]").val();
    		
    		if(username!="admin" || password!="admin"){
    			$.messager.alert('错误',"用户名密码不正确!");
    			return ;
    		}
    		window.location.href="/rest/page/index";
    	});
    </script>
</body>
</html>

item-param-list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<table class="easyui-datagrid" id="itemParamList" title="商品列表" 
       data-options="singleSelect:false,collapsible:true,pagination:true,url:'/item/param/list',method:'get',pageSize:30,toolbar:itemParamListToolbar">
    <thead>
        <tr>
        	<th data-options="field:'ck',checkbox:true"></th>
        	<th data-options="field:'id',width:60">ID</th>
        	<th data-options="field:'itemCatId',width:80">商品类目ID</th>
        	<th data-options="field:'itemCatName',width:100">商品类目</th>
            <th data-options="field:'paramData',width:300,formatter:formatItemParamData">规格(只显示分组名称)</th>
            <th data-options="field:'created',width:130,align:'center',formatter:TAOTAO.formatDateTime">创建日期</th>
            <th data-options="field:'updated',width:130,align:'center',formatter:TAOTAO.formatDateTime">更新日期</th>
        </tr>
    </thead>
</table>
<div id="itemEditWindow" class="easyui-window" title="编辑商品" data-options="modal:true,closed:true,iconCls:'icon-save',href:'/item-edit'" style="width:80%;height:80%;padding:10px;">
</div>
<script>

	function formatItemParamData(value , index){
		var json = JSON.parse(value);
		var array = [];
		$.each(json,function(i,e){
			array.push(e.group);
		});
		return array.join(",");
	}

    function getSelectionsIds(){
    	var itemList = $("#itemParamList");
    	var sels = itemList.datagrid("getSelections");
    	var ids = [];
    	for(var i in sels){
    		ids.push(sels[i].id);
    	}
    	ids = ids.join(",");
    	return ids;
    }
    
    var itemParamListToolbar = [{
        text:'新增',
        iconCls:'icon-add',
        handler:function(){
        	TAOTAO.createWindow({
        		url : "/item-param-add",
        	});
        }
    },{
        text:'编辑',
        iconCls:'icon-edit',
        handler:function(){
        	$.messager.alert('提示','该功能未实现!');
        }
    },{
        text:'删除',
        iconCls:'icon-cancel',
        handler:function(){
        	var ids = getSelectionsIds();
        	if(ids.length == 0){
        		$.messager.alert('提示','未选中商品规格!');
        		return ;
        	}
        	$.messager.confirm('确认','确定删除ID为 '+ids+' 的商品规格吗?',function(r){
        	    if (r){
        	    	var params = {"ids":ids};
                	$.post("/item/param/delete",params, function(data){
            			if(data.status == 200){
            				$.messager.alert('提示','删除商品规格成功!',undefined,function(){
            					$("#itemParamList").datagrid("reload");
            				});
            			}
            		});
        	    }
        	});
        }
    }];
</script>

item-param-add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<table cellpadding="5" style="margin-left: 30px" id="itemParamAddTable" class="itemParam">
	<tr>
		<td>商品类目:</td>
		<td><a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">选择类目</a> 
			<input type="hidden" name="cid" style="width: 280px;"></input>
		</td>
	</tr>
	<tr class="hide addGroupTr">
		<td>规格参数:</td>
		<td>
			<ul>
				<li><a href="javascript:void(0)" class="easyui-linkbutton addGroup">添加分组</a></li>
			</ul>
		</td>
	</tr>
	<tr>
		<td></td>
		<td>
			<a href="javascript:void(0)" class="easyui-linkbutton submit">提交</a>
	    	<a href="javascript:void(0)" class="easyui-linkbutton close">关闭</a>
		</td>
	</tr>
</table>
<div  class="itemParamAddTemplate" style="display: none;">
	<li class="param">
		<ul>
			<li>
				<input class="easyui-textbox" style="width: 150px;" name="group"/>&nbsp;<a href="javascript:void(0)" class="easyui-linkbutton addParam"  title="添加参数" data-options="plain:true,iconCls:'icon-add'"></a>
			</li>
			<li>
				<span>|-------</span><input  style="width: 150px;" class="easyui-textbox" name="param"/>&nbsp;<a href="javascript:void(0)" class="easyui-linkbutton delParam" title="删除" data-options="plain:true,iconCls:'icon-cancel'"></a>						
			</li>
		</ul>
	</li>
</div>
<script style="text/javascript">
	$(function(){
		TAOTAO.initItemCat({
			fun:function(node){
			$(".addGroupTr").hide().find(".param").remove();
				//  判断选择的目录是否已经添加过规格
			  $.getJSON("/item/param/query/itemcatid/" + node.id,function(data){
				  if(data.status == 200 && data.data){
					  $.messager.alert("提示", "该类目已经添加,请选择其他类目。", undefined, function(){
						 $("#itemParamAddTable .selectItemCat").click();
					  });
					  return ;
				  }
				  $(".addGroupTr").show();
			  });
			}
		});
		
		$(".addGroup").click(function(){
			  var temple = $(".itemParamAddTemplate li").eq(0).clone();
			  $(this).parent().parent().append(temple);
			  temple.find(".addParam").click(function(){
				  var li = $(".itemParamAddTemplate li").eq(2).clone();
				  li.find(".delParam").click(function(){
					  $(this).parent().remove();
				  });
				  li.appendTo($(this).parentsUntil("ul").parent());
			  });
			  temple.find(".delParam").click(function(){
				  $(this).parent().remove();
			  });
		 });
		
		$("#itemParamAddTable .close").click(function(){
			$(".panel-tool-close").click();
		});
		
		$("#itemParamAddTable .submit").click(function(){
			var params = [];
			var groups = $("#itemParamAddTable [name=group]");
			groups.each(function(i,e){
				var p = $(e).parentsUntil("ul").parent().find("[name=param]");
				var _ps = [];
				p.each(function(_i,_e){
					var _val = $(_e).siblings("input").val();
					if($.trim(_val).length>0){
						_ps.push(_val);						
					}
				});
				var _val = $(e).siblings("input").val();
				if($.trim(_val).length>0 && _ps.length > 0){
					params.push({
						"group":_val,
						"params":_ps
					});					
				}
			});
			var url = "/item/param/save/"+$("#itemParamAddTable [name=cid]").val();
			$.post(url,{"paramData":JSON.stringify(params)},function(data){
				if(data.status == 200){
					$.messager.alert('提示','新增商品规格成功!',undefined,function(){
						$(".panel-tool-close").click();
    					$("#itemParamList").datagrid("reload");
    				});
				}
			});
		});
	});
</script>

item-list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<table class="easyui-datagrid" id="itemList" title="商品列表" 
       data-options="singleSelect:false,collapsible:true,pagination:true,url:'/item/list',method:'get',pageSize:30,toolbar:toolbar">
    <thead>
        <tr>
        	<th data-options="field:'ck',checkbox:true"></th>
        	<th data-options="field:'id',width:60">商品ID</th>
            <th data-options="field:'title',width:200">商品标题</th>
            <th data-options="field:'cid',width:100">叶子类目</th>
            <th data-options="field:'sellPoint',width:100">卖点</th>
            <th data-options="field:'price',width:70,align:'right',formatter:TAOTAO.formatPrice">价格</th>
            <th data-options="field:'num',width:70,align:'right'">库存数量</th>
            <th data-options="field:'barcode',width:100">条形码</th>
            <th data-options="field:'status',width:60,align:'center',formatter:TAOTAO.formatItemStatus">状态</th>
            <th data-options="field:'created',width:130,align:'center',formatter:TAOTAO.formatDateTime">创建日期</th>
            <th data-options="field:'updated',width:130,align:'center',formatter:TAOTAO.formatDateTime">更新日期</th>
        </tr>
    </thead>
</table>
<div id="itemEditWindow" class="easyui-window" title="编辑商品" data-options="modal:true,closed:true,iconCls:'icon-save',href:'/rest/page/item-edit'" style="width:80%;height:80%;padding:10px;">
</div>
<script>

    function getSelectionsIds(){
    	var itemList = $("#itemList");
    	var sels = itemList.datagrid("getSelections");
    	var ids = [];
    	for(var i in sels){
    		ids.push(sels[i].id);
    	}
    	ids = ids.join(",");
    	return ids;
    }
    
    var toolbar = [{
        text:'新增',
        iconCls:'icon-add',
        handler:function(){
        	$(".tree-title:contains('新增商品')").parent().click();
        }
    },{
        text:'编辑',
        iconCls:'icon-edit',
        handler:function(){
        	var ids = getSelectionsIds();
        	if(ids.length == 0){
        		$.messager.alert('提示','必须选择一个商品才能编辑!');
        		return ;
        	}
        	if(ids.indexOf(',') > 0){
        		$.messager.alert('提示','只能选择一个商品!');
        		return ;
        	}
        	
        	$("#itemEditWindow").window({
        		onLoad :function(){
        			//回显数据
        			var data = $("#itemList").datagrid("getSelections")[0];
        			data.priceView = TAOTAO.formatPrice(data.price);
        			$("#itemeEditForm").form("load",data);
        			
        			// 加载商品描述
        			$.getJSON('/rest/item/query/item/desc/'+data.id,function(_data){
        				if(_data.status == 200){
        					//UM.getEditor('itemeEditDescEditor').setContent(_data.data.itemDesc, false);
        					itemEditEditor.html(_data.data.itemDesc);
        				}
        			});
        			
        			//加载商品规格
        			$.getJSON('/rest/item/param/item/query/'+data.id,function(_data){
        				if(_data && _data.status == 200 && _data.data && _data.data.paramData){
        					$("#itemeEditForm .params").show();
        					$("#itemeEditForm [name=itemParams]").val(_data.data.paramData);
        					$("#itemeEditForm [name=itemParamId]").val(_data.data.id);
        					
        					//回显商品规格
        					 var paramData = JSON.parse(_data.data.paramData);
        					
        					 var html = "<ul>";
        					 for(var i in paramData){
        						 var pd = paramData[i];
        						 html+="<li><table>";
        						 html+="<tr><td colspan=\"2\" class=\"group\">"+pd.group+"</td></tr>";
        						 
        						 for(var j in pd.params){
        							 var ps = pd.params[j];
        							 html+="<tr><td class=\"param\"><span>"+ps.k+"</span>: </td><td><input autocomplete=\"off\" type=\"text\" value='"+ps.v+"'/></td></tr>";
        						 }
        						 
        						 html+="</li></table>";
        					 }
        					 html+= "</ul>";
        					 $("#itemeEditForm .params td").eq(1).html(html);
        				}
        			});
        			
        			TAOTAO.init({
        				"pics" : data.image,
        				"cid" : data.cid,
        				fun:function(node){
        					TAOTAO.changeItemParam(node, "itemeEditForm");
        				}
        			});
        		}
        	}).window("open");
        }
    },{
        text:'删除',
        iconCls:'icon-cancel',
        handler:function(){
        	var ids = getSelectionsIds();
        	if(ids.length == 0){
        		$.messager.alert('提示','未选中商品!');
        		return ;
        	}
        	$.messager.confirm('确认','确定删除ID为 '+ids+' 的商品吗?',function(r){
        	    if (r){
        	    	var params = {"ids":ids};
                	$.post("/rest/item/delete",params, function(data){
            			if(data.status == 200){
            				$.messager.alert('提示','删除商品成功!',undefined,function(){
            					$("#itemList").datagrid("reload");
            				});
            			}
            		});
        	    }
        	});
        }
    },'-',{
        text:'下架',
        iconCls:'icon-remove',
        handler:function(){
        	var ids = getSelectionsIds();
        	if(ids.length == 0){
        		$.messager.alert('提示','未选中商品!');
        		return ;
        	}
        	$.messager.confirm('确认','确定下架ID为 '+ids+' 的商品吗?',function(r){
        	    if (r){
        	    	var params = {"ids":ids};
                	$.post("/rest/item/instock",params, function(data){
            			if(data.status == 200){
            				$.messager.alert('提示','下架商品成功!',undefined,function(){
            					$("#itemList").datagrid("reload");
            				});
            			}
            		});
        	    }
        	});
        }
    },{
        text:'上架',
        iconCls:'icon-remove',
        handler:function(){
        	var ids = getSelectionsIds();
        	if(ids.length == 0){
        		$.messager.alert('提示','未选中商品!');
        		return ;
        	}
        	$.messager.confirm('确认','确定上架ID为 '+ids+' 的商品吗?',function(r){
        	    if (r){
        	    	var params = {"ids":ids};
                	$.post("/rest/item/reshelf",params, function(data){
            			if(data.status == 200){
            				$.messager.alert('提示','上架商品成功!',undefined,function(){
            					$("#itemList").datagrid("reload");
            				});
            			}
            		});
        	    }
        	});
        }
    }];
</script>

item-edit.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>
<div style="padding:10px 10px 10px 10px">
	<form id="itemeEditForm" class="itemForm" method="post">
		<input type="hidden" name="id"/>
	    <table cellpadding="5">
	        <tr>
	            <td>商品类目:</td>
	            <td>
	            	<a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">选择类目</a>
	            	<input type="hidden" name="cid" style="width: 280px;"></input>	
	            </td>
	        </tr>
	        <tr>
	            <td>商品标题:</td>
	            <td><input class="easyui-textbox" type="text" name="title" data-options="required:true" style="width: 280px;"></input></td>
	        </tr>
	        <tr>
	            <td>商品卖点:</td>
	            <td><input class="easyui-textbox" name="sellPoint" data-options="multiline:true,validType:'length[0,150]'" style="height:60px;width: 280px;"></input></td>
	        </tr>
	        <tr>
	            <td>商品价格:</td>
	            <td><input class="easyui-numberbox" type="text" name="priceView" data-options="min:1,max:99999999,precision:2,required:true" />
	            	<input type="hidden" name="price"/>
	            </td>
	        </tr>
	        <tr>
	            <td>库存数量:</td>
	            <td><input class="easyui-numberbox" type="text" name="num" data-options="min:1,max:99999999,precision:0,required:true" /></td>
	        </tr>
	        <tr>
	            <td>条形码:</td>
	            <td>
	                <input class="easyui-textbox" type="text" name="barcode" data-options="validType:'length[1,30]'" />
	            </td>
	        </tr>
	        <tr>
	            <td>商品图片:</td>
	            <td>
	            	<a href="javascript:void(0)" class="easyui-linkbutton picFileUpload">上传图片</a>
	                <input type="hidden" name="image"/>
	            </td>
	        </tr>
	        <tr>
	            <td>商品描述:</td>
	            <td>
	                <textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea>
	            </td>
	        </tr>
	        <tr class="params hide">
	        	<td>商品规格:</td>
	        	<td>
	        		
	        	</td>
	        </tr>
	    </table>
	    <input type="hidden" name="itemParams"/>
	    <input type="hidden" name="itemParamId"/>
	</form>
	<div style="padding:5px">
	    <a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a>
	</div>
</div>
<script type="text/javascript">
	var itemEditEditor ;
	$(function(){
		//实例化编辑器
		itemEditEditor = TAOTAO.createEditor("#itemeEditForm [name=desc]");
	});
	
	function submitForm(){
		if(!$('#itemeEditForm').form('validate')){
			$.messager.alert('提示','表单还未填写完成!');
			return ;
		}
		$("#itemeEditForm [name=price]").val(eval($("#itemeEditForm [name=priceView]").val()) * 1000);
		itemEditEditor.sync();
		
		var paramJson = [];
		$("#itemeEditForm .params li").each(function(i,e){
			var trs = $(e).find("tr");
			var group = trs.eq(0).text();
			var ps = [];
			for(var i = 1;i<trs.length;i++){
				var tr = trs.eq(i);
				ps.push({
					"k" : $.trim(tr.find("td").eq(0).find("span").text()),
					"v" : $.trim(tr.find("input").val())
				});
			}
			paramJson.push({
				"group" : group,
				"params": ps
			});
		});
		paramJson = JSON.stringify(paramJson);
		
		$("#itemeEditForm [name=itemParams]").val(paramJson);
		
		$.post("/rest/item/update",$("#itemeEditForm").serialize(), function(data){
			if(data.status == 200){
				$.messager.alert('提示','修改商品成功!','info',function(){
					$("#itemEditWindow").window('close');
					$("#itemList").datagrid("reload");
				});
			}
		});
	}
</script>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>淘淘商城后台管理系统</title>
<link rel="stylesheet" type="text/css" href="js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<link rel="stylesheet" type="text/css" href="js/jquery-easyui-1.4.1/themes/icon.css" />
<link rel="stylesheet" type="text/css" href="css/taotao.css" />
<script type="text/javascript" src="js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript" src="js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>
<script type="text/javascript" src="js/common.js"></script>
<style type="text/css">
	.content {
		padding: 10px 10px 10px 10px;
	}
</style>
</head>
<body class="easyui-layout">
    <div data-options="region:'west',title:'菜单',split:true" style="width:180px;">
    	<ul id="menu" class="easyui-tree" style="margin-top: 10px;margin-left: 5px;">
         	<li>
         		<span>商品管理</span>
         		<ul>
	         		<li data-options="attributes:{'url':'item-add'}">新增商品</li>
	         		<li data-options="attributes:{'url':'item-list'}">查询商品</li>
	         		<li data-options="attributes:{'url':'item-param-list'}">规格参数</li>
	         	</ul>
         	</li>
         	<li>
         		<span>网站内容管理</span>
         		<ul>
	         		<li data-options="attributes:{'url':'content-category'}">内容分类管理</li>
	         		<li data-options="attributes:{'url':'content'}">内容管理</li>
	         	</ul>
         	</li>
         	<li>
         		<span>索引库管理</span>
         		<ul>
	         		<li data-options="attributes:{'url':'import-index'}">导入索引库</li>
	         	</ul>
         	</li>
         </ul>
    </div>
    <div data-options="region:'center',title:''">
    	<div id="tabs" class="easyui-tabs">
		    <div title="首页" style="padding:20px;">
		        	
		    </div>
		</div>
    </div>
    
<script type="text/javascript">
$(function(){
	$('#menu').tree({
		onClick: function(node){
			if($('#menu').tree("isLeaf",node.target)){
				var tabs = $("#tabs");
				var tab = tabs.tabs("getTab",node.text);
				if(tab){
					tabs.tabs("select",node.text);
				}else{
					tabs.tabs('add',{
					    title:node.text,
					    href: node.attributes.url,
					    closable:true,
					    bodyCls:"content"
					});
				}
			}
		}
	});
});
</script>
</body>
</html>

import-index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<div>
	<a class="easyui-linkbutton" onclick="importIndex()">一键导入商品数据到索引库</a>
</div>
<script type="text/javascript">
function importIndex() {
	$.post("/index/import",function(data){
		if(data.status == 200){
			$.messager.alert('提示','导入索引库成功!!!!');
		}else{
			$.messager.alert('提示','导入索引库失败~~~~~');
		}
	});
}
</script>

file-upload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html lang="en">
<head>
<!-- Force latest IE rendering engine or ChromeFrame if installed -->
<!--[if IE]>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<![endif]-->
<meta charset="utf-8">
<title>jQuery File Upload Demo</title>
<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap styles -->
<link rel="stylesheet" href="/js/file-upload/bootstrap-3.2.0/css/bootstrap.min.css">
<!-- Generic page styles -->
<link rel="stylesheet" href="/js/file-upload/css/style.css">
<!-- blueimp Gallery styles -->
<link rel="stylesheet" href="/js/file-upload/gallery/css/blueimp-gallery.min.css">
<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
<link rel="stylesheet" href="/js/file-upload/css/jquery.fileupload.css">
<link rel="stylesheet" href="/js/file-upload/css/jquery.fileupload-ui.css">
<!-- CSS adjustments for browsers with JavaScript disabled -->
<noscript><link rel="stylesheet" href="/js/file-upload/css/jquery.fileupload-noscript.css"></noscript>
<noscript><link rel="stylesheet" href="/js/file-upload/css/jquery.fileupload-ui-noscript.css"></noscript>
</head>
<body>
<div class="container">
    <form id="fileupload" action="/rest/pic/upload" method="POST" enctype="multipart/form-data">
        <!-- Redirect browsers with JavaScript disabled to the origin page -->
        <noscript><input type="hidden" name="redirect" value="https://blueimp.github.io/jQuery-File-Upload/"></noscript>
        <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
        <div class="row fileupload-buttonbar">
            <div class="col-lg-7">
                <!-- The fileinput-button span is used to style the file input field as button -->
                <span class="btn btn-success fileinput-button">
                    <i class="glyphicon glyphicon-plus"></i>
                    <span>选择文件(多选)</span>
                    <input type="file" name="files" multiple>
                </span>
                <button type="submit" class="btn btn-primary start">
                    <i class="glyphicon glyphicon-upload"></i>
                    <span>开始上传</span>
                </button>
                <button type="reset" class="btn btn-warning cancel">
                    <i class="glyphicon glyphicon-ban-circle"></i>
                    <span>取消上传</span>
                </button>
                <button type="button" class="btn btn-danger delete">
                    <i class="glyphicon glyphicon-trash"></i>
                    <span>删除</span>
                </button> 
                <input type="checkbox" class="toggle" title="全选">
                <!-- The global file processing state -->
                <span class="fileupload-process"></span>
            </div>
            <!-- The global progress state -->
            <div class="col-lg-5 fileupload-progress fade">
                <!-- The global progress bar -->
                <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
                    <div class="progress-bar progress-bar-success" style="width:0%;"></div>
                </div>
                <!-- The extended global progress state -->
                <div class="progress-extended">&nbsp;</div>
            </div>
        </div>
        <!-- The table listing the files available for upload/download -->
        <table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
    </form>
    <br>
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">说明</h3>
        </div>
        <div class="panel-body">
            <ul>
                <li>上传的文件大小限制为:<strong>5 MB</strong>.</li>
                <li>只支持的文件格式为:<strong>JPG, GIF, PNG, BMP </strong>.</li>
            </ul>
        </div>
    </div>
</div>
<!-- The blueimp Gallery widget -->
<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls" data-filter=":even">
    <div class="slides"></div>
    <h3 class="title"></h3>
    <a class="prev">‹</a>
    <a class="next">›</a>
    <a class="close">×</a>
    <a class="play-pause"></a>
    <ol class="indicator"></ol>
</div>
<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-upload fade">
        <td>
            <span class="preview"></span>
        </td>
        <td>
            <p class="name">{%=file.name%}</p>
            <strong class="error text-danger"></strong>
        </td>
        <td>
            <p class="size">Processing...</p>
            <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
        </td>
        <td>
            {% if (!i && !o.options.autoUpload) { %}
                <button class="btn btn-primary start" disabled>
                    <i class="glyphicon glyphicon-upload"></i>
                    <span>开始</span>
                </button>
            {% } %}
            {% if (!i) { %}
                <button class="btn btn-warning cancel">
                    <i class="glyphicon glyphicon-ban-circle"></i>
                    <span>取消</span>
                </button>
            {% } %}
        </td>
    </tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">
        <td>
            <span class="preview">
                {% if (file.url) { %}
                    <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img width="80" height="50" src="{%=file.url%}"></a>
                {% } %}
            </span>
        </td>
        <td>
            <p class="name">
                {% if (file.url) { %}
                    <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.url?'data-gallery':''%}>{%=file.name%}</a>
                {% } else { %}
                    <span>{%=file.name%}</span>
                {% } %}
            </p>
            {% if (file.error) { %}
                <div><span class="label label-danger">Error</span> {%=file.error%}</div>
            {% } %}
        </td>
        <td>
            <span class="size">{%=o.formatFileSize(file.size)%}</span>
        </td>
        <td>
            {% if (file.deleteUrl) { %}
                <button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
                    <i class="glyphicon glyphicon-trash"></i>
                    <span>Delete</span>
                </button>
                <input type="checkbox" name="delete" value="1" class="toggle">
            {% } else { %}
                <button class="btn btn-warning cancel">
                    <i class="glyphicon glyphicon-ban-circle"></i>
                    <span>Cancel</span>
                </button>
            {% } %}
        </td>
    </tr>
{% } %}
</script>
<script src="/js/file-upload/jquery-1.11.1.min.js"></script>
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<script src="/js/file-upload/vendor/jquery.ui.widget.js"></script>
<!-- The Templates plugin is included to render the upload/download listings -->
<script src="/js/file-upload/tmpl.min.js"></script>
<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
<script src="/js/file-upload/load-image.all.min.js"></script>
<!-- The Canvas to Blob plugin is included for image resizing functionality -->
<script src="/js/file-upload/canvas-to-blob.min.js"></script>
<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
<script src="/js/file-upload/bootstrap-3.2.0/js/bootstrap.min.js"></script>
<!-- blueimp Gallery script -->
<script src="/js/file-upload/gallery/js/jquery.blueimp-gallery.min.js"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
<script src="/js/file-upload/jquery.iframe-transport.js"></script>
<!-- The basic File Upload plugin -->
<script src="/js/file-upload/jquery.fileupload.js"></script>
<!-- The File Upload processing plugin -->
<script src="/js/file-upload/jquery.fileupload-process.js"></script>
<!-- The File Upload image preview & resize plugin -->
<script src="/js/file-upload/jquery.fileupload-image.js"></script>
<!-- The File Upload audio preview plugin -->
<script src="/js/file-upload/jquery.fileupload-audio.js"></script>
<!-- The File Upload video preview plugin -->
<script src="/js/file-upload/jquery.fileupload-video.js"></script>
<!-- The File Upload validation plugin -->
<script src="/js/file-upload/jquery.fileupload-validate.js"></script>
<!-- The File Upload user interface plugin -->
<script src="/js/file-upload/jquery.fileupload-ui.js"></script>
<!-- The main application script -->
<script src="/js/file-upload/main.js"></script>
<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->
<!--[if (gte IE 8)&(lt IE 10)]>
<script src="/js/file-upload/cors/jquery.xdr-transport.js"></script>
<![endif]-->
</body> 
</html>

content-category.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<div>
	 <ul id="contentCategory" class="easyui-tree">
    </ul>
</div>
<div id="contentCategoryMenu" class="easyui-menu" style="width:120px;" data-options="onClick:menuHandler">
    <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){
        		// 新增节点
        		$.post("/content/category/create",{parentId:node.parentId,name:node.text},function(data){
        			if(data.status == 200){
        				_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){
	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);
		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/",{id:node.id},function(){
					tree.tree("remove",node.target);
				});	
			}
		});
	}
}
</script>

content.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<div class="easyui-panel" title="Nested Panel" data-options="width:'100%',minHeight:500,noheader:true,border:false" style="padding:10px;">
    <div class="easyui-layout" data-options="fit:true">
        <div data-options="region:'west',split:false" style="width:250px;padding:5px">
            <ul id="contentCategoryTree" class="easyui-tree" data-options="url:'/content/category/list',animate: true,method : 'GET'">
            </ul>
        </div>
        <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>
		            <th data-options="field:'title',width:120">内容标题</th>
		            <th data-options="field:'subTitle',width:100">内容子标题</th>
		            <th data-options="field:'titleDesc',width:120">内容描述</th>
		            <th data-options="field:'url',width:60,align:'center',formatter:TAOTAO.formatUrl">内容连接</th>
		            <th data-options="field:'pic',width:50,align:'center',formatter:TAOTAO.formatUrl">图片</th>
		            <th data-options="field:'pic2',width:50,align:'center',formatter:TAOTAO.formatUrl">图片2</th>
		            <th data-options="field:'created',width:130,align:'center',formatter:TAOTAO.formatDateTime">创建日期</th>
		            <th data-options="field:'updated',width:130,align:'center',formatter:TAOTAO.formatDateTime">更新日期</th>
		        </tr>
		    </thead>
		</table>
        </div>
    </div>
</div>
<script type="text/javascript">
$(function(){
	var tree = $("#contentCategoryTree");
	var datagrid = $("#contentList");
	tree.tree({
		onClick : function(node){
			if(tree.tree("isLeaf",node.target)){
				datagrid.datagrid('reload', {
					categoryId :node.id
		        });
			}
		}
	});
});
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(){
    	var ids = TT.getSelectionsIds("#contentList");
    	if(ids.length == 0){
    		$.messager.alert('提示','必须选择一个内容才能编辑!');
    		return ;
    	}
    	if(ids.indexOf(',') > 0){
    		$.messager.alert('提示','只能选择一个内容!');
    		return ;
    	}
		TT.createWindow({
			url : "/content-edit",
			onLoad : function(){
				var data = $("#contentList").datagrid("getSelections")[0];
				$("#contentEditForm").form("load",data);
				
				// 实现图片
				if(data.pic){
					$("#contentEditForm [name=pic]").after("<a href='"+data.pic+"' target='_blank'><img src='"+data.pic+"' width='80' height='50'/></a>");	
				}
				if(data.pic2){
					$("#contentEditForm [name=pic2]").after("<a href='"+data.pic2+"' target='_blank'><img src='"+data.pic2+"' width='80' height='50'/></a>");					
				}
				
				contentEditEditor.html(data.content);
			}
		});    	
    }
},{
    text:'删除',
    iconCls:'icon-cancel',
    handler:function(){
    	var ids = TT.getSelectionsIds("#contentList");
    	if(ids.length == 0){
    		$.messager.alert('提示','未选中商品!');
    		return ;
    	}
    	$.messager.confirm('确认','确定删除ID为 '+ids+' 的内容吗?',function(r){
    	    if (r){
    	    	var params = {"ids":ids};
            	$.post("/content/delete",params, function(data){
        			if(data.status == 200){
        				$.messager.alert('提示','删除内容成功!',undefined,function(){
        					$("#contentList").datagrid("reload");
        				});
        			}
        		});
    	    }
    	});
    }
}];
</script>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">

	<!-- 加载属性文件 -->
	<context:property-placeholder location="classpath:resource/resource.properties"/>
	<!-- 配置注解驱动 -->
	<mvc:annotation-driven />
	<!-- 视图解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<!-- 配置包扫描器,扫描@Controller注解的类 -->
	<context:component-scan base-package="com.taotao.controller"/>
	<!-- 配置资源映射 -->
	<mvc:resources location="/css/" mapping="/css/**"/>
	<mvc:resources location="/js/" mapping="/js/**"/>
	<!-- 多媒体解析器 -->
	<!-- 配置文件上传解析器 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设定默认编码 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
		<property name="maxUploadSize" value="5242880"></property>
	</bean>
	<!-- 引用dubbo服务 -->
	<dubbo:application name="taotao-manager-web"/>
	<dubbo:registry protocol="zookeeper" address="192.168.25.167:2181"/>	
	<dubbo:reference interface="com.taotao.service.ItemService" id="itemService" />
	<dubbo:reference interface="com.taotao.service.ItemCatService" id="itemCatService" />
	<dubbo:reference interface="com.taotao.content.service.ContentCategoryService" id="contentCategoryService" />
	<dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" />
	<dubbo:reference interface="com.taotao.search.service.SearchItemService" id="searchItemService" />
</beans>      

resource.properties

#\u56fe\u7247\u670d\u52a1\u7684url
IMAGE_SERVER_URL=http://192.168.25.133/

client.conf

tracker_server=192.168.25.133:22122

FastDFSClient.java

package com.taotao.utils;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;

public class FastDFSClient {

	private TrackerClient trackerClient = null;
	private TrackerServer trackerServer = null;
	private StorageServer storageServer = null;
	private StorageClient1 storageClient = null;
	
	public FastDFSClient(String conf) throws Exception {
		if (conf.contains("classpath:")) {
			conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
		}
		ClientGlobal.init(conf);
		trackerClient = new TrackerClient();
		trackerServer = trackerClient.getConnection();
		storageServer = null;
		storageClient = new StorageClient1(trackerServer, storageServer);
	}
	
	/**
	 * 上传文件方法
	 * <p>Title: uploadFile</p>
	 * <p>Description: </p>
	 * @param fileName 文件全路径
	 * @param extName 文件扩展名,不包含(.)
	 * @param metas 文件扩展信息
	 * @return
	 * @throws Exception
	 */
	public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
		String result = storageClient.upload_file1(fileName, extName, metas);
		return result;
	}
	
	public String uploadFile(String fileName) throws Exception {
		return uploadFile(fileName, null, null);
	}
	
	public String uploadFile(String fileName, String extName) throws Exception {
		return uploadFile(fileName, extName, null);
	}
	
	/**
	 * 上传文件方法
	 * <p>Title: uploadFile</p>
	 * <p>Description: </p>
	 * @param fileContent 文件的内容,字节数组
	 * @param extName 文件扩展名
	 * @param metas 文件扩展信息
	 * @return
	 * @throws Exception
	 */
	public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
		
		String result = storageClient.upload_file1(fileContent, extName, metas);
		return result;
	}
	
	public String uploadFile(byte[] fileContent) throws Exception {
		return uploadFile(fileContent, null, null);
	}
	
	public String uploadFile(byte[] fileContent, String extName) throws Exception {
		return uploadFile(fileContent, extName, null);
	}
}

PictureController.java

package com.taotao.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.taotao.common.utils.JsonUtils;
import com.taotao.utils.FastDFSClient;

/**
 * 图片上传controller
 * <p>Title: PictureController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class PictureController {
	
	@Value("${IMAGE_SERVER_URL}")
	private String IMAGE_SERVER_URL;

	@RequestMapping("/pic/upload")
	@ResponseBody
	public String picUpload(MultipartFile uploadFile) {
		try {
			//接收上传的文件
			//取扩展名
			String originalFilename = uploadFile.getOriginalFilename();
			String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
			//上传到图片服务器
			FastDFSClient fastDFSClient = new FastDFSClient("classpath:resource/client.conf");
			String url = fastDFSClient.uploadFile(uploadFile.getBytes(), extName);
			url = IMAGE_SERVER_URL + url;
			//响应上传图片的url
			Map result = new HashMap<>();
			result.put("error", 0);
			result.put("url", url);
			return JsonUtils.objectToJson(result);
		} catch (Exception e) {
			e.printStackTrace();
			Map result = new HashMap<>();
			result.put("error", 1);
			result.put("message", "图片上传失败");
			return JsonUtils.objectToJson(result);
		}
		
	}
}

PageController.java

package com.taotao.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 页面展示Controller
 * <p>Title: PageController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class PageController {

	@RequestMapping("/")
	public String showIndex() {
		return "index";
	}
	
	@RequestMapping("/{page}")
	public String showPage(@PathVariable String page) {
		return page;
	}
	
}

ItemController.java

package com.taotao.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.common.pojo.EasyUIDataGridResult;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.pojo.TbItem;
import com.taotao.service.ItemService;

/**
 * 商品管理Controller
 * <p>Title: ItemController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class ItemController {

	@Autowired
	private ItemService itemService;
	
	@RequestMapping("/item/{itemId}")
	@ResponseBody
	public TbItem getItemById(@PathVariable Long itemId) {
		TbItem tbItem = itemService.getItemById(itemId);
		return tbItem;
	}
	
	@RequestMapping("/item/list")
	@ResponseBody
	public EasyUIDataGridResult getItemList(Integer page, Integer rows) {
		EasyUIDataGridResult result = itemService.getItemList(page, rows);
		return result;
	}
	
	@RequestMapping(value="/item/save", method=RequestMethod.POST)
	@ResponseBody
	public TaotaoResult addItem(TbItem item, String desc) {
		TaotaoResult result = itemService.addItem(item, desc);
		return result;
	}
}

ItemCatController.java

package com.taotao.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.common.pojo.EasyUITreeNode;
import com.taotao.service.ItemCatService;

/**
 * 商品分类管理Controller
 * <p>Title: ItemCatController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class ItemCatController {
	
	@Autowired
	private ItemCatService itemCatService;

	@RequestMapping("/item/cat/list")
	@ResponseBody
	public List<EasyUITreeNode> getItemCatList(@RequestParam(name="id", defaultValue="0")Long parentId) {
		List<EasyUITreeNode> list = itemCatService.getItemCatList(parentId);
		return list;
	}
}
package com.taotao.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.common.pojo.TaotaoResult;
import com.taotao.search.service.SearchItemService;

/**
 * 索引库维护Controller
 * <p>Title: IndexManagerController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class IndexManagerController {
	
	@Autowired
	private SearchItemService searchItemService;

	@RequestMapping("/index/import")
	@ResponseBody
	public TaotaoResult importIndex() {
		TaotaoResult taotaoResult = searchItemService.importItemsToIndex();
		return taotaoResult;
	}
}
package com.taotao.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.common.pojo.TaotaoResult;
import com.taotao.content.service.ContentService;
import com.taotao.pojo.TbContent;

/**
 * 内容管理Controller
 * <p>Title: ContentController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class ContentController {

	@Autowired
	private ContentService contentService;
	
	@RequestMapping("/content/save")
	@ResponseBody
	public TaotaoResult addContent(TbContent content) {
		TaotaoResult result = contentService.addContent(content);
		return result;
	}
}
package com.taotao.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.common.pojo.EasyUITreeNode;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.content.service.ContentCategoryService;

/**
 * 内容分类管理Controller
 * <p>Title: ContentCategoryController</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Controller
public class ContentCategoryController {
	
	@Autowired
	private ContentCategoryService contentCategoryService;

	@RequestMapping("/content/category/list")
	@ResponseBody
	public List<EasyUITreeNode> getContentCategoryList(
			@RequestParam(value="id", defaultValue="0")Long parentId) {
		List<EasyUITreeNode> list = contentCategoryService.getContentCategoryList(parentId);
		return list;
		
	}
	
	@RequestMapping("/content/category/create")
	@ResponseBody
	public TaotaoResult addContentCategory(Long parentId, String name) {
		TaotaoResult result = contentCategoryService.addContentCategory(parentId, name);
		return result;
	}
}

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FastDFS,Redis,Solr,ActiveMQ核心技术整合四 的相关文章

随机推荐

  • Modelling Context and Syntactical Features for Aspect-based Sentiment论文阅读笔记(ACL2020)

    目录 原文翻译 基于方面的情感分析的上下文和句法特征建模 摘要 1 介绍 2 相关工作 3 方法提出 3 1 方面提取 3 1 1 输入表示 3 1 2 词性嵌入 3 1 3 基于依赖关系的嵌入 3 1 4 微调过程 3 2 方面情感分类
  • 算法练习——力扣随笔【LeetCode】【C++】

    文章目录 LeetCode 练习随笔 力扣上的题目和 OJ题目相比不同之处 定义问题 排序问题 统计问题 注意事项 玄学 新 get 1 单调栈 2 滑动窗口 3 auto 应用 c 11 STL 4 sort 内嵌式规则 5 实现无删遍历
  • Python爬虫 如何利用浏览器获取JSON数据,如获取淘宝天猫的评论链接?

    浏览器 Chrome 工具 右键 检查 N 步骤 1 打开淘宝 天猫 2 右键 检查 3 随便点击一个商品进入购买界面 4 点击监控工具 Network Json 5 点击 商品评论 6 下拉到评论翻页处 7 点击 监控工具Clear功能
  • 微信小程序登录获取不到头像和昵称解决办法!

    微信小程序登录获取不到头像和昵称主要原因是 小程序wx getUserProfile接口被收回 大家可以按照文档操作 PS 针对小程序wx getUserProfile接口将被收回后做出的授权调整 小程序文档中提出的调整说明 对于此次变化
  • Tree-String Problem 【CodeForces - 291E】【倍增(LCA)+哈希】

    题目链接 题意 给你N个点的树 树上的边的权值是一个自上往下的字符串 然后我们再给出一个字符串 是模式串 我们现在想知道模式串在树上的出现次数 譬如说样例 我们查找的是aba 它在1 4这条链上出现了2次 在1 5上出现1次 在2 3上出现
  • [Linux]rsync显示进度

    rsync a progress info progress2
  • PCL RANSAC拟合分割多条直线

    目录 一 概述 二 代码实现 三 结果展示 1 原始点云 2 拟合结果 3 分割结果 四 相关链接 一 概述 使用RANSAC算法拟合分割多条直线 输出每一条直线的拟合参数到控制台 并保存直线点云到本地文件夹 二 代码实现 include
  • 简单的局域网实现文件共享

    局域网 网络种类 覆盖范围一般是方圆几千米之内 其具备的安装便捷 成本节约 扩展方便等特点使其在各类办公室内运用广泛 局域网可以实现文件管理 应用软件共享 打印机共享等功能 在使用过程当中 通过维护局域网网络安全 能够有效地保护资料安全 保
  • 行为驱动测试_我如何知道自己是否正在测试行为?

    行为驱动测试 在整个 测试气味 目录中 有迹象表明您可能正在测试您的代码 而不是其行为 即使在最不起眼的单元测试中 首要规则也应该是 使您的代码执行其工作 并查看结果如何 编写代码及其测试的开发人员在为代码的每一行和每个分支进行测试时 常常
  • 2023第十四届蓝桥杯国赛 C/C++ 大学 B 组 (赛后记录)

    2023 第十四届蓝桥杯国赛 C C 大学 B
  • DDR CTRL介绍

    译文 DDR4 Initialization Training and Calibration
  • 正则表达式(一)——基础之匹配字符,数量,边界

    1 概念 1 1 正则表达式概念 正则表达式 又称正规表达式 规则表达式 正规表示法等 英语 Regular Expression 在代码中常简写为regex regexp或RE 计算机科学的一个概念 正则表达式使用单个字符串来描述 匹配一
  • 图形学光照

    图形学光照 一 概述 二 环境光照 三 漫反射光照 四 镜面光照 五 光照公式 六 Demo 一 概述 现实世界的光照是极其复杂的 而且会受到诸多因素的影响 这是我们有限的计算能力所无法模拟的 因此OpenGL的光照使用的是简化的模型 对现
  • MES系统 PHP常见技术

    1 刚开始接触Web需要练习以下知识 编辑表格 修改 删查 https www cnblogs com yuyu1993 p 5598797 html 流程审批 https www cnblogs com ping04 p 7927468
  • 【程序员面试金典】请编写一个方法,返回某集合的所有非空子集。

    题目描述 请编写一个方法 返回某集合的所有非空子集 给定一个int数组A和数组的大小int n 请返回A的所有非空子集 保证A的元素个数小于等于20 且元素互异 各子集内部从大到小排序 子集之间字典逆序排序 见样例 测试样例 123 456
  • 以太坊eip150和eip158

    以太坊网络将在区块号到达2463000时进行一次硬分叉 具体分叉时间将会在中国时间2016年10月18日晚8 9点 可以在 https fork codetract io 看到本次分叉的倒计时网页 作为一个用户 我需要做些什么 下载最新版本
  • 在visio中插入数学公式

    前提 安装 visio 2013 Mathtype 依次点击 插入 对象 弹出对话框 插入对象 在弹出的对话框内点击 Microsoft 公式 3 0 点击 确定 弹出 Mathtype 编辑界面 即可插入公式
  • C#基础知识

    主要用于只是巩固和新接触的人使用 一 什么是C C 是有C C 衍生出来的一种面向对象编程语言 是一种安全的 稳定的 简单的 优雅的一种语言 他是运行于 Net Franmework智商的高级程序设计语言 二 C 第一个程序 Hellow
  • Java复习:IO流

    File类的使用 IO流原理及流的分类 1 I O是Input Output的缩写 I O技术是非常实用的技术 用于 处理设备之间的数据传输 如读 写文件 网络通讯等 2 Java程序中 对于数据的输入 输出操作以 流 stream 的 方
  • FastDFS,Redis,Solr,ActiveMQ核心技术整合四

    02 商品分类选择 分析 前端js 03 商品分类选择 分析 数据库 JJTree渲染过程解析 parent id为0就是父节点 is parent为1说明下面有子节点 state1正常2删除 tree组件有ztree 异步控件树每个节点都