认真敲项目(五) FastDFS&富文本
关键字: 商品分类 SPU SKU 富文本编辑器 FastDFS 图片上传
1. 商品分类
- 需求分析:
- 实现三级商品分类的列表查询
- 首先查询以及分类, 点击查询下级, 查询当前分类下的所有二级分类
- 以同样的方式查询三级分类
- 在查询分级的同时, 更新面包屑导航条
- 表结构分析
- tb_item_cat 商品分类表
- 代码分析
- 后端
- 在tb_item_cat表中通过ParentID查询下级的商品分类
- 前端
- 页面加载的时候就把一级分类查询出来
- 给按钮绑定点击事件, 将当前的实体类传入进去
- 更新面包屑导航
面包屑导航
$scope.grade=1;//默认为1级
//设置级别
$scope.setGrade=function(value){
$scope.grade=value;
}
//读取列表
$scope.selectList=function(p_entity){
if($scope.grade==1){//如果为1级
$scope.entity_1=null;
$scope.entity_2=null;
}
if($scope.grade==2){//如果为2级
$scope.entity_1=p_entity;
$scope.entity_2=null;
}
if($scope.grade==3){//如果为3级
$scope.entity_2=p_entity;
}
$scope.findByParentId(p_entity.id); //查询此级下级列表
}
2. 电商概念及表结构分析
- SPU 和 SKU
- SPU = Standard Product Unit (标准产品单位) 举例:ip7
- SKU=stock keeping unit(库存量单位) 举例: 规格, 颜色
- 表结构 Tb_goods
- tb_goods中关联了
seller_id
category1_id ``category2_id
create_user_id
update_user_id
type_template_id
- tb_goods中关联了
3.商家后台-商品录入[基本功能]
- 需求分析
- 实现表单的提交 包括 商品名称. 副标题, 价格, 包装列表, 售后服务.
- 代码实现
- 后端
- 因为表单中需要在多张表进行保存, 所以需要自定义一个实体类 封装 TbGoods TBGoodsDes List\
- 在进行添加功能的时候, 需要在
service层
将商品的申请状态设置为未申请状态, 还要设置 TBGoodsDes 的goodsid - 在
controller层
需要获取商家的登录名在spring_Security中获取
, 因为添加的商品是所属用户的 - 前端
- input标签进行绑定
4. 商家后台-商品录入[富文本的录入]
使用kindeditor编辑器 步骤:
- 添加js代码, 用于初始化kindeditor
<script type="text/javascript"> var editor; KindEditor.ready(function(K) { editor = K.create('textarea[name="content"]', { allowFileManager : true //是否允许浏览器服务器上传文件 默认值是false }); }); </script>
- 提取kindeditor编辑器的内容[在goodsControler.js总添加方法]
$scope.entity.goodsDesc.introduction=editor.html();
- 清空kindeditor编辑器的内容
editor.html('');//清空富文本编辑器
5. 分布式文件服务器FastDFS
- FastDFS 的原理
- FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。
- Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。
- Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,Storageserver 没有实现自己的文件系统而是利用操作系统 的文件系统来管理文件。可以将storage称为存储服务器。
- 理解: 以集群的方式来存储文件, tracker是实现调度的, storage是存储的. 在上传和下载资源的时候都需要经过tracker的调度, tracker返回给客户端一个地址, 客户通过这个地址去storage去存储或者下载资源
- 最小系统
pom.xml
<dependency>
<groupId>org.csource.fastdfs</groupId>
<artifactId>fastdfs</artifactId>
<version>1.2</version>
</dependency>
fdfs_client.conf
tracker_server=192.168.25.133:22122
java类
// 1、加载配置文件,配置文件中的内容就是 tracker 服务的地址。
ClientGlobal.init("D:/maven_work/fastDFS-demo/src/fdfs_client.conf");
// 2、创建一个 TrackerClient 对象。直接 new 一个。
TrackerClient trackerClient = new TrackerClient();
// 3、使用 TrackerClient 对象创建连接,获得一个 TrackerServer 对象。
TrackerServer trackerServer = trackerClient.getConnection();
// 4、创建一个 StorageServer 的引用,值为 null
StorageServer storageServer = null;
// 5、创建一个 StorageClient 对象,需要两个参数 TrackerServer 对象、StorageServer 的引用
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
// 6、使用 StorageClient 对象上传图片。
//扩展名不带“.”
String[] strings = storageClient.upload_file("D:/pic/benchi.jpg", "jpg",null);
// 7、返回数组。包含组名和图片的路径。
for (String string : strings) {
System.out.println(string);
}
6. 商家后台-商品录入[图片上传]
需求分析
- 在弹出的选项框中点击添加图片, 选择图片, 点击上传, 将图片上传到tranker中, 由tancker 分配 storage 中去存储, 并将地址存储到数据库中. 并进行照片的回显 显示
代码实现
- 后端
- 依赖[添加到 common模块中]
<!-- 文件上传组件 --> <dependency> <groupId>org.csource.fastdfs</groupId> <artifactId>fastdfs</artifactId> </dependency>
- 配置文件
- fdfs_client.conf
# connect timeout in seconds # default value is 30s connect_timeout=30 # network timeout in seconds # default value is 30s network_timeout=60 # the base path to store log files base_path=/home/fastdfs # tracker_server can ocur more than once, and tracker_server format is # "host:port", host can be hostname or ip address tracker_server=192.168.25.133:22122 #standard log level as syslog, case insensitive, value list: ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level=info # if use connection pool # default value is false # since V4.05 use_connection_pool = false # connections whose the idle time exceeds this time will be closed # unit: second # default value is 3600 # since V4.05 connection_pool_max_idle_time = 3600 # if load FastDFS parameters from tracker server # since V4.05 # default value is false load_fdfs_parameters_from_tracker=false # if use storage ID instead of IP address # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # default value is false # since V4.05 use_storage_id = false # specify storage ids filename, can use relative or absolute path # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # since V4.05 storage_ids_filename = storage_ids.conf #HTTP settings http.tracker_server_port=80 #use "#include" directive to include HTTP other settiongs ##include http.conf
application.properties
FILE_SERVER_URL=http://192.168.25.133/
springmvc.xml
<!-- 配置多媒体解析器 -->
<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>
UploadController.java
@RestController
public class UploadController {
@Value("${FILE_SERVER_URL}")
private String FILE_SERVER_URL;//文件服务器地址
@RequestMapping("/upload")
public Result upload( MultipartFile file){
//1、取文件的扩展名
String originalFilename = file.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try {
//2、创建一个 FastDFS 的客户端
FastDFSClient fastDFSClient
= new FastDFSClient("classpath:config/fdfs_client.conf");
//3、执行上传处理
String path = fastDFSClient.uploadFile(file.getBytes(), extName);
//4、拼接返回的 url 和 ip 地址,拼装成完整的 url
String url = FILE_SERVER_URL + path;
return new Result(true,url);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "上传失败");
}
}
}
uploadService.js
//文件上传服务层
app.service("uploadService",function($http){
this.uploadFile=function(){
var formData=new FormData();
formData.append("file",file.files[0]);
return $http({
method:'POST',
url:"../upload.do",
data: formData,
headers: {'Content-Type':undefined},
transformRequest: angular.identity
});
}
});
Goodscontroller.js
$scope.uploadFile=function(){
uploadService.uploadFile().success(function(response) {
if(response.success){//如果上传成功,取出url
$scope.image_entity.url=response.message;//设置文件地址
}else{
alert(response.message);
}
}).error(function() {
alert("上传发生错误");
});
};