linwenxin 6 mesiacov pred
rodič
commit
f2c87d9205

+ 34 - 0
src/api/app/fileLssued.js

@@ -0,0 +1,34 @@
+import request from '@/utils/request'
+
+// 列表
+export function getList(params) {
+  return request({
+    url: '/worker/comlist/list',
+    method: 'get',
+    params
+  })
+}
+// 上传万能通用列表附件
+export function getComlistSave(params) {
+  return request({
+    url: '/worker/comlist/save',
+    method: 'post',
+    params
+  })
+}
+// 修改状态
+export function getComlistUpdataStatus(params) {
+  return request({
+    url: '/worker/comlist/updateStatus',
+    method: 'post',
+    params
+  })
+}
+// 上传万能通用列表附件
+export function getComlistDelete(params) {
+  return request({
+    url: '/worker/comlist/delete',
+    method: 'post',
+    params
+  })
+}

+ 46 - 0
src/api/universal/universal_list.js

@@ -0,0 +1,46 @@
+import request from '@/utils/request'
+
+// 获取列表
+export function getList(params) {
+  return request({
+    url: '/com/list/list',
+    method: 'get',
+    params
+  })
+}
+
+// 获取下载列表
+export function getDownloadList(params) {
+  return request({
+    url: '/com/list/download/log',
+    method: 'get',
+    params
+  })
+}
+
+// 删除
+export function deleteData(params) {
+  return request({
+    url: '/com/list/delete',
+    method: 'post',
+    params
+  })
+}
+
+// 获取下载列表
+export function exportFile(params) {
+  return request({
+    url: '/com/list/download',
+    method: 'get',
+    params
+  })
+}
+
+// 导入
+export function handleImport(params) {
+  return request({
+    url: '/com/list/yonge',
+    method: 'post',
+    params
+  })
+}

+ 346 - 0
src/components/Common/imageUpload.vue

@@ -0,0 +1,346 @@
+<template>
+  <div>
+    <el-upload
+      class="uploader"
+      :action="oss_url + 'common/upload'"
+      :data="dataObj"
+      :multiple="multiple"
+      name="file"
+      :accept="accept"
+      :show-file-list="false"
+      :on-success="uploadSuccess"
+      :before-upload="beforeUpload"
+    />
+    <div class="images">
+      <div v-for="(item, index) in fileList" :key="index" class="item">
+        <div v-if="item.url" class="img" @mouseover="item.hover = true" @mouseout="item.hover = false">
+          <el-image
+            v-if="checkFileType(item.url) == 'image'"
+            ref="img"
+            :src="imageURL + item.url"
+            :preview-src-list="previewImages"
+            style="width: 120px; height: 120px"
+            fit="cover"
+          />
+          <el-image v-else ref="img" :src="imageURL + item.url" style="width: 120px; height: 120px" fit="cover">
+            <div slot="error" class="image-slot">
+              <img v-if="checkFileType(item.url) == 'word'" class="file" src="@/assets/common/word.png" />
+              <img v-if="checkFileType(item.url) == 'excel'" class="file" src="@/assets/common/excel.png" />
+              <img v-if="checkFileType(item.url) == 'ppt'" class="file" src="@/assets/common/ppt.png" />
+              <img v-if="checkFileType(item.url) == 'pdf'" class="file" src="@/assets/common/pdf.png" />
+              <img v-if="checkFileType(item.url) == 'file'" class="file" src="@/assets/common/zip.jpeg" />
+            </div>
+          </el-image>
+          <div v-show="item.hover" class="mask">
+            <i v-if="checkFileType(item.url) == 'image'" class="el-icon-zoom-in" @click="previewImage(item.url)" />
+            <i class="el-icon-upload2" @click="uploadImage(item.url)" />
+            <i class="el-icon-delete" @click="deleteImage(item.url)" />
+          </div>
+        </div>
+      </div>
+      <div v-if="multiple || (!multiple && fileList.length < 1)" class="add" @click="uploadImage()">
+        <i class="el-icon-plus" />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import request from '@/utils/request'
+import { findElem } from '@/utils/util'
+
+export default {
+  name: 'FileUpload',
+  props: {
+    // 接受上传的文件列表
+    fileList: Array,
+
+    // 接受上传的文件类型
+    fileType: {
+      type: Array,
+      default: () => ['image', 'word', 'excel', 'ppt', 'pdf', 'file']
+    },
+
+    // 是否支持多选文件
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    startRestricting: {
+      type: Boolean,
+      default: false
+    },
+    restrictFilename: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    }
+  },
+  data() {
+    return {
+      imageURL: this.$imageUrl,
+      oss_url: '',
+      aliosstoken: '',
+      dataObj: {},
+      uploadImageUrl: '',
+      waitUploadList: [],
+      fileName: ''
+    }
+  },
+  computed: {
+    isShowFileList: {
+      get: function () {
+        if (this.fileList.length > 0 && this.fileList[0].url) {
+          return true
+        } else {
+          return false
+        }
+      },
+      set: function (newValue) {}
+    },
+    accept() {
+      const imageList = ['.jpg', '.jpeg', '.png']
+      const videoList = ['.mp4']
+      const wordList = ['.doc', '.docx', '.dot', '.wps', '.wpt']
+      const excelList = ['.xls', '.xlsx', '.xlt', '.et', '.ett']
+      const pptList = ['.ppt', '.pptx', '.dps', '.dpt', '.pot', '.pps']
+      const pdfList = ['.pdf']
+      const fileList = ['.zip', '.rar', '.gz', '.apk']
+      let whiteList = []
+      this.fileType.includes('image') && (whiteList = whiteList.concat(imageList))
+      this.fileType.includes('video') && (whiteList = whiteList.concat(videoList))
+      this.fileType.includes('word') && (whiteList = whiteList.concat(wordList))
+      this.fileType.includes('excel') && (whiteList = whiteList.concat(excelList))
+      this.fileType.includes('ppt') && (whiteList = whiteList.concat(pptList))
+      this.fileType.includes('pdf') && (whiteList = whiteList.concat(pdfList))
+      this.fileType.includes('file') && (whiteList = whiteList.concat(fileList))
+      return whiteList.join(',')
+    },
+    previewImages() {
+      const fileList = []
+      if (this.fileList && this.fileList.length > 0) {
+        this.fileList.forEach(item => {
+          if (this.checkFileType(item.url) == 'image') {
+            fileList.push(this.imageURL + item.url)
+          }
+        })
+      }
+      return fileList
+    }
+  },
+  created() {
+    request({
+      url: '/qviKHUYsyN.php/index/getAliOssToken',
+      method: 'get',
+      params: {}
+    }).then(res => {
+      this.aliosstoken = res.data.aliosstoken
+      this.oss_url = res.data.host
+    })
+  },
+  methods: {
+    getUUID() {
+      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+        return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16)
+      })
+    },
+    createName(name) {
+      const date = Date.now()
+      const uuid = this.getUUID()
+      const fileSuffix = name.substring(name.lastIndexOf('.') + 1)
+      return `${date}${uuid}.${fileSuffix}`
+    },
+
+    // 检查文件类型
+    checkFileType(url) {
+      if (!url) return ''
+      const fileSuffix = url.substring(url.lastIndexOf('.') + 1)
+
+      if (['jpg', 'jpeg', 'png'].includes(fileSuffix)) {
+        return 'image'
+      } else if (['doc', 'docx', 'dot', 'wps', 'wpt'].includes(fileSuffix)) {
+        return 'word'
+      } else if (['xls', 'xlsx', 'xlt', 'et', 'ett'].includes(fileSuffix)) {
+        return 'excel'
+      } else if (['ppt', 'pptx', 'dps', 'dpt', 'pot', 'pps'].includes(fileSuffix)) {
+        return 'ppt'
+      } else if (['pdf'].includes(fileSuffix)) {
+        return 'pdf'
+      } else if (['zip', 'rar', 'gz', 'apk'].includes(fileSuffix)) {
+        return 'file'
+      }
+      {
+        return 'pdf'
+      }
+    },
+
+    // 获取oss配置
+    async getOssConfig(fileName) {
+      const result = await new Promise((resolve, reject) => {
+        getOssConfig()
+          .then(res => {
+            const fileKey = this.createName(fileName)
+
+            res.data.name = fileName
+            res.data.key = res.data.dir + fileKey
+
+            resolve(res.data)
+          })
+          .catch(res => {
+            resolve({})
+          })
+      })
+      return result
+    },
+
+    // 预览图片
+    previewImage(url) {
+      const index = findElem(this.fileList, 'url', url)
+      this.$refs.img[index].showViewer = true
+    },
+
+    // 删除图片
+    deleteImage(url) {
+      const index = findElem(this.fileList, 'url', url)
+      this.fileList.splice(index, 1)
+    },
+
+    // 点击上传
+    uploadImage(url) {
+      this.uploadImageUrl = url
+      document.querySelector('.uploader input').click()
+    },
+
+    // 上传文件之前
+    async beforeUpload(file) {
+      const loading = this.$loading({
+        lock: true,
+        text: 'Loading',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+
+      // this.getFileName(file.name);
+      // this.$emit("handleIsFileName", this.fileName);
+      this.dataObj = await this.getOssConfig(this.fileName)
+      console.log(this.dataObj, 'ppp')
+      this.waitUploadList.push(this.dataObj)
+    },
+
+    // 文件上传成功
+    uploadSuccess(res, file) {
+      const loading = this.$loading({
+        lock: true,
+        text: 'Loading',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+
+      if (this.uploadImageUrl) {
+        const index = findElem(this.fileList, 'url', this.uploadImageUrl)
+        this.$set(this.fileList, index, {
+          name: this.dataObj.name,
+          url: this.dataObj.key,
+          hover: false
+        })
+        this.waitUploadList = []
+      } else {
+        this.getFileName(file.name)
+        const index = findElem(this.waitUploadList, 'name', this.fileName)
+
+        this.fileList.push({
+          name: this.waitUploadList[index].name,
+          url: this.waitUploadList[index].key,
+          hover: false
+        })
+
+        this.waitUploadList.splice(index, 1)
+      }
+      this.showFileList = true
+      loading.close()
+    },
+
+    getFileName(name) {
+      const fileName = name.substring(0, name.lastIndexOf('.'))
+      let suffix = name.match(/.[^.]+$/)[0]
+      console.log(suffix, fileName)
+      // 押金申请上传限制
+      this.fileName = name
+      if (this.startRestricting) {
+        // 检查是否存在相应文字,否filterKeywords.length = 0
+        const filterKeywords = this.restrictFilename.filter(k => fileName.includes(k))
+        // filterKeywords = 0 || 'zip', 'rar', 'gz', 'apk' 归为 其他文件
+        if (!filterKeywords.length || suffix.includes('zip', 'rar', 'gz', 'apk')) {
+          this.fileName = `其他文件${suffix}`
+        }
+        // 限制照片/相片名称统一为照片 , restrictFilename[restrictFilename.length-1|restrictFilename.length-1]为照片、相片
+        if (fileName.includes('相片') || fileName.includes('照片')) {
+          this.fileName = `照片${suffix}`
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.images {
+  display: flex;
+  flex-wrap: wrap;
+  .item {
+    margin-right: 20px;
+    .img {
+      width: 120px;
+      height: 120px;
+      border-radius: 5px;
+      overflow: hidden;
+      position: relative;
+      border: 1px dashed #eaeaea;
+      display: flex;
+      .el-image {
+        display: block;
+      }
+      .file {
+        width: 120px;
+        height: 120px;
+        display: block;
+        padding: 30px;
+      }
+      .mask {
+        position: absolute;
+        left: 0;
+        top: 0;
+        width: 120px;
+        height: 120px;
+        background: rgba($color: #000000, $alpha: 0.3);
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        i {
+          font-size: 20px;
+          color: #ffffff;
+          cursor: pointer;
+          margin: 0 8px;
+        }
+      }
+    }
+  }
+  .add {
+    width: 120px;
+    height: 120px;
+    border: 1px dashed #eaeaea;
+    border-radius: 5px;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    i {
+      font-size: 30px;
+      color: #999;
+    }
+  }
+}
+.uploader {
+  height: 0;
+}
+</style>

+ 318 - 0
src/components/Common/imageUploadPhp.vue

@@ -0,0 +1,318 @@
+<template>
+	<div>
+		<el-upload
+			:action="upload_host"
+			:data="dataObj"
+			:multiple="uploadNum > 1?true:false"
+			:show-file-list="false"
+
+			:before-upload="beforeUpload"
+			:on-remove="handleRemove"
+			:on-success="handleUploadSuccess"
+			:on-preview="handlePreview"
+			:disabled="!isDisabled"
+			:class="name"
+			class="avatar-uploader2"
+		>
+		</el-upload>
+		<div class="images">
+		  <div class="item" v-for="(item, index) in fileList" :key="index">
+		    <div class="img" @mouseover="item.hover = true;" @mouseout="item.hover = false;">
+		      <el-image @click.stop="handleClickItem" ref="img" v-if="isImageUrl(item.url)" :src="item.url" :preview-src-list="previewImages()" style="width: 120px; height: 120px" fit="cover"></el-image>
+		      <video v-else :src="item.url" controls style="width: 120px; height: 120px; display: block"></video>
+		      <div class="mask" v-show="item.hover">
+		        <i class="el-icon-zoom-in" @click="previewImage(item.url)" v-if="isImageUrl(item.url)"></i>
+		        <i class="el-icon-zoom-in" @click="previewVideo(item.url)" v-else></i>
+		        <i class="el-icon-upload2" @click="uploadImage(item.url)" v-if="!isDisabled"></i>
+		        <i class="el-icon-delete" @click="deleteImage(item.url)" v-if="!isDisabled"></i>
+		      </div>
+		    </div>
+		  </div>
+		  <div class="add" v-if="fileList.length < uploadNum" @click="uploadImage()"><i class="el-icon-plus"></i></div>
+		</div>
+		<!-- <el-dialog :visible.sync="dialogVisible" :append-to-body="true"><img width="100%" :src="showImage" alt="" /></el-dialog> -->
+	</div>
+</template>
+<script>
+import request from '@/utils/request';
+import { findElem } from '@/utils/util'
+export default {
+	name: 'ImageUploadPhp',
+	props: {
+		isDisabled: Boolean,
+		fileType: String,
+		name: String,
+		// fileList: Array,
+		uploadNum: {
+			type: Number,
+			default: 1,
+		},
+		index: {
+			type: Number,
+			default: 0,
+		},
+	},
+	data() {
+		return {
+			dataObj: {
+				policy: '',
+				signature: '',
+				key: '',
+				ossaccessKeyId: '',
+			},
+			aliosstoken: '',
+			upload_host: '',
+			showImage: '',
+			dialogVisible: false,
+			uploadImageId: '',
+			fileList: [],
+			list: []
+		};
+	},
+	created() {
+		request({
+			url: '/qviKHUYsyN.php/index/getAliOssToken',
+			method: 'get',
+			params: {}
+		}).then(res => {
+			this.aliosstoken = res.data.aliosstoken;
+			this.upload_host = res.data.upload_host
+		});
+	},
+	computed: {
+		showFileList: {
+			get: function() {
+				if (this.fileList.length > 0 && this.fileList[0].url) {
+					return true;
+				} else {
+					return false;
+				}
+			},
+			set: function(newValue) {}
+		}
+	},
+	methods: {
+		emitInput(val) {
+			this.$emit('input', val);
+		},
+		handleClickItem(){
+			// 获取遮罩层dom
+			setTimeout(function(){
+			  let domImageMask = document.querySelector(".el-image-viewer__wrapper");
+			  if (!domImageMask) {
+			    return;
+			  }
+			  domImageMask.addEventListener("click", (e) => {
+			    if(e.target.parentNode.className == 'el-image-viewer__actions__inner') {
+			      return;  //如果点击底部菜单,不关闭
+			    }
+			    // 点击遮罩层时调用关闭按钮的 click 事件
+			    document.querySelector(".el-image-viewer__close").click();
+			  });
+			},300)
+		},
+		handleRemove(file, fileList) {
+			if (fileList.length == 0) {
+				this.fileList = [{ name: '', url: '' }];
+				// this.showFileList = false;
+			} else {
+				this.fileList = fileList;
+			}
+		},
+		handlePreview(file) {
+			// const fileExtension = file.name.substring(file.name.lastIndexOf('.') + 1);
+			// if (fileExtension == 'png' || fileExtension == 'jpg' || fileExtension == 'jpeg') {
+			// 	this.showImage = file.url;
+			// 	// this.showImage = file.full_url;
+			// 	this.dialogVisible = true;
+			// } else {
+			// 	window.open(file.url);
+			// 	// window.open(file.full_url);
+			// }
+		},
+		getUUID() {
+			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+				return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16);
+			});
+		},
+		beforeUpload(file) {
+			if(this.fileType == 'image'){
+				if(!file.type.includes('image')){
+					return this.$message.warning('该选项只支持上传图片格式的文件!');
+				}
+			}else if(this.fileType == 'video'){
+				if(!file.type.includes('video')){
+					return this.$message.warning('该选项只支持上传视频格式的文件!');
+				}
+			}else if(this.fileType == 'image/video'){
+				if(!file.type.includes('image') && !file.type.includes('video')){
+					return this.$message.warning('该选项只支持上传视频或图片格式的文件!');
+				}
+			}
+			
+			this.list.push(file.name)
+			if(this.list.length > this.uploadNum){
+				this.$message.warning('最多上传' + this.uploadNum +'个文件!');
+				return false
+			}
+			const that = this;
+			return new Promise((resolve, reject) => {
+				request({
+					url: '/addons/alioss/index/params',
+					method: 'post',
+					data: {
+						method: 'POST',
+						md5: file.name.substring(0, file.name.indexOf('.')),
+						name: file.name,
+						type: file.type,
+						size: file.size,
+						aliosstoken: this.aliosstoken
+					}
+				})
+					.then(res => {
+						that.dataObj = res.data;
+						resolve(true);
+					})
+					.catch(err => {
+						reject(false);
+					});
+			});
+		},
+		handleUploadSuccess(res, file, fileList) {
+			console.log(this.fileList)
+			// if (this.fileList.length == 1 && !this.fileList[0].url) {
+			// 	this.fileList.pop();
+			// }
+			// this.showFileList = true;
+			this.fileList.push({
+				name: file.name,
+				hover: false,
+				url: process.env.VUE_APP_BASE_API + 'qviKHUYsyN.php/index/getOssSign?object=' + this.dataObj.key.replace('${filename}', file.name)
+			});
+			
+			this.$emit('editUrl', {
+				name: file.name,
+				hover: false,
+				url: this.dataObj.key.replace('${filename}', file.name)
+			},this.name,this.index);
+			// this.fileList.push({
+			// 	name: file.name,
+			// 	url: this.dataObj.key.replace('${filename}', file.name),
+			// 	full_url: process.env.VUE_APP_BASE_API + 'qviKHUYsyN.php/index/getOssSign?object=' + this.dataObj.key.replace('${filename}', file.name)
+			// });
+		},
+		previewImages() {
+		  let images = [];
+		  if(this.fileList && this.fileList.length > 0) {
+		    this.fileList.forEach(item => {
+		      if(this.isImageUrl(item.url)) {
+		        images.push(item.url);
+		      }
+		    })
+		  }
+		  return images;
+		},
+		// 预览图片
+		previewImage(url) {
+		  let images = [];
+		  this.fileList.forEach(item => {
+		    if(this.isImageUrl(item.url)) {
+		      images.push(item);
+		    }
+		  })
+		  let index = findElem(images, 'url', url);
+		  this.$refs.img[index].showViewer = true;
+		},
+		// 预览视频
+		previewVideo(url) {
+		  // this.previewVideoUrl = url;
+		  // this.previewVideoDialog = true;
+		},
+		isImageUrl(url) {
+			const fileSuffix = url.substring(url.lastIndexOf(".") + 1);
+			const whiteList = ['jpg', 'jpeg', 'png'];
+			if (whiteList.indexOf(fileSuffix) === -1) {
+				return false;
+			}else {
+				return true;
+			}
+		},
+		uploadImage(id) {
+		    this.list = []
+		    this.uploadImageId = id;
+		    document.querySelector(`.${this.name} input`).click();
+		},
+		// 删除图片
+		deleteImage(url) {
+		  let index = findElem(this.fileList, 'url', url);
+		  this.fileList.splice(index, 1);
+		},
+	}
+};
+</script>
+<style type="text/css" lang="scss">
+	.images {
+	  display: flex;
+	  flex-wrap: wrap;
+	  .item {
+	    display: flex;
+	    flex-direction: column;
+	    justify-content: center;
+	    align-items: center;
+	    width: 120px;
+	    margin-right: 20px;
+	    .img {
+	      border: 1px dashed #eaeaea;
+	      border-radius: 5px;
+	      overflow: hidden;
+	      position: relative;
+	      .el-image {
+	        display: block;
+	      }
+	      .mask {
+	        position: absolute;
+	        left: 0;
+	        top: 0;
+	        width: 120px;
+	        height: 120px;
+	        background: rgba($color: #000000, $alpha: 0.3);
+	        display: flex;
+	        align-items: center;
+	        justify-content: center;
+	        i {
+	          font-size: 20px;
+	          color: #ffffff;
+	          cursor: pointer;
+	          margin: 0 8px;
+	        }
+	      }
+	    }
+	    .add {
+	      border: 1px solid #dddddd;
+	      border-radius: 5px;
+	      cursor: pointer;
+	    }
+	    .text {
+	      font-size: 14px;
+	      color: #666666;
+	    }
+	  }
+	  .add {
+	    width: 120px;
+	    height: 120px;
+	    border: 1px solid #dddddd;
+	    border-radius: 5px;
+	    cursor: pointer;
+	    display: flex;
+	    align-items: center;
+	    justify-content: center;
+	    i {
+	      font-size: 30px;
+	      color: #999;
+	    }
+	  }
+	}
+	.avatar-uploader2 {
+	  height: 0;
+	}
+</style>

+ 124 - 0
src/components/Common/importUpload.vue

@@ -0,0 +1,124 @@
+<template>
+	<div>
+		<el-upload
+			:action="oss_url"
+			:data="dataObj"
+			:multiple="false"
+			:show-file-list="showFileList"
+			:file-list="fileList"
+			:before-upload="beforeUpload"
+			:on-remove="handleRemove"
+			:on-success="handleUploadSuccess"
+		>
+			<el-button size="small" type="primary">{{fileList.length == 0 ? '点击上传':'重新上传'}}</el-button>
+		</el-upload>
+	</div>
+</template>
+<script>
+import request from '@/utils/request';
+export default {
+	name: 'importUpload',
+	props: {
+		fileList: Array
+	},
+	data() {
+		return {
+			oss_url: '',
+			dataObj: {
+				policy: '',
+				signature: '',
+				key: '',
+				ossaccessKeyId: '',
+			},
+			aliosstoken: '',
+		};
+	},
+	created() {
+		request({
+			url: '/qviKHUYsyN.php/index/getAliOssToken',
+			method: 'get',
+			params: {}
+		}).then(res => {
+			this.aliosstoken = res.data.aliosstoken;
+			this.oss_url = res.data.upload_host;
+		});
+	},
+	computed: {
+		showFileList: {
+			get: function() {
+				if (this.fileList.length > 0 && this.fileList[0].url) {
+					return true;
+				} else {
+					return false;
+				}
+			},
+			set: function(newValue) {}
+		}
+	},
+	methods: {
+		getUUID() {
+			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+				return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16);
+			});
+		},
+		createName(name) {
+			const date = Date.now();
+			const uuid = this.getUUID();
+			const fileSuffix = name.substring(name.lastIndexOf(".") + 1);
+			return `${date}${uuid}.${fileSuffix}`;
+		},
+		handleRemove(file, fileList) {
+			this.fileList = [{ name: '', url: '' }];
+		},
+		beforeUpload(file) {
+			const that = this;
+			const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
+      const whiteList = ['xls', 'xlsx', 'xlsm'];
+      if (whiteList.indexOf(fileSuffix) === -1) {
+        return this.$errorMsg('只支持上传excel表格文件!');
+      }
+			const fileName = this.createName(file.name);
+			const loading = this.$loading({
+        lock: true,
+        text: 'Loading',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      });
+			return new Promise((resolve, reject) => {
+				request({
+					url: '/addons/alioss/index/params',
+					method: 'post',
+					data: {
+						method: 'POST',
+						md5: fileName.substring(0, fileName.indexOf('.')),
+						name: fileName,
+						type: file.type,
+						size: file.size,
+						aliosstoken: this.aliosstoken
+					}
+				}).then(res => {
+					that.dataObj = res.data;
+					resolve(true);
+				}).catch(err => {
+					reject(false);
+				});
+			});
+		},
+		handleUploadSuccess(res, file, fileList) {
+			const loading = this.$loading({
+        lock: true,
+        text: 'Loading',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      });
+			this.fileList.pop();
+			this.fileList.push({
+				name: file.name,
+				url: this.dataObj.key
+			});
+			this.showFileList = true;
+			loading.close();
+		}
+	}
+};
+</script>

+ 206 - 0
src/components/Common/importUploadPhp.vue

@@ -0,0 +1,206 @@
+<template>
+	<block>
+		<el-upload style="display: inline-block; margin: 0 10px;" :action="upload_host" :data="dataObj" :multiple="false" :before-upload="beforeUpload" :on-success="handleUploadSuccess" :file-list="importFileList">
+			<el-button @click="upload" size="small" type="primary" :loading="importLoading">{{ importLoading ? '导入中...' : title }}</el-button>
+		</el-upload>
+		<el-dialog title="错误提示" :visible.sync="isShowMsg" width="50%" :close-on-click-modal="false" :destroy-on-close="true">
+			<div class="html" v-html="html"></div>
+			<div slot="footer" class="dialog-footer">
+				<el-button type="primary" @click="isShowMsg = false">确定</el-button>
+			</div>
+		</el-dialog>
+	</block>
+</template>
+<script>
+import request from '@/utils/request';
+import SparkMD5 from 'spark-md5'
+export default {
+	name: 'importUploadPhp',
+	props: {
+		requestUrl: {
+			type: String,
+			default: ''
+		},
+		title: {
+			type: String,
+			default: '导入'
+		},
+		batch_month: {
+			type: String,
+			default: ''
+		},
+	},
+	data() {
+		return {
+			importFileList: [],
+			importLoading: false,
+			timer: '',
+			aliosstoken: '',
+			upload_host: '',
+			dataObj: {
+				policy: '',
+				signature: '',
+				key: '',
+				ossaccessKeyId: '',
+			},
+			md5: '',
+			isShowMsg: false,
+			html: ''
+		};
+	},
+	created() {
+		
+	},
+	methods: {
+		getAliOssToken(){
+			const that = this;
+			request({
+				url: '/qviKHUYsyN.php/index/getAliOssToken',
+				method: 'get',
+				params: {}
+			}).then(res => {
+				that.aliosstoken = res.data.aliosstoken;
+				that.upload_host = res.data.upload_host
+			});
+		},
+		close(){
+			this.isShowMsg = false
+		},
+		emitInput(val) {
+			this.$emit('input', val);
+		},
+		upload(){
+			this.getAliOssToken()
+		},
+		beforeUpload(file) {
+			const that = this;
+			return new Promise((resolve, reject) => {
+				var fileReader = new FileReader();
+				//此处打印file可看到file下的raw为文件属性
+				let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
+				var spark = new SparkMD5.ArrayBuffer();
+				//获取文件二进制数据
+				fileReader.readAsArrayBuffer(file)
+						
+				//异步执行函数
+				fileReader.onload = function(e){
+					spark.append(e.target.result);
+					var md5 = spark.end()
+					that.md5 = md5
+					console.log(md5)
+					request({
+						url: '/addons/alioss/index/params',
+						method: 'post',
+						data: {
+							method: 'POST',
+							md5: md5,
+							name: md5 + file.name.substring(file.name.lastIndexOf(".")),
+							type: file.type,
+							size: file.size,
+							aliosstoken: that.aliosstoken
+						}
+					})
+						.then(res => {
+							that.dataObj = res.data;
+							resolve(true);
+						})
+						.catch(err => {
+							reject(false);
+						});
+				}
+			});
+		},
+		handleUploadSuccess(res, file, fileList) {
+			this.getNotify(file)
+			this.toLead()
+		},
+		toLead() {
+			let params = {
+				file: this.dataObj.key.replace('${filename}')
+			}
+			request({
+				url: this.requestUrl,
+				method: 'post',
+				params
+			}).then(res => {
+				if(res.data.key){
+					this.timer = setInterval(()=> {
+						this.$message({
+							type: 'success',
+							message: '导入中,请等待...'
+						});
+						this.getCache(res.data.key)
+					},3000)
+				}else if(res.data.length > 0){
+					this.$emit('importSuccess',res.data)
+				} else {
+					this.$message.error(res.msg);
+				}
+				this.importLoading = false;
+				this.importFileList = [];
+			})
+		},
+		getNotify(file){
+			request({
+				url: '/addons/alioss/index/notify',
+				method: 'post',
+				data: {
+					method: 'POST',
+					url: this.dataObj.key.replace('${filename}'),
+					md5: this.md5,
+					name: this.md5 + file.name.substring(file.name.lastIndexOf(".")),
+					type: file.type,
+					size: file.size,
+					aliosstoken: this.aliosstoken
+				}
+			}).then(res => {
+				resolve(true);
+			}).catch(err => {
+				reject(false);
+			});
+		},
+		getCache(key){
+			let params = {
+				key: key
+			}
+			if(this.batch_month){
+				params.batch_month = this.batch_month
+			}
+			request({
+				url: '/qviKHUYsyN.php/index/getCache',
+				method: 'get',
+				params
+			}).then(res => {
+				if(res.data.import_bool){
+					clearInterval(this.timer)
+					this.$emit('importSuccess')
+					this.$message({
+						type: 'success',
+						message: '导入成功!'
+					});
+				}else if(res.code != 1){
+					clearInterval(this.timer)
+					// let html = ''
+					// let arr = res.msg.split('<br />\n')
+					// arr.forEach(item => {
+					// 	html += `<div>${item}</div>`
+					// })
+					this.html = res.msg
+					this.isShowMsg = true
+					if(res.msg.length < 500){
+						setTimeout(() => {
+							this.isShowMsg = false
+						},5000)
+					}
+				}
+			});
+		},
+	}
+};
+</script>
+<style type="text/css" scoped="scoped">
+	.html{
+		font-size: 16px;
+		line-height: 20px;
+	}
+</style>

+ 156 - 0
src/components/Common/singleUpload.vue

@@ -0,0 +1,156 @@
+<template>
+	<div>
+		<el-upload
+			:action="upload_host"
+			:data="dataObj"
+			:multiple="false"
+			:show-file-list="showFileList"
+			:file-list="fileList"
+			:before-upload="beforeUpload"
+			:on-remove="handleRemove"
+			:on-success="handleUploadSuccess"
+			:on-preview="handlePreview"
+			:disabled="!isDisabled"
+		>
+			<el-button v-if="isDisabled" size="small" type="primary">点击上传</el-button>
+			<div v-if="isDisabled" slot="tip" class="el-upload__tip">可上传多个附件,不限制格式!</div>
+		</el-upload>
+		<el-dialog :visible.sync="dialogVisible" :append-to-body="true"><img width="100%" :src="showImage" alt="" /></el-dialog>
+	</div>
+</template>
+<script>
+import request from '@/utils/request';
+export default {
+	name: 'SingleUpload',
+	props: {
+		isDisabled: Boolean,
+		fileList: Array,
+		uploadNum: {
+			type: Number,
+			default: 1,
+		},
+		uploadType: {
+			type: Number,
+			default: 1,
+		}
+	},
+	data() {
+		return {
+			dataObj: {
+				policy: '',
+				signature: '',
+				key: '',
+				ossaccessKeyId: '',
+			},
+			aliosstoken: '',
+			upload_host: '',
+			showImage: '',
+			dialogVisible: false
+		};
+	},
+	created() {
+		console.log(this.fileList, 111, this.showFileList);
+		request({
+			url: '/qviKHUYsyN.php/index/getAliOssToken',
+			method: 'get',
+			params: {}
+		}).then(res => {
+			this.aliosstoken = res.data.aliosstoken;
+			this.upload_host = res.data.upload_host
+		});
+	},
+	computed: {
+		showFileList: {
+			get: function() {
+				if (this.fileList.length > 0 && this.fileList[0].url) {
+					return true;
+				} else {
+					return false;
+				}
+			},
+			set: function(newValue) {}
+		}
+	},
+	methods: {
+		emitInput(val) {
+			this.$emit('input', val);
+		},
+		handleRemove(file, fileList) {
+			if (fileList.length == 0) {
+				this.fileList = [{ name: '', url: '' }];
+				this.showFileList = false;
+			} else {
+				this.fileList = fileList;
+			}
+		},
+		handlePreview(file) {
+			const fileExtension = file.name.substring(file.name.lastIndexOf('.') + 1);
+			if (fileExtension == 'png' || fileExtension == 'jpg' || fileExtension == 'jpeg') {
+				if(this.uploadType == 1){
+					this.showImage = file.url;
+				}else{
+					this.showImage = file.full_url;
+				}
+				this.dialogVisible = true;
+			} else {
+				if(this.uploadType == 1){
+					window.open(file.url);
+				}else{
+					window.open(file.full_url);
+				}
+			}
+		},
+		getUUID() {
+			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+				return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16);
+			});
+		},
+		beforeUpload(file) {
+			if(this.fileList.length == this.uploadNum){
+				this.$message.warning('最多上传' + this.uploadNum +'个文件!');
+				return false
+			}
+			const that = this;
+			return new Promise((resolve, reject) => {
+				request({
+					url: '/addons/alioss/index/params',
+					method: 'post',
+					data: {
+						method: 'POST',
+						md5: file.name.substring(0, file.name.indexOf('.')),
+						name: file.name,
+						type: file.type,
+						size: file.size,
+						aliosstoken: this.aliosstoken
+					}
+				})
+					.then(res => {
+						that.dataObj = res.data;
+						resolve(true);
+					})
+					.catch(err => {
+						reject(false);
+					});
+			});
+		},
+		handleUploadSuccess(res, file, fileList) {
+			if (this.fileList.length == 1 && !this.fileList[0].url) {
+				this.fileList.pop();
+			}
+			this.showFileList = true;
+			if(this.uploadType == 1){
+				this.fileList.push({
+					name: file.name,
+					url: process.env.VUE_APP_BASE_API + 'qviKHUYsyN.php/index/getOssSign?object=' + this.dataObj.key.replace('${filename}', file.name)
+				});
+			}else{
+				this.fileList.push({
+					name: file.name,
+					url: this.dataObj.key.replace('${filename}', file.name),
+					full_url: process.env.VUE_APP_BASE_API + 'qviKHUYsyN.php/index/getOssSign?object=' + this.dataObj.key.replace('${filename}', file.name)
+				});
+			}
+		}
+	}
+};
+</script>

+ 43 - 37
src/views/bigViews/index.vue

@@ -7,25 +7,31 @@
           background: `url('${
             [
               'https://zfire-train.oss-cn-guangzhou.aliyuncs.com/train/pic/166997089127898d52ae7-87a5-49ca-b25b-ee1fe4f735ba.gif',
-              'https://pgxtadm.greeapps.com/java/img/get?key=uploads/20230417/860f5e3c02404eb4b638a92edcec47c9.gif',
-              'https://pgxtadm.greeapps.com/java/img/get?key=uploads/20230417/d30d030ca19c0cf0cb460e03acee5d8b.gif',
-              'https://pgxtadm.greeapps.com/java/img/get?key=uploads/20230417/16c6e3dad13c5ffe2725c42bd5e42183.gif',
-              'https://pgxtadm.greeapps.com/java/img/get?key=uploads/20230417/f6dfd70df6401871a35c255f38d5a862.gif',
+              'https://pgxtadm.greeapps.com/img/get?key=uploads/20230417/860f5e3c02404eb4b638a92edcec47c9.gif',
+              'https://pgxtadm.greeapps.com/img/get?key=uploads/20230417/d30d030ca19c0cf0cb460e03acee5d8b.gif',
+              'https://pgxtadm.greeapps.com/img/get?key=uploads/20230417/16c6e3dad13c5ffe2725c42bd5e42183.gif',
+              'https://pgxtadm.greeapps.com/img/get?key=uploads/20230417/f6dfd70df6401871a35c255f38d5a862.gif'
             ][dayIndex]
-          }')`,
+          }')`
         }"
       />
       <zj-page-container>
-        <div class="head-size"><head-view/></div>
+        <div class="head-size"><head-view /></div>
         <zj-page-fill>
-          <dataView1/>
+          <dataView1 />
         </zj-page-fill>
-        <div @click="huishouye" :style="`position: fixed;right: 20px;bottom: 100px;background-image: url(${fanhuizhuye});background-size: 100%;width:30px;height: 30px;z-index: 9999;`">
-        </div>
-        <div @click="shuxinyemian" :style="`position: fixed;right: 20px;bottom: 60px;background-image: url(${shuaxin});background-size: 100%;width:30px;height: 30px;z-index: 9999;`">
-        </div>
-        <div :style="`position: fixed;right: 20px;bottom: 20px;background-image: url(${quanpin});background-size: 100%;width:30px;height: 30px;z-index: 9999;display: flex;justify-content: center;align-items: center;`">
-          <screenfull id="screenfull" :className="'hahahdkdjshakdhssk'"/>
+        <div
+          @click="huishouye"
+          :style="`position: fixed;right: 20px;bottom: 100px;background-image: url(${fanhuizhuye});background-size: 100%;width:30px;height: 30px;z-index: 9999;`"
+        ></div>
+        <div
+          @click="shuxinyemian"
+          :style="`position: fixed;right: 20px;bottom: 60px;background-image: url(${shuaxin});background-size: 100%;width:30px;height: 30px;z-index: 9999;`"
+        ></div>
+        <div
+          :style="`position: fixed;right: 20px;bottom: 20px;background-image: url(${quanpin});background-size: 100%;width:30px;height: 30px;z-index: 9999;display: flex;justify-content: center;align-items: center;`"
+        >
+          <screenfull id="screenfull" :className="'hahahdkdjshakdhssk'" />
         </div>
       </zj-page-container>
     </div>
@@ -34,14 +40,14 @@
 
 <script>
 import Screenfull from '@/components/Screenfull'
-import pageSizeLimit from '@/components/page-size-limit.vue';
-import headView from '@/components/head.vue';
-import { delayPerform } from 'js-perform-lock';
-import quanpin from '@/assets/全屏@2x.png';
-import shuaxin from '@/assets/刷新@2x.png';
-import fanhuizhuye from '@/assets/fanhuizhuye.png';
-var d;
-import dataView1 from './dataView1/index.vue';
+import pageSizeLimit from '@/components/page-size-limit.vue'
+import headView from '@/components/head.vue'
+import { delayPerform } from 'js-perform-lock'
+import quanpin from '@/assets/全屏@2x.png'
+import shuaxin from '@/assets/刷新@2x.png'
+import fanhuizhuye from '@/assets/fanhuizhuye.png'
+var d
+import dataView1 from './dataView1/index.vue'
 export default {
   components: {
     headView,
@@ -55,39 +61,39 @@ export default {
       shuaxin,
       fanhuizhuye,
       dayIndex: (new Date().getDate() - 1) % 5,
-      showBool: true,
-    };
+      showBool: true
+    }
   },
   mounted() {
     d = new delayPerform(250).refactor((/**可接收参数**/) => {
-      this.re();
-    });
-    window.addEventListener('resize', d);
+      this.re()
+    })
+    window.addEventListener('resize', d)
   },
   beforeUnmount() {
-    window.removeEventListener('resize', d);
+    window.removeEventListener('resize', d)
   },
   methods: {
-    huishouye(){
+    huishouye() {
       this.$router.push({
         name: 'home'
       })
     },
-    shuxinyemian(){
-      location.reload();
+    shuxinyemian() {
+      location.reload()
     },
     re() {
-      this.showBool = false;
+      this.showBool = false
       this.$nextTick(() => {
-        this.showBool = true;
-      });
-    },
-  },
-};
+        this.showBool = true
+      })
+    }
+  }
+}
 </script>
 
 <style lang="scss">
-.hahahdkdjshakdhssk{
+.hahahdkdjshakdhssk {
   fill: #fff !important;
   color: #fff !important;
 }

+ 462 - 0
src/views/setting/fileDelivery/centralFileDelivery/index.vue

@@ -0,0 +1,462 @@
+<template>
+  <div class="app-container">
+    <!-- 筛选条件 -->
+    <div class="screen-container">
+      <div class="top clearfix">
+        <div class="title fl">条件筛选</div>
+      </div>
+      <el-form ref="screenForm" :model="screenForm" label-width="60px" size="small" label-position="left">
+        <el-row :gutter="20">
+          <el-col :xs="24" :sm="14" :lg="14">
+            <el-form-item label="标题" prop="title">
+              <el-input v-model="screenForm.title" placeholder="请输入标题"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="4" :lg="4">
+            <el-form-item label="是否强制提醒" prop="isNotice" label-width="100px">
+              <el-select v-model="screenForm.isNotice" placeholder="请选择">
+                <el-option
+                  v-for="item in [
+                    { value: true, label: '是' },
+                    { value: false, label: '否' }
+                  ]"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="6" :lg="6" class="tr">
+            <el-form-item label="">
+              <el-button size="small" @click="resetScreenForm">清空</el-button>
+              <el-button size="small" type="primary" @click="submitScreenForm">搜索</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+
+    <div class="mymain-container">
+      <div class="btn-group clearfix">
+        <div class="fl">
+          <el-button
+            class="fl"
+            size="small"
+            type="primary"
+            icon="el-icon-plus"
+            @click="clickImport()"
+            v-if="userInfo.type == 1"
+            >新增</el-button
+          >
+          <div class="tips fl">导入模板第一行必须为空白行、第一列必须为公司编号(S9219801)、第二列必须为网点S编号</div>
+        </div>
+      </div>
+      <div class="table">
+        <el-table
+          v-loading="listLoading"
+          :data="dataList"
+          element-loading-text="Loading"
+          border
+          fit
+          highlight-current-row
+          stripe
+        >
+          <el-table-column align="center" label="操作" fixed width="160">
+            <template slot-scope="scope">
+              <el-button type="text" @click="openDetail(scope.row.id)" v-if="checkBtnRole('edit')">详情</el-button>
+              <el-button type="text" @click="download(scope.row)" v-if="checkBtnRole('edit')">下载</el-button>
+              <el-popconfirm
+                style="margin-left: 10px"
+                title="确定删除吗?"
+                @onConfirm="deleteData(scope.row.id)"
+                v-if="userInfo.type == 1"
+              >
+                <el-button slot="reference" type="text">删除</el-button>
+              </el-popconfirm>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            label="标题"
+            prop="title"
+            min-width="140"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column align="center" label="操作人" prop="operatorUserName" min-width="140" show-overflow-tooltip>
+            <template slot-scope="scope"> {{ scope.row.operatorNickName }}({{ scope.row.operatorUserName }}) </template>
+          </el-table-column>
+          <el-table-column align="center" prop="isNotice" label="是否强制提醒" show-overflow-tooltip>
+            <template slot-scope="scope">
+              {{ scope.row.isNotice ? '是' : '否' }}
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="isPwd" label="是否需要密码">
+            <template slot-scope="scope">
+              {{ scope.row.isPwd ? '是' : '否' }}
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="remark"
+            label="备注"
+            min-width="140"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            label="创建时间"
+            prop="createTime"
+            min-width="160"
+            show-overflow-tooltip
+          ></el-table-column>
+        </el-table>
+      </div>
+
+      <div class="pagination clearfix">
+        <div class="fr">
+          <el-pagination
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+            :current-page="currentPage"
+            :page-sizes="[10, 20, 30, 50]"
+            :page-size="10"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="listTotal"
+          >
+          </el-pagination>
+        </div>
+      </div>
+    </div>
+
+    <!-- 新增 -->
+    <el-dialog
+      title="新增"
+      :visible.sync="importFormDialog"
+      :show-close="false"
+      width="40%"
+      :close-on-click-modal="false"
+    >
+      <el-form ref="importForm" label-position="left" label-width="80px">
+        <el-form-item label="标题" prop="title">
+          <el-input v-model="importForm.title" placeholder="请输入标题"></el-input>
+        </el-form-item>
+        <el-form-item label="上传文件" prop="fileUrl">
+          <!-- <el-upload
+            ref="upload"
+            :action="baseURL + 'com/list/yonge'"
+            :headers="myHeaders"
+            :on-remove="handleRemove"
+            :on-change="handleChange"
+            :auto-upload="false"
+            :file-list="fileList">
+            <el-button size="small" type="primary">{{fileList.length == 0 ? '点击上传':'重新上传'}}</el-button>
+          </el-upload> -->
+          <import-upload :fileList="fileList" />
+        </el-form-item>
+        <el-form-item label="是否强制提醒" prop="isNotice" label-width="100px">
+          <el-radio-group v-model="importForm.isNotice">
+            <el-radio :label="true">是</el-radio>
+            <el-radio :label="false">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="下载密码" prop="downloadPwd">
+          <el-input v-model="importForm.downloadPwd" placeholder="请输入下载密码"></el-input>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input type="textarea" v-model="importForm.remark" placeholder="请输入备注"></el-input>
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancelImportForm">取 消</el-button>
+        <el-button type="primary" @click="submitImportForm">确 定</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 详情 -->
+    <el-dialog title="详情" :visible.sync="detailDialog" :show-close="false" width="70%" :close-on-click-modal="false">
+      <div class="table" style="margin: 10px 0 20px">
+        <el-table
+          v-loading="detailTable_listLoading"
+          :data="detailTable_dataList"
+          element-loading-text="Loading"
+          tooltip-effect="dark"
+          style="width: 100%"
+          max-height="270"
+        >
+          <el-table-column align="center" label="序号" type="index" width="50"></el-table-column>
+          <el-table-column
+            align="center"
+            prop="title"
+            label="标题"
+            min-width="140"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column align="center" prop="websitNumber" label="网点名称" min-width="140" show-overflow-tooltip>
+            <template slot-scope="scope"> {{ scope.row.websitName }}({{ scope.row.websitNumber }}) </template>
+          </el-table-column>
+          <el-table-column align="center" prop="isNotice" label="是否强制提醒" show-overflow-tooltip>
+            <template slot-scope="scope">
+              {{ scope.row.isNotice ? '是' : '否' }}
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="remark"
+            label="备注"
+            min-width="140"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column align="center" prop="createTime" label="下载时间" min-width="160"></el-table-column>
+        </el-table>
+      </div>
+      <div class="pagination clearfix">
+        <div class="fr">
+          <el-pagination
+            @current-change="detailTableCurrentChange"
+            :current-page="detailTable_currentPage"
+            :page-size="detailTable_pageSize"
+            background
+            layout="prev, pager, next"
+            :total="detailTable_listTotal"
+          >
+          </el-pagination>
+        </div>
+      </div>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="detailDialog = false">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getToken } from '@/utils/auth'
+import { getList, getDownloadList, deleteData, exportFile, handleImport } from '@/api/universal/universal_list'
+import importUpload from '@/components/Common/importUpload.vue'
+import { downloadFiles } from '@/utils/util'
+import request from '@/utils/request'
+export default {
+  components: {
+    importUpload
+  },
+  data() {
+    return {
+      baseURL: process.env.VUE_APP_BASE_API,
+      myHeaders: { 'x-token': getToken() },
+      dataList: null, // 列表数据
+      listLoading: true, // 列表加载loading
+      currentPage: 1, // 当前页码
+      pageSize: 10, // 每页数量
+      listTotal: 0, // 列表总数
+      screenForm: {
+        // 筛选表单数据
+        title: '',
+        isNotice: ''
+      },
+      importForm: {
+        title: '',
+        remark: '',
+        isNotice: false,
+        downloadPwd: ''
+      },
+      importFormDialog: false,
+      fileList: [],
+      detailDialog: false, // 详情 - 弹窗
+      detailTable_dataList: null, // 详情 - 列表数据
+      detailTable_listLoading: true, // 详情 - 列表加载loading
+      detailTable_currentPage: 1, // 详情 - 当前页码
+      detailTable_pageSize: 10, // 详情 - 每页数量
+      detailTable_listTotal: 0 // 详情 - 列表总数
+    }
+  },
+  computed: {
+    userInfo() {
+      return JSON.parse(localStorage.getItem('greemall_user') || '{}')
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    // 查询按钮权限
+    checkBtnRole(value) {
+      return true
+      let btnRole = this.$route.meta.roles
+      if (!btnRole) {
+        return true
+      }
+      let index = btnRole.indexOf(value)
+      return index >= 0 ? true : false
+    },
+
+    // 获取列表
+    getList() {
+      this.listLoading = true
+      let params = {
+        pageNo: this.currentPage,
+        pageSize: this.pageSize,
+        title: this.screenForm.title,
+        isNotice: this.screenForm.isNotice
+      }
+      getList(params).then(res => {
+        this.listLoading = false
+        this.dataList = res.data ? res.data.records : []
+        this.listTotal = res.data ? res.data.total : 0
+      })
+    },
+
+    // 更改每页数量
+    handleSizeChange(val) {
+      this.pageSize = val
+      this.currentPage = 1
+      this.getList()
+    },
+
+    // 更改当前页
+    handleCurrentChange(val) {
+      this.currentPage = val
+      this.getList()
+    },
+
+    // 提交筛选表单
+    submitScreenForm() {
+      this.currentPage = 1
+      this.getList()
+    },
+
+    // 重置筛选表单
+    resetScreenForm() {
+      this.$refs.screenForm.resetFields()
+      this.currentPage = 1
+      this.getList()
+    },
+
+    // 操作 - 删除
+    deleteData(id) {
+      deleteData({ id }).then(res => {
+        this.getList()
+        this.$successMsg()
+      })
+    },
+
+    // 详情 - 获取列表
+    getDownloadList() {
+      getDownloadList({
+        pageNo: this.detailTable_currentPage,
+        pageSize: this.detailTable_pageSize,
+        id: this.detailId
+      }).then(res => {
+        this.detailTable_dataList = res.data.records
+        this.detailTable_listTotal = res.data.total
+        this.detailTable_listLoading = false
+      })
+    },
+
+    // 详情 - 打开弹窗
+    openDetail(id) {
+      this.detailId = id
+      this.detailDialog = true
+      this.detailTable_currentPage = 1
+      this.getDownloadList()
+    },
+
+    // 详情 - 更改列表当前页
+    detailTableCurrentChange(val) {
+      this.detailTable_currentPage = val
+      this.getDownloadList()
+    },
+
+    // 点击导入
+    clickImport() {
+      this.importFormDialog = true
+    },
+
+    // 取消 导入
+    cancelImportForm() {
+      this.importFormDialog = false
+      this.fileList = []
+      this.importForm.title = ''
+    },
+
+    // 导入
+    async submitImportForm() {
+      if (!this.importForm.title) {
+        return this.$errorMsg('请填写标题')
+      }
+      if (this.fileList.length <= 0) {
+        return this.$errorMsg('请上传文件')
+      }
+      const loading = this.$loading({
+        lock: true,
+        text: 'Loading',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      })
+      const formData = {
+        file: this.fileList[0].url,
+        title: this.importForm.title,
+        remark: this.importForm.remark,
+        isNotice: this.importForm.isNotice,
+        downloadPwd: this.importForm.downloadPwd
+      }
+      handleImport(formData)
+        .then(res => {
+          this.fileList = []
+          this.getList()
+          this.importFormDialog = false
+        })
+        .catch(res => {
+          this.$errorMsg(res.message)
+        })
+        .finally(res => {
+          loading.close()
+        })
+    },
+    //下载
+    download(item) {
+      if (item.isPwd) {
+        this.$prompt('请输入下载密码', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          inputValidator: value => {
+            //非空验证
+            if (!value) {
+              return '密码不能为空!'
+            }
+          }
+        })
+          .then(({ value }) => {
+            let screenData = {
+              id: item.id,
+              downloadPwd: value
+            }
+            downloadFiles('com/list/download', screenData)
+          })
+          .catch(() => {})
+      } else {
+        this.handleExport(item)
+      }
+    },
+    // 导出
+    handleExport(item) {
+      let screenData = {
+        id: item.id
+      }
+      downloadFiles('com/list/download', screenData)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.tips {
+  font-size: 14px;
+  color: red;
+  line-height: 32px;
+  margin-left: 10px;
+}
+</style>

+ 276 - 0
src/views/setting/fileDelivery/masterFileDelivery/index.vue

@@ -0,0 +1,276 @@
+<template>
+  <div class="app-container">
+    <!-- 筛选条件 -->
+    <div>
+      <el-form ref="searchForm" :model="searchForm" label-width="100px" size="mini" label-position="left">
+        <el-row :gutter="20">
+          <el-col :xs="24" :sm="12" :lg="6">
+            <el-form-item label="标题:" prop="title">
+              <el-input v-model="searchForm.title" placeholder="请输入"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="12" :lg="6">
+            <el-form-item label="状态:" prop="status">
+              <el-select clearable style="width: 100%" v-model="searchForm.status" placeholder="全部">
+                <el-option label="正常" :value="true" />
+                <el-option label="隐藏" :value="false" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="12" :lg="6">
+            <el-form-item label="备注:" prop="remark">
+              <el-input v-model="searchForm.remark" placeholder="请输入"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="24" :lg="6">
+            <el-form-item label class="fr">
+              <el-button size="mini" @click="emptyFn">重置</el-button>
+              <el-button size="mini" type="primary" @click="searchFn">搜索</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+    <!-- 按钮 -->
+    <div class="btn-group clearfix">
+      <div class="fl">
+        <el-button class="fl" type="primary" size="mini" @click="showDialog">新增</el-button>
+        <div class="tips fl">导入模板第一行必须为空白行、第一列必须为师傅编号(师傅S编号)</div>
+      </div>
+    </div>
+    <!-- 列表 -->
+    <div class="mymain-container">
+      <div class="table">
+        <el-table
+          v-loading="listLoading"
+          :data="dataList"
+          element-loading-text="Loading"
+          border
+          fit
+          highlight-current-row
+          stripe
+        >
+          <el-table-column align="center" label="操作" fixed width="160">
+            <template slot-scope="scope">
+              <el-button type="text" @click="downloadFile(scope.row.id)">下载</el-button>
+              <el-button type="text" @click="statusFn(scope.row)">{{ scope.row.status ? '隐藏' : '显示' }}</el-button>
+              <el-popconfirm style="margin-left: 10px" @onConfirm="deleteFn(scope.row.id)" title="确定删除吗?">
+                <el-button type="text" class="textColor" slot="reference">删除</el-button>
+              </el-popconfirm>
+              <!-- <el-button type="text" @click="deleteFn(scope.row.id)">删除</el-button> -->
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="left"
+            label="标题"
+            prop="title"
+            min-width="160"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column align="left" label="状态" prop="status" min-width="160" show-overflow-tooltip>
+            <template slot-scope="scope">
+              <el-tag size="mini" v-show="scope.row.status === true" type="success">正常</el-tag>
+              <el-tag size="mini" v-show="scope.row.status === false" type="danger">隐藏</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="left"
+            label="备注"
+            prop="remark"
+            min-width="160"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            align="left"
+            label="创建人"
+            prop="createBy"
+            min-width="160"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            align="left"
+            label="创建时间"
+            prop="createTime"
+            min-width="160"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            align="left"
+            label="修改人"
+            prop="updateBy"
+            min-width="160"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            align="left"
+            label="修改时间"
+            prop="updateTime"
+            min-width="160"
+            show-overflow-tooltip
+          ></el-table-column>
+        </el-table>
+      </div>
+      <!-- 分页 -->
+      <div class="fr">
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+          :current-page="currentPage"
+          :page-sizes="[10, 20, 30, 50]"
+          :page-size="pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="listTotal"
+        ></el-pagination>
+      </div>
+    </div>
+
+    <!-- 新增 -->
+    <el-dialog title="新增" :visible.sync="addFileDialog" :show-close="false" width="40%" :close-on-click-modal="false">
+      <el-form ref="addFileForm" :model="addFileForm" label-position="left" label-width="80px">
+        <el-form-item label="标题" prop="title">
+          <el-input v-model="addFileForm.title" placeholder="请输入标题"></el-input>
+        </el-form-item>
+        <el-form-item label="上传文件" prop>
+          <import-upload :fileList="fileList" />
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input type="textarea" v-model="addFileForm.remark" placeholder="请输入备注"></el-input>
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancelDialog">取 消</el-button>
+        <el-button type="primary" @click="submitFn">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getList, getComlistSave, getComlistUpdataStatus, getComlistDelete } from '@/api/app/fileLssued'
+import importUpload from '@/components/Common/importUpload.vue'
+import { downloadFiles } from '@/utils/util'
+export default {
+  components: {
+    importUpload
+  },
+  data() {
+    return {
+      searchForm: {
+        title: '',
+        status: null,
+        remark: ''
+      },
+      dataList: [],
+      listLoading: false, // 列表加载loading
+      currentPage: 1,
+      pageSize: 10,
+      listTotal: 0,
+      fileList: [],
+      addFileDialog: false,
+      addFileForm: {
+        title: '',
+        remark: ''
+      }
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    //下载附件
+    downloadFile(id) {
+      let screenData = {
+        comListId: id
+      }
+      downloadFiles('worker/comlist/download', screenData)
+    },
+    //删除
+    async deleteFn(id) {
+      let params = {
+        id
+      }
+      await getComlistDelete(params)
+      this.getList()
+      this.$message.success('删除成功')
+    },
+    //修改状态
+    async statusFn(value) {
+      let params = {
+        id: value.id,
+        status: !value.status
+      }
+      await getComlistUpdataStatus(params)
+      this.$message.success(value.status ? '已隐藏' : '已显示')
+      this.getList()
+    },
+    //打开弹窗
+    showDialog() {
+      this.addFileDialog = true
+    },
+    //提交
+    async submitFn() {
+      let params = {
+        file: this.fileList[0].url,
+        title: this.addFileForm.title,
+        remark: this.addFileForm.remark
+      }
+      await getComlistSave(params)
+      this.getList()
+      this.cancelDialog()
+      this.$message.success('新增成功')
+    },
+    //取消弹窗
+    async cancelDialog() {
+      this.addFileDialog = false
+      await this.$refs.addFileForm.resetFields()
+      this.fileList = []
+    },
+    // 更改每页数量
+    handleSizeChange(val) {
+      this.pageSize = val
+      this.currentPage = 1
+      this.getList()
+    },
+    // 更改当前页
+    handleCurrentChange(val) {
+      this.currentPage = val
+      this.getList()
+    },
+    //获取列表数据
+    async getList() {
+      let params = {
+        pageNum: this.currentPage,
+        pageSize: this.pageSize,
+        remark: this.searchForm.remark,
+        status: this.searchForm.status,
+        title: this.searchForm.title
+      }
+      let { data } = await getList(params)
+      console.log(data)
+      this.dataList = data.records
+      this.listTotal = data.total
+    },
+    //重置
+    async emptyFn() {
+      await this.$refs.searchForm.resetFields()
+      this.searchFn()
+    },
+    //搜索
+    searchFn() {
+      this.currentPage = 1
+      this.getList()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tips {
+  font-size: 14px;
+  color: red;
+  line-height: 32px;
+  margin-left: 10px;
+}
+</style>
+>