这个功能要求的是我们选中的条数然后去进行一个复制或者移动到别的一个分类去。
可能是多条一起操作,也可能是一条去操作。
我们选择的数据,移动到比它大的一个分类里面
我们先实现一下效果吧,这个效果主要是在html的一个页面的效果。
先附上显示截图吧,我们复制和移动到的分类这个是从数据库中查出来的。
先附上表结构吧,没有表结构可能理解的不是很清晰
1、新闻表 news 外键c_id
2、新闻类型表 category 主键cid
接下来应该考虑的是移动和复制的分类列表是怎么出来的
我是ajax请求后台传值然后返回json数据去循环数据
这个没什么好说的很好理解
先附上dao层的代码 CategoryDao
package com.msfh.news.dao;
import com.msfh.news.eneity.Category;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface CategoryDao extends PagingAndSortingRepository<Category, Integer>, JpaSpecificationExecutor<Category> {
}
这里可以看得出来dao层里并没有代码,主要是我们继承的接口
service层 CategoryService
package com.msfh.news.service;
import com.msfh.news.dao.CategoryDao;
import com.msfh.news.eneity.Category;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CategoryService {
@Autowired
private CategoryDao categoryDao;
/**
* 查询categroy这个表的所有数据
* @return categroy这个表的所有数据
*/
public Iterable<Category> findAll(){
return categoryDao.findAll();
}
}
controller层
CategoryController
package com.msfh.news.controller;
import com.msfh.news.eneity.Category;
import com.msfh.news.service.CategoryService;
import net.sf.json.JSONObject;
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 javax.servlet.http.HttpServletRequest;
@Controller
@RequestMapping("category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* ajax请求查询categroy表的所有数据
* @return
*/
@RequestMapping("findAll")
@ResponseBody
public Iterable<Category> findAll(){
return categoryService.findAll();
}
}
html Categoryhtml
<table class="table table-hover text-center">
<tr>
<th width="100" style="text-align:left; padding-left:20px;">ID</th>
<th>内容</th>
<th>名称</th>
<th>分类名称</th>
<th>作者</th>
<th>缩略图</th>
<th width="10%">更新时间</th>
<th width="310">操作</th>
</tr>
<tr v-for="ns,key in newss">
<td style="text-align:left; padding-left:20px;">
<input type="checkbox" name="nid" :value="ns.nid" v-model="nids" />
排序: <input type="text" style="width: 33px;" v-model="ns.u_id" @blur="sort(ns.nid,ns.u_id)" />
</td>
<td>{{ns.content}}</td>
<td>{{ns.title}}</td>
<td style="cursor:pointer;"><font color="#00CC99" bgid="56" class='is_show' @click="changeishome(ns.nid,ns.author)">{{ns.author}}</font></td>
<td>{{ns.cname}}</td>
<td><img v-bind:src="ns.images" width="50"/></td>
<td>{{ns.addtime}}</td>
<td><div class="button-group"> <a class="button border-main" v-on:click="doEdit(ns.nid)"><span class="icon-edit"></span> 修改</a> <a class="button border-red" v-on:click="del(ns.nid,key)"><span class="icon-trash-o"></span> 删除</a> </div></td>
</tr>
<tr>
<td style="text-align:left; padding:19px 0;padding-left:20px;">
<input type="checkbox" v-model='checked' v-on:click='checkedAll'> 全选
</td>
<td colspan="7" style="text-align:left;padding-left:20px;">
<a class="button border-red icon-trash-o" style="padding:5px 15px;" v-on:click="deleteAll()"> 删除</a>
<a style="padding:5px 15px; margin:0 10px;" class="button border-blue icon-edit" v-on:click="downloadfile()"> 数据导出</a>
操作:
<select name="ishome" style="padding:5px 15px; border:1px solid #ddd;">
<option value="">首页</option>
<option value="1">是</option>
<option value="0">否</option>
</select>
<select name="isvouch" style="padding:5px 15px; border:1px solid #ddd;" onchange="changeisvouch(this)">
<option value="">推荐</option>
<option value="1">是</option>
<option value="0">否</option>
</select>
<select name="istop" style="padding:5px 15px; border:1px solid #ddd;" onchange="changeistop(this)">
<option value="">置顶</option>
<option value="1">是</option>
<option value="0">否</option>
</select>
移动到:
<select name="movetid" style="padding:5px 15px; border:1px solid #ddd;" @change="changecate()" v-model="cid">
<option value="0">请选择分类</option>
<option v-for="cate in category" :value="cate.cid">{{cate.cname}}</option>
</select>
<select name="movetid" style="padding:5px 15px; border:1px solid #ddd;" @change="changecopy()" v-model="c_id">
<option value="0">请选择复制</option>
<option v-for="cate in category" :value="cate.cid">{{cate.cname}}</option>
</select>
</tr>
<tr><td colspan="8"><div class="pagelist"> 当前第 1 页 总数 11 个 <a href="/fangkuo/admin/list.php?page?page=1">首页</a> <a href="/fangkuo/admin/list.php?page?page=1">上页</a> <a href="/fangkuo/admin/list.php?page?page=1">下页</a> <a href="/fangkuo/admin/list.php?page?page=1">尾页</a> </div></td>
</table>
vue的方法和ajax
var vm = new Vue({
el:"#app",
data:{
newss:[],
title:"",
checked:"",
nids:[],
category:[],
cid:0,
c_id:0,
all: 10, //总页数
cur: 1,//当前页码
totalPage: 0,//当前条数
},
mounted(){
this.showCategory();
},//mounted
methods:{
showCategory:function(){
// alert(1);
$.post("/category/findAll",{},function(data){
//alert(JSON.stringify(data));
var len = data.length;
for(var i=0;i<len;i++){
vm.category.push(data[i]);
}
//alert(JSON.stringify(vm.category));
});
},//showCategory
接下来是复制和移动的一些代码
显示news dao层的代码
NewsDao 这里同样的是继承接口的方法
package com.msfh.news.dao;
import com.msfh.news.eneity.News;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
import java.util.Map;
public interface NewsDao extends PagingAndSortingRepository<News, Integer>, JpaSpecificationExecutor<News> {
}
service层
NewsService
package com.msfh.news.service;
import com.msfh.news.dao.NewsDao;
import com.msfh.news.eneity.News;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class NewsService {
@Autowired
private NewsDao newsDao;
/**
* 向news添加一条数据
*/
public void save(News news){
newsDao.save(news);
System.out.println(news.getNid());
}
}
最后是controller层
这个是重要的我会把每一部分代码分开写
不过以下代码都是controller层的
NewsController
1、第一部分的是移动和复制的代码
/**
* 这个是移动代码
*/
@RequestMapping("findByNidEdit")
@ResponseBody
public JSONObject findByNidEdit(HttpServletRequest request) {
JSONObject data = new JSONObject();
String nids = request.getParameter("nids");
Integer cid = Integer.parseInt(request.getParameter("cid"));
JSONArray jsonArray = JSONArray.fromObject(nids);
for (int i = 0; i < jsonArray.size(); i++) {
News news = newsService.findByNid(jsonArray.getInt(i));
news.setC_id(cid);
newsService.save(news);
}
data.put("success","成功");
data.put("status",1);
return data;
}
移动的很简单
2、接下来是复制的代码,复制的时候我们需要去用到克隆,克隆之后我们需要去复制图片文件,并且我们需要去给复制的这条数据重新给图片名称赋值,而且涉及到了一个重新命名,这里我们调了一个时间戳+随机数的方法来命名
我们随机名称的方法是做的一个静态的方法直接调用就可以
@RequestMapping("newsCopy")
@ResponseBody
public JSONObject newsCopy(HttpServletRequest request) throws CloneNotSupportedException{
JSONObject data = new JSONObject();
String nids = request.getParameter("nids");
Integer cid = Integer.parseInt(request.getParameter("cid"));
JSONArray jsonArray = JSONArray.fromObject(nids);
for (int i = 0; i < jsonArray.size(); i++) {
News news = newsService.findByNid(jsonArray.getInt(i));
//JSONObject jsonObject = JSONObject.fromObject(news);
//jsonObject.discard("nid");
News copy = (News) news.clone();
File f1 = new File("D:\\E\\"+copy.getImages());
// 目标文件
String fileName = generateRandomFilename()+".jpg";
File f2 = new File("D:\\E\\"+fileName);
try {
// 这个 win10系统 大概是 3.50G 的 复制过程 花了 156 秒 == 2 分6 秒
copyFile(f1, f2);
} catch (Exception e) {
e.printStackTrace();
}
copy.setNid(null);
copy.setImages(fileName);
copy.setC_id(cid);
newsService.save(copy);
}
data.put("success","成功");
data.put("status",1);
return data;
}
随机名称
private static byte[] lock = new byte[0];
// 位数,默认是8位
private final static long w = 100000000;
//生成随机文件名,防止上传文件后文件名重复
public static String generateRandomFilename(){
long r = 0;
synchronized (lock) {
r = (long) ((Math.random() + 1) * w);
}
return System.currentTimeMillis() + String.valueOf(r).substring(1);
}
最后是复制文件的一个方法,这里也是写的一个静态方法是直接给复制文件方法写的一个静态方法,也是直接调用传值
就可以搞定。
/**
* 复制文件
*
* @param resource
* @param target
*/
public static void copyFile(File resource, File target) throws Exception {
// 输入流 --> 从一个目标读取数据
// 输出流 --> 向一个目标写入数据
long start = System.currentTimeMillis();
// 文件输入流并进行缓冲
FileInputStream inputStream = new FileInputStream(resource);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
// 文件输出流并进行缓冲
FileOutputStream outputStream = new FileOutputStream(target);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
// 缓冲数组
// 大文件 可将 1024 * 2 改大一些,但是 并不是越大就越快
byte[] bytes = new byte[1024 * 2];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, len);
}
// 刷新输出缓冲流
bufferedOutputStream.flush();
//关闭流
bufferedInputStream.close();
bufferedOutputStream.close();
inputStream.close();
outputStream.close();
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) / 1000 + " s");
}
接下来是html部分
这里是@change方法调用的
移动到:
<select name="movetid" style="padding:5px 15px; border:1px solid #ddd;" @change="changecate()" v-model="cid">
<option value="0">请选择分类</option>
<option v-for="cate in category" :value="cate.cid">{{cate.cname}}</option>
</select>
<select name="movetid" style="padding:5px 15px; border:1px solid #ddd;" @change="changecopy()" v-model="c_id">
<option value="0">请选择复制</option>
<option v-for="cate in category" :value="cate.cid">{{cate.cname}}</option>
</select>
这里是vue的方法
var vm = new Vue({
el:"#app",
data:{
newss:[],
title:"",
checked:"",
nids:[],
category:[],
cid:0,
c_id:0,
all: 10, //总页数
cur: 1,//当前页码
totalPage: 0,//当前条数
},
mounted(){
//this.dataListFn(1);
this.showCategory();
},//mounted
methods:{
changecate:function(){
//alert(JSON.stringify(vm.cid));
$.post("/news/findByNidEdit",{nids:JSON.stringify(vm.nids),cid:vm.cid},function(data){
if(data.status == 1){
alert(data.success);
}
});
},//changecate
changecopy:function(){
$.post("/news/newsCopy",{nids:JSON.stringify(vm.nids),cid:vm.c_id},function(data){
if(data.status == 1){
alert(data.success);
}
});
},//changecope
showCategory:function(){
// alert(1);
$.post("/category/findAll",{},function(data){
//alert(JSON.stringify(data));
var len = data.length;
for(var i=0;i<len;i++){
vm.category.push(data[i]);
}
//alert(JSON.stringify(vm.category));
});
},//showCategory
downloadfile:function(){
window.location.href="/UserExcelDownloads";
},
checkedAll: function() {
var _this = this;
//遍历数组列表
this.newss.forEach(function(ns, index) {
if(_this.nids.indexOf(ns.nid)==-1){//判断某元素是否存在于数组中
//默认选中的数组
_this.nids.push(ns.nid);
}else{//存在则移除
var nkey = _this.nids.indexOf(ns.nid);
_this.nids.splice(nkey,1);
}
});
},
//分页
btnClick: function(data){//页码点击事件
if(data != this.cur){
this.cur = data
}
//根据点击页数请求数据
this.dataListFn(this.cur.toString());
},//btnClick
pageClick: function(){
//根据点击页数请求数据
this.dataListFn(this.cur.toString());
},//pageClick
},//methods
watch: {
'nids': {
handler: function(val, oldVal) {
if (val.length === this.newss.length) {
this.checked = true;
} else {
this.checked = false;
}
},
deep: true
}
},
});
最后放一下实体类的克隆方法
实体需要继承一个接口
package com.msfh.news.eneity;
import javax.persistence.*;
import java.sql.Timestamp;
@Entity(name = "news")
@Table(name = "news")
public class News implements Cloneable{
public News(){
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer nid;
private String title;
private String content;
private java.sql.Timestamp addtime;
private String author;
private Integer u_id;
private Integer c_id;
private String images;
public String getImages() {
return images;
}
public void setImages(String images) {
this.images = images;
}
public Integer getNid() {
return nid;
}
public void setNid(Integer nid) {
this.nid = nid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Timestamp getAddtime() {
return addtime;
}
public void setAddtime(Timestamp addtime) {
this.addtime = addtime;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Integer getU_id() {
return u_id;
}
public void setU_id(Integer u_id) {
this.u_id = u_id;
}
public Integer getC_id() {
return c_id;
}
public void setC_id(Integer c_id) {
this.c_id = c_id;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}