2021SC@SDUSC
智能研究中心快递柜学习笔记11
commonuploadfile实现文件上传,
import { getFileAccessHttpUrl } from '@/api/manage'
const getFilecommonuploadfileName=(path)=>{
if(path.lastIndexOf("\\")>=0){
let reg=new RegExp("\\\\","g");
path = path.replace(reg,"/");
}
return path.substring(path.lastIndexOf("/")+1);
}
const uidGenerator=()=>{
return '-'+parseInt(Math.random()*10000+1,10);
}
const getFilePaths=(uploadFiles)=>{
let arr = [];
if(!uploadFiles){
return ""
}
for(let a=0;a<uploadFiles.length;a++){
arr.push(uploadFiles[a].response.message)
}
if(arr && arr.length>0){
return arr.join(",")
}
return ""
}
const getUploadFileList=(paths)=>{
if(!paths){
return [];
}
let fileList = [];
let arr = paths.split(",")
for(let a=0;a<arr.length;a++){
if(!arr[a]){
continue
}else{
fileList.push({
uid:uidGenerator(),
name:getFileName(arr[a]),
status: 'done',
url: getFileAccessHttpUrl(arr[a]),
response:{
status:"history",
message:arr[a]
}
})
}
}
return fileList;
}
export {getFilePaths,getUploadFileList}
文件上传的原理分析
文件上传的必要前提
a、表单的method必须是post
b、表单的enctype属性必须是multipart/form-data类型的。
enctype默认值:application/x-www-form-urlencoded
作用:告知服务器,请求正文的MIME类型
ServletRequest.getParameter(String name);该方法是专门读取该类型的方法
乱码问题
a、普通字段的乱码 FileItem.getString(String charset);编码要和客户端一致
b、上传的中文文件名乱码 request.setCharacterEncoding("UTF-8");编码要和客户端一致
限制文件的大小
a、 ServletFileUpload.setFileSizeMax(3*1024*1024);//设置单个文件上传的大小
b、ServletFileUpload.setSizeMax(6*1024*1024);//多文件上传时总大小限制
JEditableTableUtil
获取指定的 $refs 对象,有时候可能会遇到组件未挂载到页面中的情况,导致无法获取 $refs 中的某个对象,这个方法可以等待挂载完成之后再返回 $refs 的对象,避免报错。
export function getRefPromise(vm, name) {
return new Promise((resolve) => {
(function next() {
let ref = vm.$refs[name]
if (ref) {
resolve(ref)
} else {
setTimeout(() => {
next()
}, 10)
}
})()
})
}
一次性验证主表单和所有的次表单
@param form 主表单 form 对象
@param cases 接收一个数组,每项都是一个JEditableTable实例
@returns {Promise<any>}
export function validateFormAndTables(form, cases) {
if (!(form && typeof form.validateFields === 'function')) {
throw `form 参数需要的是一个form对象,而传入的却是${typeof form}`
}
let options = {}
return new Promise((resolve, reject) => {
// 验证主表表单
form.validateFields((err, values) => {
err ? reject({ error: VALIDATE_NO_PASSED }) : resolve(values)
})
}).then(values => {
Object.assign(options, { formValue: values })
// 验证所有子表的表单
return validateTables(cases)
}).then(all => {
Object.assign(options, { tablesValue: all })
return Promise.resolve(options)
}).catch(error => {
return Promise.reject(error)
})
}
验证并获取一个或多个表格的所有值
@param cases 接收一个数组,每项都是一个JEditableTable实例
@param deleteTempId 是否删除临时ID,如果设为true,行编辑就不返回新增行的ID,ID需要后台生成
export function validateTables(cases, deleteTempId) {
if (!(cases instanceof Array)) {
throw `'validateTables'函数的'cases'参数需要的是一个数组,而传入的却是${typeof cases}`
}
return new Promise((resolve, reject) => {
let tables = []
let index = 0;
if(!cases || cases.length === 0){
resolve()
}
(function next() {
let vm = cases[index]
vm.getAll(true, deleteTempId).then(all => {
tables[index] = all
// 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验
if (++index === cases.length) {
resolve(tables)
} else (
next()
)
}, error => {
// 出现未验证通过的表单,不再进行下一步校验,直接返回失败并跳转到该表格
if (error === VALIDATE_NO_PASSED) {
// 尝试获取tabKey,如果在ATab组件内即可获取
let paneKey;
let tabPane = getVmParentByName(vm, 'ATabPane')
if (tabPane) {
paneKey = tabPane.$vnode.key
}
reject({error: VALIDATE_NO_PASSED, index, paneKey})
}
reject(error)
})
})()
})
}
LunarFullCalendarUtil定义了日历视图的各种类型
month: 'month', // 月视图
basicWeek: 'basicWeek', // 基础周视图
basicDay: 'basicDay',// 基础天视图
agendaWeek: 'agendaWeek', // 议程周视图
agendaDay: 'agendaDay', // 议程天视图
定义默认视图为月视图
const defaultView = calendarViewType.month
定义日历默认配置
const defaultSettings = {
locale: 'zh-cn',
// 按钮文字
buttonText: {
today: '今天',
month: '月',
week: '周',
day: '日'
},
// 头部排列方式
header: {
left: 'prev,next, today',
center: 'title',
right: 'hide, custom, month,agendaWeek,agendaDay'
},
//点击今天日列表图
eventLimitClick: 'day',
// 隐藏超出的事件
eventLimit: true,
// 设置每周开始日期为周日
firstDay: 0,
// 默认显示视图
defaultView,
timeFormat: 'H:mm',
axisFormat: 'H:mm',
// agenda视图下是否显示all-day
allDaySlot: true,
// agenda视图下all-day的显示文本
allDayText: '全天',
// 时区默认本地的
timezone: 'local',
// 周视图和日视同的左侧时间显示
slotLabelFormat: 'HH:mm',
// 设置第二天阈值
nextDayThreshold: '00:00:00',
}
还有一些增强方法
const CalendarMixins = {
data() {
return {
calenderCurrentViewType: defaultView
}
},
methods: {
getCalendarConfigEventHandler() {
return {
// 处理 view changed 事件
viewRender: (view, element) => {
let { type } = view
let lastViewType = this.calenderCurrentViewType
this.calenderCurrentViewType = type
if (typeof this.handleViewRender === 'function') {
this.handleViewRender(type, view, element)
}
if (lastViewType !== this.calenderCurrentViewType && typeof this.handleViewChanged === 'function') {
this.handleViewChanged(type, view, element)
}
},
}
},
/** 获取 LunarFullCalendar 实例,ref = baseCalendar */
getCalendar(fn) {
return getRefPromise(this, 'baseCalendar').then(fn)
},
calendarEmit(name, data) {
this.getCalendar(ref => ref.$emit(name, data))
},
/** 强制重新加载所有的事件(日程)*/
calendarReloadEvents() {
this.calendarEmit('reload-events')
}
}
}