This commit is contained in:
aihe 2023-12-12 08:50:19 +08:00
parent 86cfd4d71d
commit 572f62a0de
7 changed files with 394 additions and 20 deletions

5
common/api.js Normal file
View File

@ -0,0 +1,5 @@
export const host = '/TODO'
export default {
uploadFile: `${host}`
}

52
common/manageServer.js Normal file
View File

@ -0,0 +1,52 @@
import { goto } from "./untool";
import { showToast } from "./untool"
// 请求接口
function dealRequest(def, url, param) {
const promise = new Promise(function (resolve, reject) {
def.then(function (res) {
handleResponse(res, resolve, reject, url, param);
}, function (res) {
console.log('request url==========1', url)
console.log('request param==========1', param)
console.log('response ===========1', res);
showToast(`网络错误`)
reject(res)
})
})
// 统一提示 errmsg
promise.then(function (res) {
}, function (res) {
uni.hideLoading()
})
return promise;
}
// 处理响应
function handleResponse(res, resolve, reject, url, param) {
const orgRes = { ...res };
if ((res && res.respCode == 1)) {
resolve(res.respData)
} else {
if (res.respCode == '-1') { // 统一判断需要认证, 并作页面跳转
showToast(res.respMsg)
setTimeout(()=>{
goto(`TODO`, 1)
}, 3500)
return reject({ code: {} });
}
setTimeout(()=> {
showToast(`网络错误`)
}, 0)
reject({code: {}});
}
}
export {
dealRequest,
handleResponse
}

40
common/request.js Normal file
View File

@ -0,0 +1,40 @@
import { dealRequest } from "./manageServer"
import { showToast } from "./untool"
const corePostBase = (url, reqParams, options) => {
return new Promise((resolve, reject)=> {
uni.request({
url,
data: reqParams,
header: options,
method: 'POST',
success: (res)=> {
resolve(res)
},
fail: (e)=> {
reject(e)
}
})
})
}
const BaseParam = {}
// 请求处理
let corePost = function (url, params = {}, options = {}) {
let { tid } = Storage.get("MEMBER_SESSION") || {}
// 统一把emo转unicode
// emoUnicode(params)
const reqParams = {
...BaseParam,
...params,
}
return dealRequest(corePostBase(url, reqParams, options)).then(res => {
// 解析unicode
// emoUnicode(res, 2)
return res
})
}
export {
corePost
}

View File

@ -35,11 +35,15 @@ const setClipboardData = (val)=> {
uni.setClipboardData({
data: val,
success: () => {
uni.showToast({ title: "复制成功", icon: 'none' })
showToast({ title: "复制成功", icon: 'none' })
},
})
}
const showToast = (val)=> {
uni.showToast({ title: val, icon: 'none' })
}
const confirmModal = (title) => {
return new Promise((resolve)=> {
uni.showModal({ content: title, confirmColor: '#B12D29' }).then((res)=> {
@ -64,4 +68,5 @@ export {
setClipboardData,
confirmModal,
showLoading,
showToast
}

99
common/upload.js Normal file
View File

@ -0,0 +1,99 @@
import { handleResponse } from './manageServer.js'
import apiConfig from './api.js' //接口配置
import { showToast } from "./untool"
const chooseFile = function (action = 'chooseImage', opt = {}) {
let opts = {
// sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sizeType: ['compressed'],
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
...opt
}
return new Promise((resolve, reject) => {
uni[action]({
count: 1, // 默认9
...opts,
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths || [res.tempFilePath]
resolve(tempFilePaths)
},
fail: function (res) {
reject()
}
})
})
}
const doRequest = function (file) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${apiConfig.uploadFile}`,
fileType: 'image', // TODO
filePath: file,
name: 'file',
formData: {
// 'user': 'test'
},
success(res) {
try {
const data = JSON.parse(res.data)
handleResponse(data, resolve, reject)
} catch (error) {
reject()
}
},
fail() {
reject()
}
})
})
}
// 单 选择并上传文件
const coreUploadFile = function (action = 'chooseImage', opt = {}) {
return chooseFile(action, opt).then(async (files) => {
if (opt.asyncFileFun) {
const newFiles = await opt.asyncFileFun(files)
files = newFiles
}
uni.showLoading()
return doRequest(files[0]).then(res => {
return res
}).finally(()=> {
uni.hideLoading()
})
})
}
// 多 选择并上传文件
const coreMultiUploadFile = async (action = 'chooseImage', opt = {})=> {
let files = await chooseFile(action, opt)
files = files || []
const allDef = []
if (opt.asyncFileFun) {
const newFiles = await opt.asyncFileFun(files)
files = newFiles
}
uni.showLoading()
files.map(val=>{
const def = doRequest(val).then(res => {
return res
})
allDef.push(def)
})
try{
let resFiles = await Promise.all(allDef)
uni.hideLoading()
return resFiles
}catch(e){
uni.hideLoading()
return files
}
}
export {
coreUploadFile,
coreMultiUploadFile
}

View File

@ -0,0 +1,49 @@
<template>
<image :src="src" :mode="mode" :hidden="!loadFlag" @load="bindload"></image>
</template>
<script>
export default {
props: {
src: {
default () {
return ''
}
},
mode: {
default () {
return 'widthFix'
}
},
scale: {
default () {
return [1, 1] // 宽高比
}
},
},
data() {
return {
loadFlag: false,
imageHeight: 0,
}
},
created() {
},
onHide() {
},
destroyed() {},
methods: {
bindload: function(res) {
this.loadFlag = true
this.imageHeight = res.detail.height
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -1,21 +1,53 @@
<template>
<u-upload
:fileList="fileList1" name="formFilesTODO" :maxCount="max" :previewFullImage="fileType==fileTypeEnum.image"
@afterRead="afterRead" @delete="deletePic"
>
<slot></slot>
</u-upload>
<view>
<view v-if="!isSlot" @click="handleChooseFile" class="cam" style="">
<view class="">
<u-icon name="camera" size="50"></u-icon>
</view>
<view class="font-22">
<text>上传</text>
<text v-if="fileType==fileTypeEnum.image">照片</text>
<text v-if="fileType==fileTypeEnum.video">视频</text>
</view>
</view>
<view v-if="isSlot" @click="handleChooseFile">
<slot></slot>
</view>
<view v-for="(item) in list" style="margin-top: 10rpx;">
<view class="cdimg" @click="handleItem" data-index="{{index}}">
<tpx-image v-if="fileType==fileTypeEnum.image" :src="item" :mode="mode" :scale="scale"></tpx-image>
<video v-if="fileType==fileTypeEnum.video" :src="item"></video>
</view>
</view>
</view>
</template>
<script>
import { coreMultiUploadFile } from "@/common/upload"
import { showToast } from "@/common/untool"
const fileTypeEnum = {
all: "all",
// all: "all",
image: "image",
video: "video",
}
export default {
computed: {
list() {
let val = this.value
let res = []
if (typeof val == "object") {
res = val
}
if (typeof val == 'string' && val !== '') {
res = val.split(",")
}
return res
},
},
props: {
value: {
default () {
@ -24,16 +56,21 @@
},
fileType: {
default () {
return fileTypeEnum.all
return fileTypeEnum.image
}
},
max: {
default () {
pickMaxLen: { // 一次最多选择个数
default () {
return 5
}
},
maxLen: { // 最大个数
default () {
return 1
}
}
},
min: {
default () {
minLen: { // 最小个数
default () {
return 1
}
},
@ -41,6 +78,11 @@
default () {
return [1, 1] // 宽高比
}
},
isSlot: {
default () {
return false
}
}
},
data() {
@ -55,16 +97,98 @@
},
destroyed() {},
methods: {
handleChange(val){
doChooseFile(opt = {}) {
const that = this
const actMap = {
image: "chooseImage",
video: "chooseVideo",
}
return coreMultiUploadFile(actMap[this.fileType], opt)
},
handlePreview() {
uni.previewImage({
urls: [
...this.list
]
})
},
handleItem(e) {
const that = this
const index = e.currentTarget.dataset.index
let { list, fileType } = this
let itemList = ['更换', '删除', '预览']
if (fileType == fileTypeEnum.video) {
itemList.length--
}
uni.showActionSheet({
itemList,
success: (res) => {
const {
tapIndex
} = res
if (tapIndex == 0) {
// 更换, 只能选择一个文件
that.doChooseFile({
count: 1
}).then((res) => {
list[index] = res[0]
that.triggerChanged(list)
})
}
if (tapIndex == 1) {
list.splice(index, 1)
that.triggerChanged(list)
}
if (tapIndex == 2) {
this.handlePreview()
}
},
fail: (res) => {
console.log(res.errMsg)
}
})
},
handleChooseFile: function() {
let that = this
let { maxLen, pickMaxLen, list } = this
let count = pickMaxLen
if (list.length + pickMaxLen > maxLen) {
count = maxLen - list.length
}
if (count <= 0) {
return showToast(`最多上传${maxLen}个`)
}
this.doChooseFile({
count
}).then((res) => {
list = list.concat(res)
that.triggerChanged(list)
})
},
triggerChanged(list) {
let val = list
if(this.maxLen == 1) {
val = list[0] || ''
}
this.$emit('change', val)
this.$emit('update:value', val)
this.$emit('update:value', val)
}
}
}
</script>
<style scoped lang="scss">
.cam {
height: 168rpx;
width: 168rpx;
border: 2rpx solid #EFEFEF;
border-radius: 6rpx;
background: #F8F8F8;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>