@@ -263,6 +263,12 @@ export default { | |||||
return this.handleResult(err, res) | return this.handleResult(err, res) | ||||
}, | }, | ||||
async HTTP_UPLOAD2(url,filePath, formData) { | |||||
const [err, res] = await this.UPLOAD(url, filePath, formData) | |||||
return this.handleResult(err, res) | |||||
}, | |||||
// 封装的文件下载,集成了验证信息 | // 封装的文件下载,集成了验证信息 | ||||
// 返回临时文件路径或 null | // 返回临时文件路径或 null | ||||
@@ -654,6 +660,7 @@ export default { | |||||
title: '登录状态无效,正在跳转到登录页…', | title: '登录状态无效,正在跳转到登录页…', | ||||
icon: 'none' | icon: 'none' | ||||
}) | }) | ||||
return null | |||||
this.CLEAR_GLOBAL() | this.CLEAR_GLOBAL() | ||||
uni.reLaunch({ | uni.reLaunch({ | ||||
url: '/pages/login' | url: '/pages/login' | ||||
@@ -673,6 +680,14 @@ export default { | |||||
return null | return null | ||||
} | } | ||||
if(result.data.code != 200){ | |||||
uni.hideLoading() | |||||
uni.showToast({ | |||||
title: result.data.info, | |||||
icon: 'none' | |||||
}) | |||||
return null | |||||
} | |||||
return result.data.data | return result.data.data | ||||
}, | }, | ||||
@@ -3,14 +3,13 @@ | |||||
<view class="grid col-4 grid-square flex-sub"> | <view class="grid col-4 grid-square flex-sub"> | ||||
<view | <view | ||||
v-for="(item, index) in imgList" | v-for="(item, index) in imgList" | ||||
@tap="viewImg" | |||||
@tap="viewImg(index)" | |||||
:key="index" | :key="index" | ||||
class="bg-img" | class="bg-img" | ||||
> | > | ||||
<!-- {{API + '/user/img?data=' + (path.path ? path.path : path)}} --> | |||||
<image | <image | ||||
v-if="showfile()" | v-if="showfile()" | ||||
:src="API + item.url" | |||||
:src="item.id?CONFIG('webHost')+item.url:item.url" | |||||
mode="aspectFill" | mode="aspectFill" | ||||
></image> | ></image> | ||||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" style="width: 18px; height: 18px; font-size: 24px"> | <view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" style="width: 18px; height: 18px; font-size: 24px"> | ||||
@@ -90,8 +89,26 @@ export default { | |||||
}, | }, | ||||
uploadImage(){ | uploadImage(){ | ||||
// 单图上传 多图没写 | |||||
// let array = | |||||
// function apiFn(item){ | |||||
// return this.HTTP_POST('StuInfoFresh/savePhoto', postData, '图片上传失败!').then((data) => { | |||||
// if (data) { | |||||
// reslove([{ | |||||
// url:data.Url, | |||||
// id:data.AnnexesFileId | |||||
// }]) | |||||
// }else{ | |||||
// reject('图片上传失败!') | |||||
// } | |||||
// }) | |||||
// } | |||||
// return this.promiseAllLimit(5,array,apiFn) | |||||
// 单图上传 | |||||
return new Promise(async (reslove,reject)=>{ | return new Promise(async (reslove,reject)=>{ | ||||
let hasNotUpdatedList = this.imgList.every(item=>item.id) | |||||
if(hasNotUpdatedList){ | |||||
reslove(this.imgList) | |||||
} | |||||
if(this.imgList.length){ | if(this.imgList.length){ | ||||
var postData = { | var postData = { | ||||
Base64Url: await this.imgToBase64(this.imgList[0].url) | Base64Url: await this.imgToBase64(this.imgList[0].url) | ||||
@@ -110,11 +127,59 @@ export default { | |||||
reslove("") | reslove("") | ||||
} | } | ||||
}) | }) | ||||
}, | |||||
/** | |||||
* @description 控制promise.all并发数量 | |||||
* @param limit 并发数 | |||||
* @param array 参数列表 | |||||
* @param apiFn 执行函数 | |||||
* @returns {Promise<Awaited<unknown>[]>} | |||||
*/ | |||||
async promiseAllLimit(limit, array, apiFn) { | |||||
const ret = [] // 用于存放所有的promise实例 | |||||
const executing = [] // 用于存放目前正在执行的promise | |||||
for (const item of array) { | |||||
const p = apiFn(item) | |||||
ret.push(p) | |||||
if (limit <= array.length) { | |||||
// then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除 | |||||
const e = p.then(() => executing.splice(executing.indexOf(e), 1)) | |||||
executing.push(e) | |||||
if (executing.length >= limit) { | |||||
// 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更, | |||||
// 状态变更后,就会执行上面then的回调,将该promise从executing中删除, | |||||
// 然后再进入到下一次for循环,生成新的promise进行补充 | |||||
await Promise.race(executing) | |||||
} | |||||
} | |||||
} | |||||
return Promise.all(ret) | |||||
}, | |||||
validate(array){ | |||||
// let type = array.every(item=>{ | |||||
// return item.type && item.type.substring(0,6) == "image/" | |||||
// }) | |||||
// if(!type){ | |||||
// this.TOAST('文件类型错误'); | |||||
// return false | |||||
// } | |||||
let size = array.every(item=>{ | |||||
return item.size && item.size <= 10 * 1024 * 1024 | |||||
}) | |||||
if(!size){ | |||||
this.TOAST('文件大小不得超过10M'); | |||||
return false | |||||
} | |||||
return true | |||||
}, | }, | ||||
imgToBase64(url){ | imgToBase64(url){ | ||||
return new Promise((resolve,reject)=>{ | return new Promise((resolve,reject)=>{ | ||||
if(!url){ | |||||
resolve("") | |||||
} | |||||
var canvas = document.createElement('canvas'), | var canvas = document.createElement('canvas'), | ||||
ctx = canvas.getContext('2d'), | ctx = canvas.getContext('2d'), | ||||
img = new Image; | img = new Image; | ||||
@@ -152,8 +217,8 @@ export default { | |||||
viewImg(index) { | viewImg(index) { | ||||
uni.previewImage({ | uni.previewImage({ | ||||
urls: this.imgList, | |||||
current: this.imgList[index], | |||||
urls: this.imgList.map(item=>item.id?this.CONFIG('webHost')+item.url:item.url), | |||||
current: this.imgList[index].id?this.CONFIG('webHost')+this.imgList[index].url:this.imgList[index].url, | |||||
}); | }); | ||||
}, | }, | ||||
@@ -0,0 +1,300 @@ | |||||
<template> | |||||
<view class="cu-form-group"> | |||||
<view class="grid col-4 grid-square flex-sub"> | |||||
<view | |||||
v-for="(item, index) in imgList" | |||||
@tap="viewImg(item)" | |||||
:key="index" | |||||
class="bg-img" | |||||
> | |||||
<!-- {{API + '/user/img?data=' + (path.path ? path.path : path)}} --> | |||||
<!-- <image | |||||
v-if="showfile()" | |||||
:src="API + item.url" | |||||
mode="aspectFill" | |||||
></image> --> | |||||
<l-icon v-if="showfile()" type="text" /> | |||||
<text class="file-name">{{item.name}}</text> | |||||
<view v-if="!readonly" @tap.stop="delImg(index)" class="cu-tag bg-red" style="width: 18px; height: 18px; font-size: 24px"> | |||||
<l-icon | |||||
type="close" | |||||
style="width: 18px; height: 18px; font-size: 12px" | |||||
/> | |||||
</view> | |||||
</view> | |||||
<view | |||||
v-if="!readonly && imgList.length < Number(number)" | |||||
@tap="chooseImg" | |||||
class="solids" | |||||
> | |||||
<l-icon type="file" /> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
props: { | |||||
number: { default: 1 }, | |||||
readonly: {}, | |||||
value: { default: () => [] }, | |||||
folderId:{}, | |||||
}, | |||||
data(){ | |||||
return{ | |||||
imgList:[], | |||||
} | |||||
}, | |||||
methods: { | |||||
delImg(index) { | |||||
this.LOADING('正在删除…'); | |||||
const newList = JSON.parse(JSON.stringify(this.imgList)); | |||||
this.HTTP_POST('StuInfoFresh/deleteFiles', {id:this.imgList[index].id},"文件删除失败").then((data) => { | |||||
this.HIDE_LOADING(); | |||||
if (data) { | |||||
newList.splice(index, 1); | |||||
this.imgList = newList | |||||
this.$emit("update:value", newList); | |||||
this.$emit("input", newList); | |||||
this.$emit("change"); | |||||
this.$emit("del"); | |||||
} | |||||
}) | |||||
}, | |||||
showfile() { | |||||
return true; | |||||
}, | |||||
chooseImg() { | |||||
uni.chooseFile({ | |||||
// count: (Number(this.number) - this.imgList.length), | |||||
count: 1, | |||||
type:"all", | |||||
success: async (res) => { | |||||
let {tempFilePaths,tempFiles} = res | |||||
if(!this.validate(tempFiles))return | |||||
let uploadImageRes = await this.uploadImage(tempFilePaths[0]) | |||||
let newList = this.imgList || [] | |||||
if(uploadImageRes){ | |||||
newList = JSON.parse(JSON.stringify(newList)).concat(uploadImageRes); | |||||
} | |||||
this.imgList = newList | |||||
this.$emit("update:value", newList); | |||||
this.$emit("input", newList); | |||||
this.$emit("change",newList); | |||||
this.$emit("add"); | |||||
}, | |||||
}); | |||||
}, | |||||
uploadImage(url){ | |||||
// 文件上传 | |||||
return new Promise(async (reslove,reject)=>{ | |||||
this.LOADING('正在上传…'); | |||||
this.HTTP_UPLOAD2('StuInfoFresh/upload', url||this.imgList[0].url,{folderId:this.folderId}).then((data) => { | |||||
this.HIDE_LOADING(); | |||||
if (data) { | |||||
// this.HTTP_GET('StuInfoFresh/upload', {fileId:data}) | |||||
reslove([{ | |||||
id:data.F_Id, | |||||
name:data.F_FileName, | |||||
url:data.F_FilePath | |||||
}]) | |||||
}else{ | |||||
reject('上传失败!') | |||||
} | |||||
}) | |||||
}) | |||||
}, | |||||
// 图片文件转为 base64 | |||||
getPictureBase64(file) { | |||||
return new Promise((resolve, reject) => { | |||||
const reader = new FileReader(); | |||||
reader.readAsDataURL(file); | |||||
reader.onload = () => resolve(reader.result); | |||||
reader.onerror = (error) => reject(error); | |||||
}); | |||||
}, | |||||
base64ToBlob (base64) { | |||||
const parts = base64.split(";base64,"); | |||||
const contentType = parts[0].split(":")[1]; | |||||
const raw = window.atob(parts[1]); | |||||
const rawLength = raw.length; | |||||
const uInt8Array = new Uint8Array(rawLength); | |||||
for (let i = 0; i < rawLength; i += 1) { | |||||
uInt8Array[i] = raw.charCodeAt(i); | |||||
} | |||||
return new Blob([uInt8Array], { type: contentType }); | |||||
}, | |||||
imgToBase64(url){ | |||||
return new Promise((resolve,reject)=>{ | |||||
var canvas = document.createElement('canvas'), | |||||
ctx = canvas.getContext('2d'), | |||||
img = new Image; | |||||
img.crossOrigin = 'Anonymous'; | |||||
img.onload = function () { | |||||
canvas.height = img.height; | |||||
canvas.width = img.width; | |||||
ctx.drawImage(img, 0, 0); | |||||
var dataURL = canvas.toDataURL('image/png'); | |||||
canvas = null; | |||||
resolve(dataURL) | |||||
}; | |||||
img.src = url; | |||||
}) | |||||
}, | |||||
ceshi(){ | |||||
function apiFn(params){ | |||||
return new Promise((resolve,reject)=>{ | |||||
this.LOADING('正在上传…'); | |||||
this.HTTP_UPLOAD2('StuInfoFresh/upload', params.url,{folderId:this.folderId}).then((data) => { | |||||
this.HIDE_LOADING(); | |||||
if (data) { | |||||
// this.HTTP_GET('StuInfoFresh/upload', {fileId:data}) | |||||
this.imgList[params.index] = [{ | |||||
id:data.F_Id, | |||||
name:data.F_FileName, | |||||
url:data.F_FilePath | |||||
}] | |||||
reslove(this.imgList[params.index]) | |||||
}else{ | |||||
reject('上传失败!') | |||||
} | |||||
}) | |||||
}) | |||||
} | |||||
let array = this.imgList.map(item=>{ | |||||
if(item.id){ | |||||
return "" | |||||
}else{ | |||||
return { | |||||
url:"learun/adms/annexes/upload" | |||||
} | |||||
} | |||||
}) | |||||
this.promiseAllLimit(2,[1,2,3,4,5,6,7,8,9],a).then(res=>{ | |||||
console.log(res) | |||||
}) | |||||
}, | |||||
/** | |||||
* @description 控制promise.all并发数量 | |||||
* @param limit 并发数 | |||||
* @param array 参数列表 | |||||
* @param apiFn 执行函数 | |||||
* @returns {Promise<Awaited<unknown>[]>} | |||||
*/ | |||||
async promiseAllLimit(limit, array, apiFn) { | |||||
const ret = [] // 用于存放所有的promise实例 | |||||
const executing = [] // 用于存放目前正在执行的promise | |||||
for (const item of array) { | |||||
const p = apiFn(item) | |||||
ret.push(p) | |||||
if (limit <= array.length) { | |||||
// then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除 | |||||
const e = p.then(() => executing.splice(executing.indexOf(e), 1)) | |||||
executing.push(e) | |||||
if (executing.length >= limit) { | |||||
// 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更, | |||||
// 状态变更后,就会执行上面then的回调,将该promise从executing中删除, | |||||
// 然后再进入到下一次for循环,生成新的promise进行补充 | |||||
await Promise.race(executing) | |||||
} | |||||
} | |||||
} | |||||
return Promise.all(ret) | |||||
}, | |||||
validate(array){ | |||||
// let type = array.every(item=>{ | |||||
// return item.type && item.type.substring(0,6) == "image/" | |||||
// }) | |||||
// if(!type){ | |||||
// this.TOAST('文件类型错误'); | |||||
// return false | |||||
// } | |||||
let size = array.every(item=>{ | |||||
return item.size && item.size <= 10 * 1024 * 1024 | |||||
}) | |||||
if(!size){ | |||||
this.TOAST('文件大小不得超过10M'); | |||||
return false | |||||
} | |||||
return true | |||||
}, | |||||
viewImg(item) { | |||||
window.location.href = this.CONFIG("webHost")+item.url | |||||
}, | |||||
// previewFile() { | |||||
// var file = document.querySelector('input[type=file]').files[0]; | |||||
// var reader = new FileReader(); | |||||
// // fileReader.readAsDataURL(blob); | |||||
// // fileReader.onerror = () => { | |||||
// // reject(new Error('blobToBase64 error')); | |||||
// // }; | |||||
// // var encodedData = window.btoa("Hello, world"); | |||||
// reader.onloadend = function () { | |||||
// //$('#PhotoImg').attr('src', reader.result); | |||||
// var postData = { | |||||
// Base64Url: reader.result | |||||
// } | |||||
// this.HTTP_POST(config.webapi + "StuInfoFresh/savePhoto", postData, (data) => { | |||||
// if (data) { | |||||
// $('#Photo').val(data.AnnexesFileId); | |||||
// $('#PhotoImg').attr('src', config.web + data.Url); | |||||
// } else { | |||||
// learun.layer.toast('采集照片信息失败!'); | |||||
// } | |||||
// }); | |||||
// } | |||||
// if (file) { | |||||
// reader.readAsDataURL(file); | |||||
// } | |||||
// }, | |||||
}, | |||||
created() { | |||||
// id name | |||||
console.log(this.value) | |||||
this.imgList = JSON.parse(JSON.stringify(this.value.map(item=>{ | |||||
return { | |||||
id:item.F_Id, | |||||
name:item.F_FileName, | |||||
url:item.F_FilePath | |||||
} | |||||
}))) | |||||
// [{url:"",id:""}] | |||||
} | |||||
}; | |||||
</script> | |||||
<style scoped> | |||||
.file-name{ | |||||
position: absolute; | |||||
bottom: 0; | |||||
width: 100%; | |||||
color: #606266; | |||||
font-size: 13px; | |||||
text-align: center; | |||||
text-overflow: ellipsis; | |||||
overflow: hidden; | |||||
white-space: nowrap; | |||||
} | |||||
</style> |
@@ -22,12 +22,13 @@ export default { | |||||
// ], | // ], | ||||
"apiHost": [ | "apiHost": [ | ||||
// "http://localhost:31173/" | // "http://localhost:31173/" | ||||
"http://192.168.10.58:8012/" | |||||
"http://192.168.10.85:8088/" | |||||
], | ], | ||||
"webHost":"http://192.168.10.85:8087/", | |||||
// 开发环境下自动填充登录账号密码,与接口地址一一对应,只在开发环境下显示 | // 开发环境下自动填充登录账号密码,与接口地址一一对应,只在开发环境下显示 | ||||
"devAccount": [ | "devAccount": [ | ||||
// 20201130230 | |||||
{ username: "420528200606205026", password: "www.qj.com" } | |||||
// 20201130230 21364200000400266 老师 420528196310072253 学生 420528200606205026 | |||||
{ username: "420528200507261428", password: "www.qj.com" } | |||||
], | ], | ||||
//是否分布式部署 指WebApi与Web不在一台服务器 | //是否分布式部署 指WebApi与Web不在一台服务器 | ||||
"isDistributed":true, | "isDistributed":true, | ||||
@@ -14,7 +14,7 @@ | |||||
<view style="flex: 1;"> | <view style="flex: 1;"> | ||||
<view style="display: flex;"> | <view style="display: flex;"> | ||||
<view style="flex: 1;color: #303133;font-size: 14px;padding: 8px 0;"> | <view style="flex: 1;color: #303133;font-size: 14px;padding: 8px 0;"> | ||||
<view class="wrap1">{{item.bigGroup}}</view> | |||||
<view class="wrap1">{{item.bigGroup}}{{item.smallGroup?"-"+item.smallGroup:""}}</view> | |||||
<view style="color: #909399;font-size: 12px;"> | <view style="color: #909399;font-size: 12px;"> | ||||
<view> | <view> | ||||
餐次:{{item.seg||"--"}} | 餐次:{{item.seg||"--"}} | ||||
@@ -231,7 +231,8 @@ | |||||
this.multipleData.StartTime = this.dateRange.start | this.multipleData.StartTime = this.dateRange.start | ||||
this.multipleData.EndTime = this.dateRange.end | this.multipleData.EndTime = this.dateRange.end | ||||
} else{ | } else{ | ||||
this.multipleData.StartTime = "" | |||||
this.multipleData.EndTime = "" | |||||
} | } | ||||
// console.log(this.dateRange,"==========") | // console.log(this.dateRange,"==========") | ||||
@@ -63,7 +63,9 @@ | |||||
<view class="welDel" @click="del('StuInfoFreshEmergePeopleEntities', i)"><text class="text-xxl cuIcon cuIcon-move"></text></view> | <view class="welDel" @click="del('StuInfoFreshEmergePeopleEntities', i)"><text class="text-xxl cuIcon cuIcon-move"></text></view> | ||||
</view> | </view> | ||||
</view> | </view> | ||||
<view class="btn" @click="tapBtn">保存</view> | |||||
<view class="welT" style="padding-top: 10px;">附件</view> | |||||
<uploadFile v-if="uploadVisiable" :number="10" :folderId="queryData.ID" :value="fileList"></uploadFile> | |||||
<view class="btn" @click="submit">保存</view> | |||||
</view> | </view> | ||||
</template> | </template> | ||||
@@ -71,11 +73,16 @@ | |||||
import moment from 'moment'; | import moment from 'moment'; | ||||
import get from 'lodash/get'; | import get from 'lodash/get'; | ||||
import set from 'lodash/set'; | import set from 'lodash/set'; | ||||
import uploadFile from '@/components/upload-file.vue' | |||||
export default { | export default { | ||||
components:{ | |||||
uploadFile, | |||||
}, | |||||
data() { | data() { | ||||
return { | return { | ||||
photo:[], | photo:[], | ||||
uploadVisiable:true, | |||||
fileList:[], | |||||
uploadVisiable:false, | |||||
imgSrc: '', | imgSrc: '', | ||||
scheme: { | scheme: { | ||||
PartyFaceNo: { | PartyFaceNo: { | ||||
@@ -141,8 +148,10 @@ export default { | |||||
_this.queryData.StuInfoFreshFamilyEntities = _this.COPY(res.StuInfoFreshFamilyList); | _this.queryData.StuInfoFreshFamilyEntities = _this.COPY(res.StuInfoFreshFamilyList); | ||||
_this.queryData.StuInfoFreshEmergePeopleEntities = _this.COPY(res.StuInfoFreshEmergePeopleList); | _this.queryData.StuInfoFreshEmergePeopleEntities = _this.COPY(res.StuInfoFreshEmergePeopleList); | ||||
_this.queryData.ID = res.StuInfoFreshEntity.ID; | _this.queryData.ID = res.StuInfoFreshEntity.ID; | ||||
_this.queryData.Photo = res.StuInfoFreshEntity.Photo; | _this.queryData.Photo = res.StuInfoFreshEntity.Photo; | ||||
_this.photo = [{url:res.StuInfoFreshEntity.Photo}]; | |||||
_this.photo = [{url:res.StuInfoFreshEntity.Url,id:res.StuInfoFreshEntity.Photo}]; | |||||
_this.fileList = res.StuInfoFreshEntity.FilesList | |||||
_this.refreshComponent() | _this.refreshComponent() | ||||
_this.queryData.telephone = res.StuInfoFreshEntity.telephone; | _this.queryData.telephone = res.StuInfoFreshEntity.telephone; | ||||
_this.queryData.FamilyAddress = res.StuInfoFreshEntity.FamilyAddress; | _this.queryData.FamilyAddress = res.StuInfoFreshEntity.FamilyAddress; | ||||
@@ -150,16 +159,14 @@ export default { | |||||
// _this.imgSrc = this.API.slice(0,-1) + res.Url; | // _this.imgSrc = this.API.slice(0,-1) + res.Url; | ||||
}); | }); | ||||
}, | }, | ||||
async tapBtn() { | |||||
async submit() { | |||||
this.LOADING('正在提交数据…'); | this.LOADING('正在提交数据…'); | ||||
let res = await this.$refs["upload"].uploadImage() | let res = await this.$refs["upload"].uploadImage() | ||||
if(res){ | |||||
this.queryData.Photo = res[0]["AnnexesFileId"]; | |||||
if(res&&res.length){ | |||||
this.queryData.Photo = res[0]["id"]; | |||||
} | } | ||||
console.log(this.queryData) | |||||
this.HTTP_GET('StuInfoFresh/saveStuInfoFresh', this.queryData, '加载数据时出错').then(res => { | |||||
this.HTTP_GET('StuInfoFresh/saveStuInfoFresh', this.queryData).then(res => { | |||||
this.HIDE_LOADING(); | this.HIDE_LOADING(); | ||||
// console.log(res); | |||||
if (res) { | if (res) { | ||||
this.TOAST('保存成功'); | this.TOAST('保存成功'); | ||||
} | } | ||||