vue中,el-table树形数据与懒加载【实例】(二)——封装拖拽上传el-upload & 本地下载模板-public下的file文件夹 & JSON.parse转对象 & 表单禁止输入特殊字符
4、封装拖拽下载模板和上传
src\components\customPlanImport.vue
<template> <div class="item-content"> <el-dialog v-model="isShow" :close-on-click-modal="true" :destroy-on-close="true" :show-close="true" title="导入规划计划" width="35%" @close="handleCancel" > <el-upload ref="uploadRef" action="#" class="upload-demo" drag :file-list="fileList" :http-request="handlePeopleUpload" :limit="1" :multiple="false" :show-file-list="true" > <!-- :on-change="handleChange" :on-remove="handleRemove" --> <i class="el-icon-upload"></i> <div class="el-upload__text"> <em>选择文件</em> 或将文件拖拽至此区域 </div> <div class="el-upload__tip">支持格式:xls、xlsx</div> </el-upload> <el-button type="text" @click="handleDownLoadTemplate(source)"> 下载导入模板 </el-button> <div class="upload-footer"> <el-button type="primary" @click="handleSubmit">确 定</el-button> <el-button plain type="primary" @click="handleCancel">取 消</el-button> </div> </el-dialog> <!-- 导入失败 --> <el-dialog v-model="isShowFail" class="fail-dialog" :close-on-click-modal="true" :destroy-on-close="true" :show-close="true" title="导入失败" width="35%" @close="handleClose" > <template v-if="errorList[0].row"> <h4 class="fail-title"> 导入失败,请求改后重新上传,错误数据{
{ errNumber }}条,失败原因如下: </h4> <el-table border :data="errorList"> <el-table-column label="行数" prop="index" /> <el-table-column label="错误原因" prop="msg" /> </el-table> </template> <template v-else> <h4 class="fail-title"> 导入失败,请求改后重新上传,失败原因: <span style="font-weight: 200; color: red"> {
{ errorList[0].msg }} </span> </h4> </template> </el-dialog> </div> </template> <script> // import { downloadFileCom } from '@src/hooks/useFolesUtils.js' // 走接口下载 // import { getFeasDownload } from '@/api/research/index' // 走接口下载 import { downFile } from '@src/utils/util' // 本地下载 import { ElMessage } from 'element-plus' import { uploadPlanFileApi } from '@/api/organization/project' export default defineComponent({ name: 'CustomTaskImport', components: {}, props: { source: { require: true, type: String, default: '', }, showDialog: { require: true, type: Boolean, default: false, }, }, emits: ['closeDialog', 'submitDialog', 'downLoadTemplate'], setup(props, { emit }) { const { showDialog, source } = toRefs(props) const state = reactive({ isShow: showDialog, uploadRef: null, isShowFail: false, source: source, fileList: [], formData: { name: '', }, fileData: [], errNumber: 0, errorList: [], }) //下载导入模板 const handleDownLoadTemplate = (type) => { if (type === 'approval') { // 接口下载模板 // getFeasDownload().then((res) => { // downloadFileCom(res, '规划计划导入模板') // }) downFile('Plan-Import.xlsx') } } //提交 const handlePeopleUpload = (options) => { const formData = new FormData() formData.append('file', options.file) switch (state.source) { case 'research': case 'task': case 'approval': uploadPlanFileApi(formData).then((res) => { if (res.code === '00000') { // state.fileData = res.data ElMessage({ type: 'success', message: '上传成功', }) } else { // state.errNumber = 0 ElMessage.error(res.message) } }) } } const handleSubmit = () => { state.uploadRef.clearFiles() // if (state.errNumber > 0) { // state.isShowFail = true // } else { // state.isShowFail = false // if (state.fileData.length && state.errorList.length) { // ElMessage.success('导入成功') // } else { // ElMessage.error({ // type: 'error', // message: '请先上传文件', // }) // } // } handleClose() // emit('submitDialog', state.fileData) emit('submitDialog', state.handleClose) } // 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 const handleChange = (file) => { const fileName = file.raw.name //限制文件类型 const fileExt = fileName.replace(/.+\./, '') if (['xlsx', 'xls'].indexOf(fileExt.toLowerCase()) === -1) { ElMessage({ showClose: true, message: '请上传后缀名为xlsx、xls', type: 'error', }) return } } //移除 const handleRemove = () => {} // 取消 const handleCancel = () => { emit('closeDialog') } // 关闭 const handleClose = () => { state.handleClose = false } return { ...toRefs(state), handleClose, handleSubmit, handleRemove, handleChange, handleCancel, handlePeopleUpload, handleDownLoadTemplate, } }, }) </script> <style lang="scss" scoped> .fail-dialog { .fail-title { margin: 0px 0 10px; } :deep() { .ym-dialog__body { padding: 10px 20px 20px; } } } :deep() { .ym-dialog { .ym-dialog__title { float: left; } } } .upload-footer { display: flex; justify-content: center; padding-bottom: 20px; } </style>
src\app\plan\api\organization\project.js
//上传文件-规划计划模板 export const uploadPlanFileApi = (data) => {
return request({
url: `${
plan}/prog/importProg`, method: 'post', data, headers: {
'Content-Type': 'multipart/from-data', }, }) }
5、本地下载-public下的file文件夹
src\utils\util.js
//文件流导出数据处理 export const downLoadxls = (res, fileName) => {
let name = fileName if (res.headers['content-disposition']) {
const contentDisposition = res.headers['content-disposition'].split('=') name = (contentDisposition && decodeURI(contentDisposition[1])) || '' } const file = new File([res.data], name, res.data) const href = URL.createObjectURL(file) const aTag = document.createElement('a') aTag.download = file.name aTag.target = '_blank' aTag.href = href aTag.click() URL.revokeObjectURL(href) } //本地文件下载 下载的模板文件放在public下的file文件夹中 const configInfo = sessionStorage.getItem('configInfo') || '{}' const url = JSON.parse(configInfo)?.baseApiUrl const apiUrl = url ? `${
url.split('kjapi')[0] + 'cmn/science/'}` : '/' export const downFile = (fileName) => {
const anchor = document.createElement('a') anchor.href = `${
apiUrl}static/file/${
fileName}` anchor.setAttribute('download', fileName) anchor.innerHTML = 'downloading...' anchor.style.display = 'none' document.body.appendChild(anchor) setTimeout(() => {
anchor.click() document.body.removeChild(anchor) setTimeout(() => {
self.URL.revokeObjectURL(anchor.href) }, 250) }, 66) }
6、获取会话数据-sessionStorage.getItem 和 JSON.parse
src\utils\getOrgLevel.js
export const getOrgLevel = () => {
const loginUserInfo = JSON.parse(sessionStorage.getItem('loginUserInfo')) const orgNo = loginUserInfo?.orgNo if (!orgNo) {
return '' }else if (orgNo === '0000') {
return '01' // 总部 }else if (orgNo.length === 4) {
return '02' // 省级 }else if (orgNo.length === 8) {
return '03' // 市级 }else if (orgNo.length === 12) {
return '04' // 县级 } }
7、表单禁止输入特殊字符
src\utils\validate.ts
import {
ElMessage } from 'element-plus' import {
validatorSpecialCharacter,filterSpecialCharacterAction } from './filter' // 禁止输入框特殊字符校验 export function replaceCommonText(e: any) {
if (e.length) {
const val = e.trim() if (!val) {
ElMessage({
message: '请输入有效内容', type: 'warning', }) return } const err: any = validatorSpecialCharacter(e) if (err) {
ElMessage({
message: err.message, type: 'warning', }) const y = filterSpecialCharacterAction(val) return y } else {
return e } } }
src\utils\filter.js
/* eslint-disable */ // 特殊字符 敏感词检验过滤 import {
init } from './deailFilter' let regObj = {
urlReg: /\+|\?|#|\*|%2B|%20|%2F|%3F|%25|%23|%26|%3D|%27|%26|%22|%28|%29|%2a|%2b|%2d|%30/, htmlReg: /object|comment| |"|&|'|/|<|>|Æ|Á|Â|À|Å|Ã|Ä|Ç|Ð|É|Ê|È|Ë|Í|Î|Ì|Ï|Ñ|Ó|Ô|Ò|Ø|Õ|Ö|Þ|Ú|Û|Ù|Ü|Ý|á|â|æ|à|å|ã|ä|ç|é|ê|è|ð|ë|í|î|ì|ï|ñ|ó|ô|ò|ø|õ|ö|ß|þ|ú|û|ù|ü|ý|ÿ|¢|\\""|&|'/, jsReg: /,|\||{|}|%|<|>|&|""|'|\/|\\|\\r|\\n|\\\\|\\t|\\f|\\b|!|@|#|\$|\^|\*|\(|\)|~|:|;|\\`|-|=|\[|\]|javascript|script|function|jscript|vbscript|onfocus|onblur|location|document|window|onclick|href|<!--|--|->|\/\\\\\\\*|\\\\\\\*\/|onfocus|\/\/|onerror|\/\*|data:|\\u003e|\\u003c|eval|url|expr|URLUnencoded|referrer|write\(.\)|writeln|body\.innerHtml|execScript|navigate|srcdoc|%0a|<\/|\.|_|·|!|¥|…|【|】|、|;|‘|’|:|“|”|,|。|、|《|》|?/, sqlReg: /\\\*|--|%28|\)|\/\/|\/\*|\/\\\*\\\\*/, replaceStrs: [ '//', '/*', '</', '/\\*', 'net +user', 'net +localgroup +administrators', 'information_schema.columns', 'netlocalgroup administrators', 'body.innerHtml', '()', '(', ')', 'null', 'NULL', 'Null', ], } const sqlKeyword = [ 'and', 'or', 'exec', 'execute', 'insert', 'select', 'delete', 'update', 'alter', 'create', 'drop', 'count', 'chr', 'char', 'asc', 'desc', 'mid', 'substring', 'master', 'truncate', 'declare', 'xp_cmdshell', 'restore', 'backup', 'net user', 'like', 'table', 'from', 'grant', 'use', 'column_name', 'group_concat', 'table_schema', 'union', 'where', 'order', 'by', 'join', 'modify', 'into', 'substr', 'ascii', 'having', ] const htmlTag = [ 'a', 'iframe', 'body', 'form', 'base', 'img', 'style', 'div', 'meta', 'link', 'input', 'br', ] const jsFunction = [ 'open', 'confirm', 'prompt', 'setInterval', 'setTimeout', 'alert', ] let jsFunctionStr = (() => {
let regArr = [] jsFunction.forEach((item) => {
regArr.push(`${
item}\\(.*\\)`) }) return regArr.join('|') })() let htmlTagRegStr = (() => {
let regArr = []
htmlTag.forEach((item) => {
regArr.push(`<${
item}`) regArr.push(`${
item}>`) }) return regArr.join('|') })() regObj.jsFunctionReg = new RegExp(jsFunctionStr) regObj.htmlTagReg = new RegExp(htmlTagRegStr, 'i') regObj.sqlKeywordReg = new RegExp(sqlKeyword.join('\\s|') + '\\s', 'i') const reg = copyReg(regObj) init(reg) // 全局敏感词校验方法 export function validatorSpecialCharacter(value) {
if (!isNaN(value)) return false if (typeof value !== 'string') return false // 只校验字符串 value = String(value).trim() if (value === '') return false // 空不检验 if (reg.urlReg.test(value)) {
return {
message: '不能包含特殊字符', reg: reg.urlReg, } } if (reg.htmlReg.test(value)) {
return {
message: '不能包含关键字', reg: reg.htmlReg, } } if (reg.jsReg.test(value)) {
return {
message: '不能包含特殊字符', reg: reg.jsReg, } } if (reg.sqlReg.test(value)) {
return {
message: '不能包含特殊字符', reg: reg.sqlReg, } } if (reg.sqlKeywordReg.test(value)) {
return {
message: '不能包含关键字', msg: '不能包含SQL语句', reg: reg.sqlKeywordReg, } } if (reg.htmlTagReg.test(value)) {
return {
msg: '不能包含HTML标签', message: '不能包含关键字', reg: reg.htmlTagReg, } } if (reg.jsFunctionReg.test(value)) {
return {
msg: '不能包含JS方法', message: '不能包含关键字', reg: reg.jsFunctionReg, } } let str = reg.replaceStrs.find((val) => {
return value.indexOf(val) !== -1 }) if (str) {
return {
message: '不能包含关键字', str: str, reg: str, } } return false } function isArray(data) {
return Object.prototype.toString.call(data) === '[object Array]' } function isObject(data) {
return Object.prototype.toString.call(data) === '[object Object]' } // 过滤特殊字符的方法 export function filterSpecialCharacterAction(data) {
if (isArray(data) || isObject(data)) {
for (const key in data) {
data[key] = filterSpecialCharacterAction(data[key]) } } else {
let err = validatorSpecialCharacter(data) if (err) {
if (err.reg) {
return filterSpecialCharacterAction(data.replace(err.reg, '')) } if (err.str) {
return filterSpecialCharacterAction(data.replace(err.str, '')) } } } return data } function copyReg(regObj) {
let result = {
} for (const key in regObj) {
result[key] = regObj[key] } return result } // 响应数据过滤数据 export const filterSpecialCharacter = (data) => {
let result = data return result }
到此这篇vue中,el-table树形数据与懒加载【实例】(二)——封装拖拽上传el-upload & 本地下载模板-public下的file文件夹 & JSON.parse转对象 & 表单禁止输入特殊字符的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/10675.html