新增上传处理

master
于肖磊 2025-07-03 17:18:32 +08:00
parent 3f1508c237
commit b7bc45a539
2 changed files with 423 additions and 0 deletions

View File

@ -0,0 +1,340 @@
<template>
<view :class="theme_view">
<template v-if="propType !== 'file'">
<view class="flex-row flex-wrap">
<template v-if="propData.length > 0">
<view v-for="(item, index) in propData" :key="index" class="item margin-right-lg pr">
<view v-if="propDelete" class="delete-icon pa z-i-deep" @tap="upload_delete_event" :data-index="index">
<iconfont name="icon-bjdz-guanbi" size="36rpx" color="rgba(87,91,102,0.65)"></iconfont>
</view>
<template v-if="propType == 'img'">
<image :src="item.url" @tap="upload_show_event" :data-index="index" mode="aspectFill" class="img border-radius-main oh"></image>
</template>
<template v-else-if="propType == 'video'">
<view class="pr show-video">
<video :src="item.url" class="video border-radius-main oh" :show-center-play-btn="false" :controls="false" objectFit="cover" style="object-fit: cover" ></video>
<view class="video-container border-radius-main z-i flex-row align-c jc-c" :data-index="index" @tap="upload_show_event">
<iconfont name="icon-bofang" size="32rpx" color="#fff"></iconfont>
</view>
</view>
</template>
</view>
</template>
<view v-if="(propData || null) == null || propData.length < propMaxNum" class="add-img img border-radius-main flex-col align-c jc-c" @tap="file_upload_event">
<iconfont name="icon-add" size="52rpx" color="#999"></iconfont>
</view>
</view>
</template>
<template v-else>
<view v-if="propData.length > 0" class="flex-col gap-5 margin-bottom">
<view v-for="(item, index) in propData" :key="index" class="upload-file-content flex-row align-c gap-10">
<view v-if="item" class="flex-1 flex-row align-c upload-file-title w h">
<span class="text-line-1">{{ new_name(item.name)[0] || '' }}</span><span>.{{ new_name(item.name)[1] || '' }}</span>
</view>
<view :data-index="index" @tap="upload_delete_event">
<iconfont name="icon-close" size="20rpx" color="#999"></iconfont>
</view>
</view>
</view>
<view v-if="(propData || null) == null || propData.length < propMaxNum" class="file flex-row align-c" :style="propBorderStyle" @tap="file_upload_event">
请选择文件最多可以上传{{ propMaxNum }}
</view>
</template>
<uni-popup ref="popup" type="center" border-radius="20rpx" mask-background-color="rgba(0,0,0,0.8)">
<view class="wh-auto ht-auto">
<view class="popup-close oh" @tap="popup_close">
<iconfont name="icon-close" size="32rpx" color="#fff"></iconfont>
</view>
<video :src="video_src" autoplay controls class="radius-md" objectFit="cover" :style="{ width: popup_width, height: popup_height }"></video>
</view>
</uni-popup>
</view>
</template>
<script>
const app = getApp();
var common_static_url = app.globalData.get_static_url('common');
var system = app.globalData.get_system_info(null, null, true);
var sys_width = app.globalData.window_width_handle(system.windowWidth);
import VideoPlayer from '@/components/video-player/video-player.vue';
import { isEmpty } from '@/common/js/common/common.js';
export default {
components: {
VideoPlayer,
},
props: {
propType: {
type: String,
default: 'img',
},
//
propData: {
type: Array,
default: () => {
return [];
},
},
//
propMaxNum: {
type: [Number, String],
default: 3,
},
//
propDelete: {
type: Boolean,
default: true,
},
//
propPreview: {
type: Boolean,
default: true,
},
// common
propPathType: {
type: String,
default: 'common',
},
propBorderStyle: {
type: String,
default: '',
},
//
propCallData: {
type: [Number, String, Array, Object],
default: '',
},
},
data() {
return {
theme_view: app.globalData.get_theme_value_view(),
common_static_url: common_static_url,
form_images_list: [],
video_src: '',
popup_width: '0rpx',
popup_height: '0rpx',
};
},
computed: {
//
new_name() {
return (name) => {
if (!isEmpty(name)) {
let index = name.lastIndexOf('.'); // /
let lastSegment = name.substring(index + 1); // /
let new_name = name.substring(0, index);
return [ new_name, lastSegment]
} else {
return ['', '']
}
}
}
},
mounted() {
// 80%16
const block = (sys_width * 0.8) / 16;
this.setData({
popup_width: block * 16 * 2 + 'rpx', // 16:9
popup_height: block * 9 * 2 + 'rpx', //
form_images_list: this.propData,
});
},
created: function () {},
methods: {
//
upload_one_by_one(img_paths, success, fail, count, length, action) {
var self = this;
if (self.form_images_list.length <= this.propMaxNum) {
uni.uploadFile({
url: app.globalData.get_request_url('index', 'ueditor'),
filePath: img_paths[count],
name: 'upfile',
formData: {
action: action,
path_type: self.propPathType,
},
success: function (res) {
success++;
if (res.statusCode == 200) {
var data = typeof res.data == 'object' ? res.data : JSON.parse(res.data);
if (data.code == 0 && (data.data.url || null) != null) {
var list = self.form_images_list;
list.push({
url: data.data.url,
name: data.data.original,
});
self.setData({
form_images_list: list,
});
self.$emit('call-back', self.form_images_list, self.propCallData);
} else {
app.globalData.showToast(data.msg);
}
}
},
fail: function (e) {
console.log(e);
fail++;
},
complete: function (e) {
count++;
//
if (count >= length) {
//
//app.showToast('' + success +'', 'success');
} else {
//
self.upload_one_by_one(img_paths, success, fail, count, length, action);
}
},
});
}
},
message(e) {
console.log(e);
},
//
file_upload_event(e) {
if (this.propType == 'img') {
var self = this;
uni.chooseImage({
count: self.propMaxNum,
success(res) {
var success = 0;
var fail = 0;
var length = res.tempFilePaths.length;
var count = 0;
self.upload_one_by_one(res.tempFilePaths, success, fail, count, length, 'uploadimage');
},
});
} else if (this.propType == 'video') {
var self = this;
uni.chooseVideo({
count: self.propMaxNum,
success(res) {
var success = 0;
var fail = 0;
var length = 0;
var count = 0;
self.upload_one_by_one([res.tempFilePath], success, fail, count, length, 'uploadvideo');
},
});
} else {
const ext_file_name_list = ['.png', '.jpg', '.jpeg', '.bmp', '.webp', '.gif', '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg', '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.csv', '.wav', '.mid', '.cab', '.iso', '.ofd', '.xml', '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.vsd', '.sql'];
var self = this;
// #ifdef H5
uni.chooseFile({
count: self.propMaxNum,
extension: ext_file_name_list,
success(res) {
var success = 0;
var fail = 0;
var length = res.tempFilePaths.length;
var count = 0;
self.upload_one_by_one(res.tempFilePaths, success, fail, count, length, 'uploadfile');
},
});
// #endif
// #ifdef MP-QQ || MP-WEIXIN
uni.chooseMessageFile({
count: self.propMaxNum,
extension: ext_file_name_list,
success(res) {
var success = 0;
var fail = 0;
var length = res.tempFilePaths.length;
var count = 0;
self.upload_one_by_one(res.tempFilePaths, success, fail, count, length, 'uploadfile');
},
});
// #endif
}
},
//
upload_delete_event(e) {
var self = this;
uni.showModal({
title: this.$t('common.warm_tips'),
content: this.$t('order.order.psi67g'),
success(res) {
if (res.confirm) {
var list = self.form_images_list;
list.splice(e.currentTarget.dataset.index, 1);
self.setData({
form_images_list: list,
});
self.$emit('call-back', self.form_images_list, self.propCallData);
}
},
});
},
//
upload_show_event(e) {
if(this.propPreview) {
if (this.propType == 'img') {
uni.previewImage({
current: this.form_images_list[e.currentTarget.dataset.index].url,
urls: this.form_images_list.map(item => item.url),
});
} else if (this.propType == 'video') {
this.setData({
video_src: this.form_images_list[e.currentTarget.dataset.index].url,
});
this.$refs.popup.open();
}
}
},
popup_close() {
this.$refs.popup.close();
}
},
};
</script>
<style scoped>
.img, .video {
width: 120rpx;
height: 120rpx;
}
.delete-icon {
top: -16rpx;
right: -16rpx;
}
.add-img {
background: #f0f1f4;
}
::v-deep .show-video .uni-video-cover-duration {
display: none;
}
.video-container {
position: absolute;
width: 120rpx;
height: 120rpx;
top: 0;
left: 0;
background: #000;
opacity: 0.5;
}
.popup-close {
position: fixed;
top: 32rpx;
right: 32rpx;
z-index: 99;
}
.file {
background: #fff;
color: #606266;
font-size: 24rpx;
padding: 10rpx 20rpx;
}
.gap-5 {
gap: 10rpx;
}
.upload-file-content {
padding: 20rpx 24rpx 20rpx 32rpx;
box-shadow: 0px 0px 10rpx 0px rgba(207,207,207,0.5);
background: #fff;
border-radius: 8rpx;
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<uploads :propType="propType" :propData="form_value" :propMaxNum="max_num" :propPathType="pathType" :propBorderStyle="border_style" @call-back="call_back"></uploads>
</template>
<script>
import { isEmpty, common_form_styles_computer } from '@/common/js/common/common.js';
import uploads from '@/pages/form-input/components/form-input/modules/uploads.vue';
export default {
components: {
uploads
},
props: {
propType: {
type: String,
default: 'img',
},
propValue: {
type: Object,
default: () => ({}),
},
propKey: {
type: [String, Number],
default: 0,
},
propDataId: {
type: [String, Number],
default: '',
},
propDataIndex: {
type: Number,
default: 0,
},
propStyle: {
type: String,
default: '',
},
propIsCustom: {
type: Boolean,
default: false,
}
},
data() {
return {
com_data: {},
form_value: [],
pathType: '',
max_num: 1000,
border_style: '',
};
},
watch: {
propKey(val) {
//
this.init();
},
},
mounted() {
this.init();
},
methods: {
isEmpty,
//
init() {
const com_data = this.propValue;
this.setData({
com_data: com_data,
max_num: com_data.is_limit_num == '1' ? com_data.limit : 1000,
pathType: `forminputdata-${this.propDataId}`,
form_value: com_data.form_value || [],
border_style: common_form_styles_computer(com_data.common_config)
});
},
call_back(list = [], call_data = '') {
this.setData({
form_value: list,
});
this.$emit('dataChange', { value: list, index: this.propDataIndex });
}
},
};
</script>
<style></style>