本案例是实现某系统的PropertyStaff表中的个人照片的上传
一、根据ftp服务器搭建文档创建一个新用户
用户为:user1,密码为root,为其共享D盘(后面将图片保存至D盘)
二、 后台
1.在后台上传FtpUtils工具类
代码:
package com.ruoyi.wxapp.utils;
import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.wxapp.config.FtpConfig;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@Component
public class FtpUtils {
/**
* 默认大小 50M
*/
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
/** 此处静态方法不能用注入的方式初始化 否则为null 因为@Atuowire在初始化此对象之后执行 而调用静态方法不会初始化对象*/
static FtpConfig ftpConfig;
@Autowired
FtpConfig ftp;
@PostConstruct
public void init(){
ftpConfig=this.ftp;
}
/**
* @param baseDir 上传的路径 为相对路径
* @param file 要上传到ftp服务器的文件
*/
public static String upLoad(String baseDir, MultipartFile file) throws Exception {
FTPClient ftp = new FTPClient();
try {
/** 1. 检查文件大小和扩展名是否符合要求*/
assertFile(file);
/** 2. 产生新的文件名,目的使得文件名统一为英文字符加数字;fileName包含文件后缀名*/
String fileName=reBuildFileName(file);
/** 3. 连接ftp服务器*/
ftp.connect(ftpConfig.getIp(),ftpConfig.getPort());
ftp.login(ftpConfig.getUsername(),ftpConfig.getPassword());
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
// 不合法时断开连接
ftp.disconnect();
throw new IOException("ftp连接异常,异常码为:"+ftp.getReplyCode());
}
String path=ftpConfig.getUploadPath()+baseDir;
String[] dirs=path.split("/");
ftp.changeWorkingDirectory("/");
/** 4. 判断ftp服务器目录是否存在 不存在则创建*/
for(int i=0; i<dirs.length && dirs != null;i++){
if(! ftp.changeWorkingDirectory(dirs[i])){
if(ftp.makeDirectory(dirs[i])){
if(! ftp.changeWorkingDirectory(dirs[i]))
throw new Exception("打开文件夹"+dirs[i]+"失败");
}else{
throw new Exception("创建文件夹"+dirs[i]+"失败");
}
}
}
/** 5.切换ftp文件操作目录*/
ftp.changeWorkingDirectory(path);
/** 6.上传文件*/
// 设置文件类型,二进制
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
// 设置缓冲区大小
ftp.setBufferSize(3072);
// 上传文件
ftp.storeFile(fileName, file.getInputStream());
// 登出服务器
ftp.logout();
return baseDir+"/"+fileName;
}catch (Exception e){
throw new Exception(e.getMessage(), e);
}finally {
/** 关闭*/
// 判断连接是否存在
if (ftp.isConnected()) {
// 断开连接
ftp.disconnect();
}
}
}
/**
* @description: 从ftp服务器上下载文件到本地
* @param baseDir ftp服务器文件路径 为相对路径 使用数据库中的url路径(ftp存在共享文件夹)
* @param fileName 文件名
* @param localDir web服务器本地存储路径 为相对路径 使用数据库中的url路径
* */
public static boolean downLoad(String localDir,String baseDir,String fileName){
boolean result = false;
String localPath=ftpConfig.getDownPath()+localDir;
String ftpPath=ftpConfig.getUploadPath()+baseDir;
FTPClient ftp = new FTPClient();
OutputStream os = null;
try {
// 连接至服务器,端口默认为21时,可直接通过URL连接
ftp.connect(ftpConfig.getIp(), ftpConfig.getPort());
// 登录服务器
ftp.login(ftpConfig.getUsername(), ftpConfig.getPassword());
// 判断返回码是否合法
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
// 不合法时断开连接
ftp.disconnect();
// 结束程序
return result;
}
// 设置文件操作目录
ftp.changeWorkingDirectory(ftpPath);
// 设置文件类型,二进制
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
// 设置缓冲区大小
ftp.setBufferSize(3072);
// 设置字符编码
ftp.setControlEncoding("UTF-8");
// 构造本地文件夹
File localFilePath = new File(localPath);
if (!localFilePath.exists()) {
localFilePath.mkdirs();
}
// 构造本地文件对象
File localFile = new File(localPath + "/" + fileName);
// 获取文件操作目录下所有文件名称
String[] remoteNames = ftp.listNames();
// 循环比对文件名称,判断是否含有当前要下载的文件名
for (String remoteName : remoteNames) {
if (fileName.equals(remoteName)) {
result = true;
}
}
// 文件名称比对成功时,进入下载流程
if (result) {
// 构造文件输出流
os = new FileOutputStream(localFile);
// 下载文件 写入到输出流中
result = ftp.retrieveFile(fileName, os);
// 关闭输出流
os.close();
}
// 登出服务器
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 判断输出流是否存在
if (null != os) {
// 关闭输出流
os.close();
}
// 判断连接是否存在
if (ftp.isConnected()) {
// 断开连接
ftp.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* @desecription: 删除web服务器本地文件
* @param realFile: web服务器本地文件
* */
public static boolean delrealFile(String realFile){
File file =new File(realFile);
if( file.exists()&&file.isFile()){
if(file.delete()){
//System.out.println("删除成功");
return true;
}else {
System.out.println("删除失败");
return false;
}
}else {
System.out.println("删除"+realFile+"文件不存在或者不是一个文件类型");
return false;
}
}
/**
* @Description: 判断文件大小是否超过50M 以及判断文件扩展名是否是image类型
* */
public static void assertFile(MultipartFile file)throws FileSizeLimitExceededException,InvalidExtensionException{
long size=file.getSize();
if(size>DEFAULT_MAX_SIZE){
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE/1024/1024);
}
String fileName=file.getOriginalFilename();
String extension=getExtension(file);
if(! isAllowedExtension(extension)){
throw new InvalidExtensionException.InvalidImageExtensionException(MimeTypeUtils.IMAGE_EXTENSION, extension,
fileName);
}
}
/**
* 编码文件名
*/
public static final String reBuildFileName(MultipartFile file)
{
String fileName = file.getOriginalFilename();
String extension = getExtension(file);
fileName = IdUtils.fastUUID() + "." + extension;
return fileName;
}
/**
* 获取文件名的后缀
*
* @param file 表单文件
* @return 后缀名
*/
public static final String getExtension(MultipartFile file)
{
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if (StringUtils.isEmpty(extension))
{
extension = MimeTypeUtils.getExtension(file.getContentType());
}
return extension;
}
/**
* 判断MIME类型是否是允许的Image类型
*
* @param extension
* @return
*/
public static final boolean isAllowedExtension(String extension)
{
for (String str : MimeTypeUtils.IMAGE_EXTENSION)
{
if (str.equalsIgnoreCase(extension))
{
return true;
}
}
return false;
}
}
2.在yml文件中进行配置
3.添加配置文件FtpConfig
代码:
package com.ruoyi.wxapp.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
public class FtpConfig {
@Value("${ftpServer.ip}")
String ip;
@Value("${ftpServer.port}")
int port;
@Value("${ftpServer.username}")
String username;
@Value("${ftpServer.password}")
String password;
@Value("${ftpServer.uploadPath}")
String uploadPath;
@Value("${ftpServer.downPath}")
String downPath;
//在Controller中用于第二层与第三层路径的拼接
public static String getPropertyStaffDir(){
return "/propertyStaffImage";
}
}
4.显示接口(共用一个显示接口),用来在前端预览上传图片
代码:
package com.ruoyi.wxapp.common;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.wxapp.config.FtpConfig;
import com.ruoyi.wxapp.utils.FtpUtils;
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 javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
@Controller
@RequestMapping("/common")
public class ImageController {
@Autowired
FtpConfig ftpConfig;
/**
* 从ftp服务器上查找到图片,然后存储到本地,将本地图片转化为字节流,返回到前端,最后删除本地图片
* */
@RequestMapping("/getImage")
public void getImageBinary(@RequestParam(value = "url", required = true) String url,
HttpServletResponse response)throws IOException {
if(! StringUtils.isNotEmpty(url)){
return;
}
//url对应的路径
String urlPath=url.substring(0,url.lastIndexOf("/"));
String fileName = url.substring(url.lastIndexOf("/")+1);
if(FtpUtils.downLoad(urlPath,urlPath,fileName)){
String realFile=ftpConfig.getDownPath()+urlPath+"/"+fileName;
FileInputStream fis = null;
OutputStream os = null;
try {
fis = new FileInputStream(realFile);
os = response.getOutputStream();
int count = 0;
byte[] buffer = new byte[1024 * 3];
while ((count = fis.read(buffer)) != -1) {
os.write(buffer, 0, count);
os.flush();
}
} catch (Exception e) {
System.out.println("读取下载的图片失败!");
e.printStackTrace();
} finally {
try {
fis.close();
os.close();
//关闭流之后才能删除下载的文件
FtpUtils.delrealFile(realFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
System.out.println("下载图片失败");
return;
}
}
}
5. Controller添加方法
代码:
@RequestMapping("/uploadimage")
public AjaxResult uploadPropertyStaffImage(@RequestParam("file") MultipartFile file) throws Exception {
if(!file.isEmpty()){
//此处拼接第三层路径:D:/zhihui/propertyStaffImage/物业人员信息
String baseDir=ftpConfig.getPropertyStaffDir()+ "/" + "物业人员信息";
String url= FtpUtils.upLoad(baseDir,file);
AjaxResult ajaxResult=AjaxResult.success();
ajaxResult.put("url",url);
return ajaxResult;
}
return AjaxResult.error("图片上传失败联系管理员");
}
三、前端
1.上传对话框
<el-form-item label="个人照片" prop="image">
<el-upload
action=""
list-type="picture-card"
accept="image/*"
:limit=1
:file-list="imagelist"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:before-upload="beforeAvatarUpload"
:on-error="imgUploadError"
:on-change="selectImageChange"
:http-request="upload"
class="avatar-uploader"
:class="{ disabled: uploadDisabled }"
:auto-upload="false"
>
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
</el-form-item>
分析
2.添加限制,可解决当上传一个图片后又出现上传框的情况。在method方法上添加computed方法
//只显示一个上传框 返回Boolean值
computed: {
uploadDisabled: function () {
return this.imagelist.length > 0;
},
},
3.添加disable的样式(在最底部)
<style >
.disabled .el-upload--picture-card {
display: none;
}
/*去除upload组件过渡效果*/
.el-upload-list__item {
transition: none !important;
}
</style>
4.添加配置,写在computed方法下即可
async mounted() {
this.VUE_APP_BASE_API = process.env.VUE_APP_BASE_API;
},
作用:
5.一些钩子函数(在methods:中添加下列方法)
methods: {
/** 图片上传失败调用 */
imgUploadError(err, file, fileList) {
this.$message.error("上传图片失败!");
},
/** 文件上传之前调用做一些拦截限制 */
beforeAvatarUpload(file) {
console.log("before");
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("上传图片大小不能超过2MB!");
}
return isLt2M;
},
/** 取消默认上传操作 */
upload() {},
/** 移除图片时调用 */
handleRemove(file, fileList) {
this.imagelist = [];
},
/** 上传表单中预览图片时调用*/
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
/** 选择的图片列表变化时调用(增加) */
async selectImageChange(file, fileList) {
if (fileList.length >= 1 && this.imagelist.length == 0) {
this.imagelist.push(file);
}
this.fd = new FormData();
this.fd.append("file", file.raw); //传文件
console.log("file:"+file.raw);
},
/** table中预览图片 */
previewImg(row) {
this.imgSrc =
//"http://localhost" +
this.VUE_APP_BASE_API +
"/common/getImage?url=" +
row.image;
this.tableDialogVisible = true;
},
6. 显示区域
<el-table-column
label="个人照片"
align="center"
prop="image"
>
<template slot-scope="scope">
<div v-if="scope.row.image != null && scope.row.image != ''">
<el-image
style="width: 80px; height: 100px"
:src="VUE_APP_BASE_API+'/common/getImage?url='+scope.row.image"
@click="previewImg(scope.row)"
fit="cover"
>
</el-image>
<el-dialog :visible.sync="tableDialogVisible">
<img
width="100%"
:src="imgSrc"
alt="点击可预览"
/>
</el-dialog>
</div>
<div v-else>暂未提供</div>
</template>
</el-table-column>
7.在handleUpdate函数中为el-upload标签中的file-list的属性值imagelist数组填充图片url信息用于回显
代码:
var imageurl=this.VUE_APP_BASE_API+"common/getImage?url="+
this.form.image;
//修改图片时的回显
let obj=new Object();
obj.url=imageurl;
this.imagelist.push(obj);
8.在api中添加addImgData函数请求后端的接口
代码:
export function addImgData(data) {
return request({
url: '/wxapp/property_staff/uploadimage',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
data: data // 参数需要是单一的formData形式
})
}
9.在propertystaff对应的index.vue中导入函数,并在导出中填写默认值
10.提交按钮
三、index.vue整体代码(-----之间的代码为添加的新代码)
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<!-- <el-form-item label="物业编号" prop="wyid">
<el-input
v-model="queryParams.wyid"
placeholder="请输入物业编号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item label="姓名" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入姓名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select v-model="queryParams.gender" placeholder="请选择性别" clearable size="small">
<el-option
v-for="dict in genderOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="职位" prop="job">
<el-input
v-model="queryParams.job"
placeholder="请输入职位"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-input
v-model="queryParams.type"
placeholder="请输入类型"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="联系方式" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="请输入联系方式"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="入职时间" prop="creatTime">
<el-date-picker clearable size="small" style="width: 200px"
v-model="queryParams.creatTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择入职时间">
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="用户头像" prop="image">
<el-input
v-model="queryParams.image"
placeholder="请输入用户头像"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item label="备注" prop="comment">
<el-input
v-model="queryParams.comment"
placeholder="请输入备注"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="个人照片" prop="picture">
<el-input
v-model="queryParams.picture"
placeholder="请输入个人照片"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item label="微信号" prop="wxid">
<el-input
v-model="queryParams.wxid"
placeholder="请输入微信号"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="是否删除,删除为1,未删除为0" prop="isDelete">
<el-input
v-model="queryParams.isDelete"
placeholder="请输入是否删除,删除为1,未删除为0"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item>
<el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['wxapp:property_staff:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['wxapp:property_staff:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['wxapp:property_staff:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['wxapp:property_staff:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="property_staffList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="物业编号" align="center" prop="wyid" /> -->
<el-table-column label="姓名" align="center" prop="name" />
<el-table-column label="性别" align="center" prop="gender" :formatter="genderFormat" />
<el-table-column label="职位" align="center" prop="job" />
<el-table-column label="类型" align="center" prop="type" />
<el-table-column label="联系方式" align="center" prop="phone" />
<el-table-column label="入职时间" align="center" prop="creatTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.creatTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="comment" />
<!-- ------------------------------------------------------------------------ -->
<el-table-column
label="个人照片"
align="center"
prop="image"
>
<template slot-scope="scope">
<div v-if="scope.row.image != null && scope.row.image != ''">
<el-image
style="width: 80px; height: 100px"
:src="VUE_APP_BASE_API+'/common/getImage?url='+scope.row.image"
@click="previewImg(scope.row)"
fit="cover"
>
</el-image>
<el-dialog :visible.sync="tableDialogVisible">
<img
width="100%"
:src="imgSrc"
alt="点击可预览"
/>
</el-dialog>
</div>
<div v-else>暂未提供</div>
</template>
</el-table-column>
<!-- ------------------------------------------------------------------------ -->
<el-table-column label="微信号" align="center" prop="wxid" />
<!-- <el-table-column label="是否删除,删除为1,未删除为0" align="center" prop="isDelete" /> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['wxapp:property_staff:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['wxapp:property_staff:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改物业人员信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select v-model="form.gender" placeholder="请选择性别">
<el-option
v-for="dict in genderOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="parseInt(dict.dictValue)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="职位" prop="job">
<el-input v-model="form.job" placeholder="请输入职位" />
</el-form-item>
<el-form-item label="类型" prop="type">
<el-input v-model="form.type" placeholder="请输入类型" />
</el-form-item>
<el-form-item label="联系方式" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系方式" />
</el-form-item>
<el-form-item label="入职时间" prop="creatTime">
<el-date-picker clearable size="small" style="width: 200px"
v-model="form.creatTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择入职时间">
</el-date-picker>
</el-form-item>
<el-form-item label="地址编号" prop="id">
<el-input v-model="form.id" placeholder="请输入地址编号" />
</el-form-item>
<el-form-item label="备注" prop="comment">
<el-input v-model="form.comment" placeholder="请输入备注" />
</el-form-item>
<!-- ------------------------------------------- -->
<el-form-item label="个人照片" prop="image">
<el-upload
action=""
list-type="picture-card"
accept="image/*"
:limit=1
:file-list="imagelist"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:before-upload="beforeAvatarUpload"
:on-error="imgUploadError"
:on-change="selectImageChange"
:http-request="upload"
class="avatar-uploader"
:class="{ disabled: uploadDisabled }"
:auto-upload="false"
>
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
</el-form-item>
<!-- ------------------------------------------------------ -->
<el-form-item label="微信号" prop="wxid">
<el-input v-model="form.wxid" placeholder="请输入微信号" />
</el-form-item>
<!-- <el-form-item label="是否删除,删除为1,未删除为0" prop="isDelete">
<el-input v-model="form.isDelete" placeholder="请输入是否删除,删除为1,未删除为0" />
</el-form-item> -->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listProperty_staff, getProperty_staff, delProperty_staff, addProperty_staff, updateProperty_staff, exportProperty_staff,addImgData } from "@/api/wxapp/property_staff";
export default {
name: "Property_staff",
data() {
return {
// 遮罩层
loading: true,
// 选中数组
// form用于图像显示的数组
// ---------------------------------------
imagelist: [],
// form的图像预览url
dialogImageUrl: "",
// form的图像预览控制
dialogVisible: false,
// table的图像预览url
imgSrc : null,
//table的图像预览控制
tableDialogVisible: false,
//上传图片的对象
fd :null,
// -----------------------------------
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 物业人员信息表格数据
property_staffList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 性别字典
genderOptions: [],
// // 类型字典
// typeOptions: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
wyid: null,
name: null,
gender: null,
job: null,
type: null,
phone: null,
creatTime: null,
// image: null,
comment: null,
picture: null,
wxid: null,
isDelete: null
},
// 表单参数
form: {},
// 表单校验
rules: {
wyid: [
{ required: true, message: "物业编号不能为空", trigger: "blur" }
],
name: [
{ required: true, message: "姓名不能为空", trigger: "blur" }
],
gender: [
{ required: true, message: "性别不能为空", trigger: "change" }
],
job: [
{ required: true, message: "职位不能为空", trigger: "blur" }
],
type: [
{ required: true, message: "类型不能为空", trigger: "change" }
],
phone: [
{ required: true, message: "联系方式不能为空", trigger: "blur" }
],
creatTime: [
{ required: true, message: "入值时间不能为空", trigger: "blur" }
],
id: [
{ required: true, message: "地址编号不能为空", trigger: "blur" }
],
wxid: [
{ required: true, message: "微信号不能为空", trigger: "blur" }
],
isDelete: [
{ required: true, message: "是否删除,删除为1,未删除为0不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
this.getDicts("sys_user_sex").then(response => {
this.genderOptions = response.data;
});
// this.getDicts("db_property_staff_type").then(response => {
// this.typeOptions = response.data;
// });
},
// ----------------------------------------------------
//只显示一个上传框 返回Boolean值
computed: {
uploadDisabled: function () {
return this.imagelist.length > 0;
},
},
async mounted() {
this.VUE_APP_BASE_API = process.env.VUE_APP_BASE_API;
},
// -----------------------------------------------------
methods: {
// ------------------------------------------------
/** 图片上传失败调用 */
imgUploadError(err, file, fileList) {
this.$message.error("上传图片失败!");
},
/** 文件上传之前调用做一些拦截限制 */
beforeAvatarUpload(file) {
console.log("before");
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("上传图片大小不能超过2MB!");
}
return isLt2M;
},
/** 取消默认上传操作 */
upload() {},
/** 移除图片时调用 */
handleRemove(file, fileList) {
this.imagelist = [];
},
/** 上传表单中预览图片时调用*/
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
/** 选择的图片列表变化时调用(增加) */
async selectImageChange(file, fileList) {
if (fileList.length >= 1 && this.imagelist.length == 0) {
this.imagelist.push(file);
}
this.fd = new FormData();
this.fd.append("file", file.raw); //传文件
console.log("file:"+file.raw);
},
/** table中预览图片 */
previewImg(row) {
this.imgSrc =
//"http://localhost" +
this.VUE_APP_BASE_API +
"/common/getImage?url=" +
row.image;
this.tableDialogVisible = true;
},
// ----------------------------------------------------------
/** 查询物业人员信息列表 */
getList() {
this.loading = true;
listProperty_staff(this.queryParams).then(response => {
this.property_staffList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 性别字典翻译
genderFormat(row, column) {
return this.selectDictLabel(this.genderOptions, row.gender);
},
// 类型字典翻译
// typeFormat(row, column) {
// return this.selectDictLabel(this.typeOptions, row.type);
// },
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
wyid: null,
name: null,
gender: null,
job: null,
type: null,
phone: null,
creatTime: null,
updateTime: null,
// image: null,
id: null,
comment: null,
picture: null,
wxid: null,
isDelete: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.wyid)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加物业人员信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const wyid = row.wyid || this.ids
getProperty_staff(wyid).then(response => {
this.form = response.data;
// ------------------------------------------------------
var imageurl=this.VUE_APP_BASE_API+"common/getImage?url="+
this.form.image;
//修改图片时的回显
let obj=new Object();
obj.url=imageurl;
this.imagelist.push(obj);
// ----------------------------------------------------
this.open = true;
this.title = "修改物业人员信息";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(async (valid )=> {
if (valid) {
// ------------------------------------
if (this.fd != null && this.fd != undefined) {
await addImgData(this.fd).then((res)=>{
this.form.image = res.url;
//console.log(this.form.image)
});
}
//----------------------------------
if (this.form.wyid != null) {
updateProperty_staff(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
}
});
} else {
addProperty_staff(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
}
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const wyids = row.wyid || this.ids;
this.$confirm('是否确认删除物业人员信息编号为"' + wyids + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delProperty_staff(wyids);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(function() {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm('是否确认导出所有物业人员信息数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportProperty_staff(queryParams);
}).then(response => {
this.download(response.msg);
}).catch(function() {});
}
}
};
</script>
<style >
/****************************************************************/
.disabled .el-upload--picture-card {
display: none;
}
/*去除upload组件过渡效果*/
.el-upload-list__item {
transition: none !important;
}
</style>