页面样式;
navicat:
后端;
package org.jit.sose.entity.agriculture;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* 建个实体类ArDownload
*/
@Data
@TableName("ar_download")
public class ArDownload {
//id自增长
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
private String name;
private String state;
private Date createdDate;
private Date stateDate;
//@TableField(value = "picture_url")没有特殊情况,一般是可以实现驼峰转下划线识别的
private String pictureUrl;
private String url;
//不是数据库字段,标记不存在
@TableField(exist = false)
private Integer pageSize;
@TableField(exist = false)
private Integer pageNum;
}
package org.jit.sose.controller.agriculture;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import org.jit.sose.entity.agriculture.ArDownload;
import org.jit.sose.service.agriculture.ArDownLoadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("/ArDownLoad")
public class ArDownLoadController {
@Autowired
ArDownLoadService arDownLoadService;
/**
* @Description:获取表所有数据
**/
@RequestMapping("/getAllDownLoad")
public PageInfo<ArDownload> selectDownLoads(@RequestBody String str){
JSONObject obj = JSON.parseObject(str);
Integer pageNum = obj.getInteger("pageNum");
Integer pageSize = obj.getInteger("pageSize");
PageInfo<ArDownload> page = arDownLoadService.selectDownLoads(pageNum,pageSize);
return page;
}
/**
* @Description:根据id新增
**/
@PostMapping("/addDownLoadList")
public String addDownLoadList(@RequestParam(value = "name", required = true) String name,
@RequestParam(value = "pictureUrl", required = true) MultipartFile imgMultipartFile,
@RequestParam(value = "url", required = true) String url)throws Exception{
ArDownload arDownload = new ArDownload();
arDownload.setUrl(url);
arDownload.setName(name);
try{
return arDownLoadService.addDownLoadList(arDownload, imgMultipartFile);
}catch (Exception e){
return "fail";
}
}
/**
* @Description:修改
**/
@PostMapping("/editDownLoadList")
public String editDownLoadList(@RequestParam(value = "id", required = true) Integer id,
@RequestParam(value = "name", required = true) String name,
@RequestParam(value = "pictureUrl", required = false) MultipartFile imgMultipartFile,
@RequestParam(value = "url", required = true) String url) throws Exception{
ArDownload arDownload = new ArDownload();
arDownload.setId(id);
arDownload.setName(name);
arDownload.setUrl(url);
try{
return arDownLoadService.editDownLoadList(arDownload, imgMultipartFile);
}catch (Exception e){
//打印报错信息;因为throws被抛出去后如果遇到报错它会没有报错信息而且很突兀结束debug;
e.printStackTrace();
return "fail";
}
}
/**
* @Description:根据id删除
**/
@PostMapping("/deleteDownLoadList/{id}")
public Integer deleteDownLoadList(@PathVariable Integer id){
return arDownLoadService.deleteDownLoadList(id);
}
}
(1)一般自定义service接口public interface ArDownLoadServic,然后去实现public class ArDownLoadImpl implements ArDownLoadService 即可;
(2)extends IService<ArDownload你的实体类>:因为我想后面调用IService里封装好的一些方法所以需要去继承(目前这里还没用到);
extends ServiceImpl<ArDownLoadMapper你的Mappper, ArDownload你的实体类>:这里继承IService后一定要去实现类里去继承对应已经封装好的实现ServiceImpl ,省得再写实现了;
package org.jit.sose.service.agriculture;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import org.jit.sose.entity.agriculture.ArDownload;
import org.springframework.web.multipart.MultipartFile;
public interface ArDownLoadService extends IService<ArDownload> {
PageInfo<ArDownload> selectDownLoads(Integer pageNum, Integer pageSize);
String addDownLoadList(ArDownload arDownload, MultipartFile imgMultipartFile) throws Exception;
Integer deleteDownLoadList(Integer id);
String editDownLoadList(ArDownload arDownload, MultipartFile imgMultipartFile) throws Exception;
}
这里亮点就是点击上传图片对图片文件的处理;
package org.jit.sose.service.agriculture.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.jit.sose.config.SystemConfig;
import org.jit.sose.entity.agriculture.ArDownload;
import org.jit.sose.mapper.agriculture.ArDownLoadMapper;
import org.jit.sose.service.agriculture.ArDownLoadService;
import org.jit.sose.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
@Service
public class ArDownLoadImpl extends ServiceImpl<ArDownLoadMapper, ArDownload> implements ArDownLoadService {
@Autowired
ArDownLoadMapper arDownLoadMapper;
@Override
public PageInfo<ArDownload> selectDownLoads(Integer pageNum, Integer pageSize){
PageHelper.startPage(pageNum,pageSize);
List<ArDownload> downloadList = new ArrayList<>();
downloadList = arDownLoadMapper.selectDownLoads();
return new PageInfo<>(downloadList);
}
/**
* @Description:根据id新增
**/
public String addDownLoadList(ArDownload arDownload, MultipartFile imgMultipartFile) throws Exception{
if(imgMultipartFile != null){
//判断父目录是否存在,不存在就新建
String parentFolderPath = SystemConfig.SAVE_PATH + File.separator + "ar_download";
File parentFolder = new File(parentFolderPath);
if (!parentFolder.exists()){
parentFolder.mkdir();
}
//获取图片后缀名,并保存到本地
String imgFileSuffix = FileUtil.getFileSuffix(imgMultipartFile.getOriginalFilename());
File imgFile = FileUtil.multipartFileToFile(imgMultipartFile,parentFolderPath + File.separator + Calendar.getInstance().getTimeInMillis() + "." + imgFileSuffix);
//将图片保存到数据库
//这里图片使用的是网络地址非本地地址
//arDownload.setPictureUrl(SystemConfig.VIRTUAL_PREFIX+SystemConfig.VIRTUAL_PATH+"/ar_download/"+imgFile.getName());
arDownload.setPictureUrl(SystemConfig.VIRTUAL_PATH+"/ar_download/"+imgFile.getName());
arDownload.setUrl(arDownload.getUrl());
arDownload.setName(arDownload.getName());
arDownLoadMapper. addDownLoadList(arDownload);
return "success";
}else {
return "no_img";
}
}
/**
* @Description:修改
**/
@Override
public String editDownLoadList(ArDownload arDownload, MultipartFile imgMultipartFile) throws Exception{
//imgMultipartFile不为空,即用户上传了新图片
if (imgMultipartFile != null){
//定义了一个保存图片的父文件夹路径
String parentFolderPath = SystemConfig.SAVE_PATH + File.separator + "ar_download";
//查询数据库中当前arDownload对象对应的图片路径
Integer arDownloadId = arDownload.getId();
ArDownload pictureUrlCheck = arDownLoadMapper.selectById(arDownloadId);
String pictureUrlPath = pictureUrlCheck.getPictureUrl();
//将图片路径中的虚拟路径替换为实际的保存路径
pictureUrlPath = pictureUrlPath.replace(SystemConfig.VIRTUAL_PREFIX+SystemConfig.VIRTUAL_PATH, SystemConfig.SAVE_PATH);
//删除原有的图片文件
FileUtil.deleteTempFile(pictureUrlPath);
//从上传的文件名中获取文件的后缀
String imgFileSuffix = FileUtil.getFileSuffix(imgMultipartFile.getOriginalFilename());
//保存新图片:将MultipartFile对象转换为File对象,并保存到指定的文件夹中;文件名使用了当前时间戳作为前缀,以确保文件名的唯一性
File imgFile = FileUtil.multipartFileToFile(imgMultipartFile,parentFolderPath+File.separator + "_" + Calendar.getInstance().getTimeInMillis()+"."+imgFileSuffix);
//设置arDownload对象的图片路径为新的虚拟路径
// arDownload.setPictureUrl(SystemConfig.VIRTUAL_PREFIX+SystemConfig.VIRTUAL_PATH+"/ar_download/"+imgFile.getName());
arDownload.setPictureUrl(SystemConfig.VIRTUAL_PATH+"/ar_download/"+imgFile.getName());
}
//更新数据库中的arDownload对象
arDownLoadMapper.updateById(arDownload);
return "success";
}
/**
* @Description:根据id删除
**/
@Override
public Integer deleteDownLoadList(Integer id) {
return arDownLoadMapper.deleteDownLoadList(id);
}
}
Impl实现里用了mybatisPlus里封装的Mapper里的selectById方法,这样就不用自己去写mapper方法;
ArDownload pictureUrlCheck = arDownLoadMapper.selectById(arDownloadId);
使用:在你的mapper里加个继承BaseMapper,extends BaseMapper<ArDownload你的实体类>就可以用BaseMapper里的方法;
package org.jit.sose.mapper.agriculture;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jit.sose.entity.agriculture.ArDownload;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface ArDownLoadMapper extends BaseMapper<ArDownload> {
List<ArDownload> selectDownLoads();
Integer deleteDownLoadList(Integer id);
void addDownLoadList(ArDownload arDownload);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jit.sose.mapper.agriculture.ArDownLoadMapper">
<select id="selectDownLoads" resultType="org.jit.sose.entity.agriculture.ArDownload" >
SELECT
id,
name,
picture_url as pictureUrl,
url,
state,
created_date AS createdDate,
state_date AS stateDate
FROM
ar_download
WHERE
state = 'A'
ORDER BY state_date DESC
</select>
<insert id="addDownLoadList" parameterType="org.jit.sose.entity.agriculture.ArDownload">
INSERT INTO ar_download(id, name, picture_url, url)
VALUES (#{id}, #{name}, #{pictureUrl}, #{url})
</insert>
<delete id="deleteDownLoadList" parameterType="org.jit.sose.entity.agriculture.ArDownload">
UPDATE ar_download AS ad
SET ad.state = 'X'
WHERE
id = #{id} AND state = 'A';
</delete>
</mapper>
前端:
<template>
<div class="carouselManage">
<div class="table-board">
<div style="margin:20px 0;">
<el-button type="primary" @click="openAddFileModal">新增</el-button>
</div>
<!-- 表格 -->
<div>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="文件名" width="350"/>
<el-table-column label="图片" width="400">
<template #default="scope">
<img :src="scope.row.pictureUrl" style="height:80px;width:120px">
</template>
</el-table-column>
<el-table-column prop="url" label="链接" width="350"/>
<el-table-column label="操作" width="350">
<template #default="scope">
<el-button size="small" type="primary" @click="openEditFileInfoModal(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="deleteDownLoadList(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="paging">
<el-pagination v-model:currentPage="filterInfo.pageNum" v-model:page-size="filterInfo.pageSize" background layout="prev, pager, next" :total="filterInfo.total" @current-change="filter"/>
</div>
<!-- 新增图片模态框 -->
<el-dialog v-model="addFileModal" title="新增" width="800px">
<div class="input-item">
文件名:<el-input v-model="fileInfo.name" placeholder="请输入文件名" style="width:600px"/>
</div>
<div class="input-item">
图片:<div class="img-uploader" @click="chooseImg">
<div v-if="fileInfo.imgSrc==null" class="text">上传图片</div>
<img v-else :src="fileInfo.imgSrc">
</div>
</div>
<div class="input-item">
链接:<el-input v-model="fileInfo.url" placeholder="请输入链接" style="width:600px"/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="addFileModal = false">关闭</el-button>
<el-button type="primary" @click="addDownLoadList">新增</el-button>
</span>
</template>
</el-dialog>
<!-- 编辑图片信息 -->
<el-dialog v-model="editFileInfoModal" width="800px" title="编辑">
<div class="input-item">
文件名:<el-input v-model="fileInfo.name" placeholder="请输入文件名" style="width:600px"/>
</div>
<div class="input-item">
图片:<div class="img-uploader" @click="chooseImg">
<div v-if="fileInfo.imgSrc==null" class="text">上传图片</div>
<img v-else :src="fileInfo.imgSrc">
</div>
</div>
<div class="input-item">
<div class="txt">链接:</div>
<el-input v-model="fileInfo.url" placeholder="请输入链接" style="width:600px"/>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="editFileInfoModal = false">关闭</el-button>
<el-button type="primary" @click="editDownLoadInfo">修改</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import { ElMessage, ElMessageBox } from 'element-plus'
export default {
data(){
return{
addFileModal:false,
fileInfo:{
id:null,
name:'',
pictureUrl:'',
imgSrc:'',
url:'',
},
tableData:[],
editFileInfoModal:false,
filterInfo:{
pageNum:1,
pageSize:6,
total:1
},
activeName:'all',
firstAuditData:[],
finalAuditData:[],
refuseModal:false,
refuseInfo:{
auditId:null,
reason:null,
otherReason:null,
isFinal:false
}
}
},
created(){
this.filter();
},
methods:{
// 分页查表格所有数据
filter(){
let data = {
pageNum:this.filterInfo.pageNum,
pageSize:this.filterInfo.pageSize,
};
let url = "/ArDownLoad/getAllDownLoad";
this.$request.post(url,data).then(res=>{
this.filterInfo.total = res.obj.total;
for(let item of res.obj.list){
//文件名为空时显示空
if (item.name == null){
item.name = '空'
}
//图片地址为空时设置一个默认图片
if (item.pictureUrl != null){
item.pictureUrl=window.location.origin+'/api/'+item.pictureUrl
}else {
item.pictureUrl = "https://data.alibabagroup.com/ecms-files/1479231421/9631a7c2-a376-4869-931a-10f2839b0aae/Alibaba%20Hangzhou%20Xixi%20Campus%20Park%20B.jpg"
}
//链接为空时显示空
if (item.url == null){
item.url = '空'
}
}
this.tableData = res.obj.list;
console.log("this.tableData----------",this.tableData)
})
},
// 点击新增
openAddFileModal(){
this.resetFileInfo();
this.addFileModal = true;
},
resetFileInfo(){
this.fileInfo.id = null;
this.fileInfo.name = null;
this.fileInfo.pictureUrl = null;
this.fileInfo.imgSrc = null;
this.fileInfo.url = null;
},
//点击上传图片
chooseImg(){
let fileInput = document.createElement("input");//这是动态的在HTML中添加一个元素的方法
fileInput.style.display = "none";
fileInput.type = "file";
fileInput.accept="image/png";
fileInput.onchange = ()=>{
let file = fileInput.files[0];
this.fileInfo.pictureUrl = file;
let fr = new FileReader();//FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件的内容
fr.onload = () =>{
let url = fr.result;
this.fileInfo.imgSrc = url;
fileInput.remove();
}//window.onload是一个事件,在文档加载完成后能立即触发,并且能够为该事件注册事件处理函数。将要对对象或者模块进行操作的代码存放在处理函数中。即:window.onload =function (){//代码};
//读取文件内容
fr.readAsDataURL(file);//readAsDataURL方法会使用base-64进行编码,编码的资料由data字串开始,后面跟随的是MIME type
}
fileInput.click();
},
//新增提交
addDownLoadList(){
if(this.$dataFormat.isEmpty(this.fileInfo.name)||this.$dataFormat.isEmpty(this.fileInfo.imgSrc)||this.$dataFormat.isEmpty(this.fileInfo.url)){
ElMessage({
message: '请先补全信息',
type: 'warning',
})
return;
}
if(this.fileInfo.pictureUrl.type != "image/png" && this.fileInfo.pictureUrl.type != "image/jpeg"){
ElMessage({
message: '封面请使用jpg或png格式图片',
type: 'warning',
})
return;
}
let url = "/ArDownLoad/addDownLoadList";
let data = {
name: this.fileInfo.name,
pictureUrl:this.fileInfo.pictureUrl,
url:this.fileInfo.url
}
this.$request.postForm(url,data).then(res =>{
this.$msg.warning('新增成功!')
this.addFileModal = false;
this.filter();
}).catch(() => {
})
},
// 点击编辑
openEditFileInfoModal(item){
this.resetFileInfo();
this.fileInfo.id = item.id;
this.fileInfo.name = item.name;
this.fileInfo.imgSrc = item.pictureUrl;
this.fileInfo.url = item.url;
this.editFileInfoModal = true;
},
// 编辑弹窗
editDownLoadInfo(){
let url = "/ArDownLoad/editDownLoadList";
let data = {
id:this.fileInfo.id,
name:this.fileInfo.name,
pictureUrl:this.fileInfo.pictureUrl,
url:this.fileInfo.url,
}
this.$request.postForm(url,data).then(res=>{
this.$msg.warning('编辑成功!')
this.editFileInfoModal = false;
this.filter();
}).catch(() => {
})
},
// 删除弹窗
deleteDownLoadList(id){
ElMessageBox.confirm(
'请确认是否删除?',
'警告',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
let url = "/ArDownLoad/deleteDownLoadList/" + id;
this.$request.post(url).then(res=>{
this.$msg.warning('删除成功!')
this.filter();
});
}).catch(() => {
})
},
}
}
</script>
<style lang="less">
.carouselManage{
padding:50px;
.table-board{
width: 100%;
}
.paging{
margin:0 auto;
margin-top:50px;
height:60px;
width:400px;
}
.input-item{
margin:10px 0px;
}
.img-uploader{
width:240px;
height:180px;
border:1px dashed black;
text-align: center;
.text{
margin-top:80px;
}
img{
height:100%;
width:100%;
}
}
.img-uploader:hover{
cursor: pointer;
border:1px dashed red;
color:red;
}
}
</style>