lyuis 7 月之前
父节点
当前提交
8b23dc8795

+ 635 - 0
pages/my/attachment.vue

@@ -0,0 +1,635 @@
+<template>
+	<view>
+		<!-- 顶部导航栏 -->
+		<view class="navbar" :style="{ paddingTop: (12 + statusBarHeight) + 'px' }">
+			<view class="navbar-content">
+				<view class="navbar-left" @click="goBack">
+					<u-icon name="arrow-leftward" size="36" color="#333"></u-icon>
+				</view>
+				<view class="navbar-title">附件管理</view>
+				<view class="navbar-right"></view>
+			</view>
+		</view>
+
+		<!-- <nav-bar title="基本信息"></nav-bar> -->
+		<view class="contain flex flex-direction">
+			<view class="usermain">
+				<scroll-view scroll-with-animation scroll-y>
+				<!-- 我的公司 -->
+					<view class="usermain-item item-padding" v-for="item in content">
+						<view class="usermain-item-title c-flex-center"><image src="../../static/images/pdf.svg" class="header-icon" /></view>
+						<view @click="seekDoc(item)" class="fileContent c-flex-center">
+							<view class="fileName">{{item.attachment_name}}</view>
+							<view class="filedesc">{{item.attachment_size}} 更新于{{item.create_time}}</view>
+						</view>
+						<view @click.stop="more(item.resumes_attachment_id)" class="c-flex-center">
+							<u-icon name="more-dot-fill"></u-icon>
+						</view>
+					</view>
+					<empty :isShow="false" v-if="content.length==0" />
+				</scroll-view>
+			</view>
+			
+			<view class="footer-btn">
+				<fileSelector title="上传简历" allowType=".doc,.docx,.xls,.xlsx,.pdf" @fileSelected="uploadResumes" @filesChanged="onFilesChanged" />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import configdata from '../../common/config.js';
+	import navBar from "@/components/nav-bar/index.vue";
+	// 引入组件
+	import fileSelector from '@/uni_modules/zhouquan-fileSelector/components/zhouquan-fileSelector/file-selector.vue';
+	import empty from '../../components/empty.vue'
+	export default {
+		components: {
+			navBar,
+			fileSelector,
+			empty
+		},
+		data() {
+			return {
+				statusBarHeight: 0, // 状态栏高度
+				phone: '',
+				weChatNum:'',//微信号
+				email: '',//接收简历邮箱
+				selectedCompany: '深圳市汉瑞国际猎头服务有限公司', // 我的公司
+				selectedPosition: '人事总监', // 我的职务
+				avatar: '../../static/logo.png',
+				userName: '',
+				nickName: '',
+				userId: '',
+				realName: '',
+				weChatId: "",
+				password: '',
+				platform: '',
+				createTime: '',
+				money: '',
+				jiFen: '',
+				status: '',
+				zhiFuBao: '',
+				zhiFuBaoName: '',
+				sex: 1,
+				age: 0,
+				content:[]
+			};
+		},
+		computed: {
+			phoneWithMask() {
+				if (this.phone && this.phone.length >= 11) {
+					return this.phone.substring(0, 3) + '******' + this.phone.substring(9);
+				}
+				return this.phone || '请设置手机号';
+			}
+		},
+		onLoad(e) {
+			// 获取状态栏高度
+			let systemInfo = uni.getSystemInfoSync();
+			this.statusBarHeight = systemInfo.statusBarHeight || 0;
+			
+			this.getUserInfo()
+			// this.avatar = uni.getStorageSync('avatar')
+		},
+		methods: {
+			// 返回上一页
+			goBack() {
+				uni.navigateBack();
+			},
+			// 修改手机号
+			modifyPhone() {
+				console.log('点击修改手机号,当前手机号:', this.phone);
+				const url = `/pages/my/userphone?currentPhone=${this.phone}`;
+				console.log('跳转路径:', url);
+				
+				uni.navigateTo({
+					url: url,
+				});
+			},
+			// 选择公司
+			selectCompany() {
+				uni.navigateTo({
+					url: '/pages/my/myCompany'
+				});
+			},
+			// 选择职务
+			selectPosition() {
+				// 这里可以跳转到职务选择页面或显示职务选择弹窗
+				console.log('选择职务');
+			},
+			onChooseAvatar(e) {
+				let that = this;
+				let token = uni.getStorageSync('token');
+				uni.uploadFile({
+					url: that.config("APIHOST1") +
+					'/alioss/upload', //真实的接口地址
+					filePath: e.detail.avatarUrl,
+					header: {
+						token: token
+					},
+					name: 'file',
+					success: uploadFileRes => {
+						let url = JSON.parse(uploadFileRes.data);
+						that.avatar = url.data
+						uni.hideLoading();
+			 	}
+			 });
+
+			},
+			goMyAddress() {
+				uni.navigateTo({
+					url: '../jifen/myaddress'
+				});
+			},
+			uploadImg() {
+				let token = uni.getStorageSync('token')
+
+				if (!token) {
+					this.goLoginInfo();
+					return;
+				}
+				let that = this;
+				var url = null;
+				uni.showActionSheet({
+					// itemList按钮的文字接受的是数组
+					itemList: ["查看头像", "从相册选择图片"],
+					success(e) {
+						var index = e.tapIndex
+						if (index === 0) {
+							// 用户点击了预览当前图片
+							// 可以自己实现当前头像链接的读取
+							let url = that.avatar;
+							let arr = []
+							arr.push(url)
+							uni.previewImage({
+								// 预览功能图片也必须是数组的
+								urls: arr
+							})
+						} else if (index === 1) {
+							uni.chooseImage({
+								count: 1, //默认9
+								sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+								sourceType: ['album'], //从相册选择
+								success: function(res) {
+									uni.showLoading({
+										title: '上传中...'
+									});
+									let token = uni.getStorageSync('token');
+									let userId = uni.getStorageSync('userId');
+									uni.uploadFile({
+										url: that.config("APIHOST1") +
+										'/alioss/upload', //真实的接口地址
+
+										filePath: res.tempFilePaths[0],
+										header: {
+											token: token
+										},
+										name: 'file',
+										success: uploadFileRes => {
+											url = JSON.parse(uploadFileRes.data);
+											that.avatar = url.data
+											uni.hideLoading();
+										}
+									});
+								}
+							});
+						}
+					}
+				})
+			},
+			config: function(name) {
+				var info = null;
+				if (name) {
+					var name2 = name.split("."); //字符分割
+					if (name2.length > 1) {
+						info = configdata[name2[0]][name2[1]] || null;
+					} else {
+						info = configdata[name] || null;
+					}
+					if (info == null) {
+						let web_config = cache.get("web_config");
+						if (web_config) {
+							if (name2.length > 1) {
+								info = web_config[name2[0]][name2[1]] || null;
+							} else {
+								info = web_config[name] || null;
+							}
+						}
+					}
+				}
+				return info;
+			},
+			getUserInfo() {
+				this.$Request.get("/app/resumes/getAttachment").then(res => {
+					if (res.code == 0) {
+						this.content=res.data
+					}
+					uni.hideLoading();
+				});
+
+
+			},
+			// 保存
+			uploadResumes(e) {
+				var that=this
+				console.log(e.path)
+				uni.getFileInfo({
+				  filePath: e.path,
+				  success: (info) => {
+				    console.log('文件大小:', info.size); // 单位:字节
+					let attachment_size=parseInt(info.size/1024)
+					that.$queue.uploadFile(e.path,function(path){
+						if(path)
+							that.$Request.postJson("/app/resumes/saveAttachment", {
+							  		attachment_address:path,
+									attachment_name:e.name,
+									attachment_size
+							  	}).then(res => {
+							  		if (res.code === 0) {
+							  			that.getUserInfo()
+							  		} else {
+							  			uni.showToast({
+							  				title: res.msg,
+							  				icon: "none"
+							  			})
+							  		}
+							  	})
+						else
+							that.$queue.showToast('文件上传失败')
+					})
+				  },
+				  fail: (err) => {
+				    console.error('获取失败', err);
+				  }
+				});
+				
+			},
+			more(id){
+				var that=this
+				uni.showActionSheet({
+					itemList: ["删除"],
+					itemColor: "#3273db",
+					success(res) {
+						if(res.tapIndex==0)
+							that.deleteAttachment(id)
+					},
+					fail(res) {
+						console.log(res.errMsg);
+					},
+				});
+			},
+			deleteAttachment(id){
+			  var that = this;
+			  uni.showModal({
+			    title: '提示',
+			    content: '确定删除?',
+			    success(res) {
+			      if (res.confirm) {
+			        that.$Request.postJson("/app/resumes/deleteAttachment", {
+			        		resumes_attachment_id: id
+			        	}).then(res => {
+			        		if (res.code === 0) {
+			        			var info = that.content.filter(function (item) {
+			        			  return item.resumes_attachment_id != id;
+			        			});
+			        			that.content=info
+			        		} else {
+			        			uni.showToast({
+			        				title: res.msg,
+			        				icon: "none"
+			        			})
+			        		}
+			        	})
+			      } else if (res.cancel) {
+			        console.log('用户点击取消')
+			      }
+			    }
+			  })
+			},
+			onFilesChanged(e){
+				console.log(e)
+			},
+			seekDoc(it){
+				uni.navigateTo({
+					url: '/pages/index/webView?url=' + it.attachment_address
+				});
+			}
+		},
+		// userphone(){
+		// 	uni.navigateTo({
+		// 		url:'/pages/my/userphone'
+		// 	})
+		// }
+
+	};
+</script>
+
+<style lang="scss" scoped>
+	page {
+		/* background: #f6f6f6; */
+	}
+
+	.navbar {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		z-index: 999;
+		background: #fff;
+		padding: 0 0 40rpx 20rpx;
+		
+		.navbar-content {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			padding: 0 30rpx;
+			height: 60rpx;
+			
+			.navbar-left {
+				width: 60rpx;
+				height: 60rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+			
+			.navbar-title {
+                color: rgba(23, 23, 37, 1);
+                font-family: DM Sans;
+                font-size: 36rpx;
+                font-weight: 700;
+                line-height: 52rpx;
+                letter-spacing: 0%;
+                text-align: center;
+			}
+			
+			.navbar-right {
+				width: 60rpx;
+				height: 60rpx;
+			}
+		}
+	}
+
+	button::after {
+		border: none;
+		background-color: none;
+	}
+
+	button {
+		position: relative;
+		display: block;
+		margin-left: auto;
+		margin-right: auto;
+		padding-left: 0px;
+		padding-right: 0px;
+		box-sizing: border-box;
+		text-decoration: none;
+		line-height: 1.35;
+		overflow: hidden;
+		color: #666666;
+		/* background-color: #fff; */
+		background-color: rgba(255, 255, 255, 0) !important;
+		width: 100%;
+		height: 100%;
+	}
+	.contain{
+		padding-top: 120rpx; /* 为固定导航栏留出空间 */
+		height: 100vh;
+	}
+	.usermain {
+		background: #ffffff;
+		/* color: #fff; */
+		height: 100vh;
+		scroll-view{
+			height: 100%;
+		}
+	}
+
+	.usermain-item {
+		display: flex;
+		justify-content: space-between;
+		margin: 0 40rpx;
+		padding: 30rpx 0;
+		// border-bottom: 1rpx solid rgba(229, 229, 229, 0.3);
+		background: #fff;
+		gap: 16rpx;
+		.fileContent{
+			width: 80%;
+			margin:0 20rpx;
+		}
+		.fileName{
+			color: #222;
+		}
+		.filedesc{
+			margin-top: 10rpx;
+			font-size: 20rpx;
+		}
+		.c-flex-center{
+			align-self: center;
+			color: #aaa;
+		}
+		
+	}
+
+	.usermain-item-title {
+		color: rgba(31, 44, 55, 1);
+		font-family: DM Sans;
+		font-size: 28rpx;
+		font-weight: 500;
+		line-height: 44rpx;
+		text-align: left;
+		.header-icon{
+			width: 50rpx;
+			height: 50rpx;
+			display: block;
+		}
+	}
+
+	.usermain-item.item-padding {
+		/* padding: 0; */
+	}
+
+	.cu-form-group {
+		padding: 0;
+		background: #ffffff;
+		text-align: right;
+	}
+
+	.cu-form-group input {
+		background: #ffffff;
+		font-size: 28rpx;
+		/* color: #fff; */
+
+	}
+
+	/* 姓名字段样式 - 参考basicInfo.vue */
+	.usermain-item .form-label {
+		color: rgba(31, 44, 55, 1);
+		font-family: DM Sans;
+		font-size: 32rpx;
+		font-weight: 500;
+		line-height: 44rpx;
+		letter-spacing: 0.5%;
+		text-align: left;
+		display: flex;
+		align-items: center;
+		margin-bottom: 16rpx;
+	}
+
+	.usermain-item .required-mark {
+		color: #FF3B30;
+		font-size: 36rpx;
+		font-weight: 600;
+		margin-right: 8rpx;
+	}
+
+	.usermain-item .cu-form-group {
+		background: transparent;
+		text-align: left;
+		padding: 0;
+	}
+
+	.usermain-item .cu-form-group input {
+		width: 100%;
+		height: 68rpx;
+		font-size: 28rpx;
+		border: 1rpx solid rgba(227, 231, 236, 1);
+		border-radius: 44rpx;
+		color: rgba(23, 23, 37, 1);
+		padding: 0 32rpx;
+		background: #ffffff;
+		font-family: DM Sans;
+		font-weight: 400;
+	}
+
+	.usermain-item .cu-form-group input::placeholder {
+		color: rgba(155, 155, 155, 1);
+		font-size: 28rpx;
+	}
+
+	/* 联系方式样式 */
+	.contact-structure {
+		border-bottom: none !important;
+	}
+
+	.contact-wrapper {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 0;
+		margin-top: 8rpx;
+	}
+
+	.phone-display {
+		color: rgba(23, 23, 37, 1);
+		font-family: DM Sans;
+		font-size: 28rpx;
+		font-weight: 400;
+		line-height: 40rpx;
+		letter-spacing: 0.5%;
+	}
+
+	.modify-link {
+		color: rgba(24, 144, 255, 1);
+		font-family: DM Sans;
+		font-size: 28rpx;
+		font-weight: 400;
+		line-height: 40rpx;
+		letter-spacing: 0.5%;
+		cursor: pointer;
+		text-decoration: none;
+	}
+
+	.modify-link:active {
+		opacity: 0.7;
+	}
+
+	/* 头像编辑图标样式 */
+	.avatar-wrapper {
+		position: relative;
+		display: inline-block;
+	}
+
+	.edit-avatar-icon {
+		position: absolute;
+		bottom: 10rpx;
+		right: 2rpx;
+		width: 24rpx;
+		height: 24rpx;
+		// background: #fff;
+		border-radius: 50%;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+	}
+
+	.avatar-button {
+		position: relative;
+		padding: 0;
+		margin: 0;
+		background: transparent;
+		border: none;
+	}
+
+	.footer-btn {
+		margin-top: 40rpx;
+		padding-bottom: 40rpx;
+	}
+
+	.footer-btn .usermain-btn {
+		color: rgba(255, 255, 255, 1);
+		background: rgba(1, 107, 246, 1);
+		text-align: center;
+		width: 90%;
+		height: 80rpx;
+		font-size: 32rpx;
+		line-height: 80rpx;
+		margin: 20rpx auto;
+		border-radius: 40rpx;
+	}
+
+	/* 选择器样式 - 参考workExperience页面 */
+	.form-input-selector {
+		width: 100%;
+		height: 68rpx;
+		padding: 0 40rpx;
+		border: 1px solid rgba(227, 231, 236, 1);
+		border-radius: 24px;
+		background: rgba(255, 255, 255, 1);
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		cursor: pointer;
+		transition: all 0.2s ease;
+		
+		.placeholder {
+			color: #999999;
+			font-family: DM Sans;
+			font-size: 28rpx;
+			font-weight: 400;
+			line-height: 40rpx;
+		}
+		
+		text {
+			color: rgba(23, 23, 37, 1);
+			font-family: DM Sans;
+			font-size: 28rpx;
+			font-weight: 400;
+			line-height: 40rpx;
+		}
+	}
+
+	.arrow-down {
+		color: rgba(96, 98, 102, 1);
+		font-size: 24rpx;
+		font-weight: 400;
+		transform: scale(1.5);
+	}
+
+	.selector-group:active {
+		background: #f5f7fa !important;
+		transform: scale(0.99);
+	}
+</style>

+ 1 - 0
static/images/pdf.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1764229655507" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9328" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M160 32c-12 0-24.8 4.8-33.6 14.4S112 68 112 80v864c0 12 4.8 24.8 14.4 33.6 9.6 9.6 21.6 14.4 33.6 14.4h704c12 0 24.8-4.8 33.6-14.4 9.6-9.6 14.4-21.6 14.4-33.6V304L640 32H160z" fill="#FF5562" p-id="9329"></path><path d="M912 304H688c-12 0-24.8-4.8-33.6-14.4-9.6-8.8-14.4-21.6-14.4-33.6V32l272 272z" fill="#FFBBC0" p-id="9330"></path><path d="M696 843.2c-50.4 0-95.2-86.4-119.2-142.4-40-16.8-84-32-126.4-42.4-37.6 24.8-100.8 61.6-149.6 61.6-30.4 0-52-15.2-60-41.6-6.4-21.6-0.8-36.8 5.6-44.8 12.8-17.6 39.2-26.4 79.2-26.4 32 0 72.8 5.6 118.4 16.8 29.6-20.8 59.2-44.8 85.6-70.4-12-56-24.8-146.4 8-188 16-20 40.8-26.4 70.4-17.6 32.8 9.6 44.8 29.6 48.8 44.8 13.6 54.4-48.8 128-91.2 171.2 9.6 37.6 21.6 76.8 36.8 112.8C663.2 704 735.2 744 743.2 788c3.2 15.2-1.6 29.6-13.6 41.6-10.4 8.8-21.6 13.6-33.6 13.6z m-74.4-121.6c30.4 61.6 59.2 90.4 74.4 90.4 2.4 0 5.6-0.8 10.4-4.8 5.6-5.6 5.6-9.6 4.8-12.8-3.2-16-28.8-42.4-89.6-72.8z m-296-82.4c-39.2 0-50.4 9.6-53.6 13.6-0.8 1.6-4 5.6-0.8 16.8 2.4 9.6 8.8 19.2 29.6 19.2 25.6 0 62.4-14.4 105.6-40-31.2-6.4-58.4-9.6-80.8-9.6z m158.4-4.8c25.6 7.2 52 16 76.8 25.6-8.8-23.2-16-47.2-22.4-70.4-17.6 15.2-36 30.4-54.4 44.8zM583.2 376c-8.8 0-15.2 3.2-20.8 9.6-16.8 20.8-18.4 73.6-5.6 140.8 48.8-52 75.2-100 68.8-125.6-0.8-4-4-15.2-26.4-21.6-6.4-2.4-11.2-3.2-16-3.2z" fill="#FFFFFF" p-id="9331"></path></svg>

+ 4 - 0
uni_modules/zhouquan-fileSelector/changelog.md

@@ -0,0 +1,4 @@
+## 1.0.1(2025-02-08)
+修改APP端存放路径名称
+## 1.0.0(2025-02-08)
+文件选择器组件、多文件选择功能、文件类型识别功能(支持图片、文档、音频、视频、压缩包等)、文件列表展示功能、文件删除功能、H5平台支持、APP平台支持。

+ 272 - 0
uni_modules/zhouquan-fileSelector/components/zhouquan-fileSelector/file-selector.vue

@@ -0,0 +1,272 @@
+<template>
+    <view class="main">
+        <!-- 上传区域 -->
+        <view class="upload-area" @click="fileRender.createFileInputDom">
+            <text class="upload-text">{{title}}</text>
+        </view>
+        
+        <!-- 文件列表 -->
+        <view hidden class="file-list">
+            <view v-for="(file, index) in fileList" :key="index" class="file-item">
+                <text class="file-type-icon">
+                    {{getFileEmoji(file.name)}}
+                </text>
+                <view class="file-info">
+                    <text class="file-name">{{file.name}}</text>
+                </view>
+                <view class="delete-btn" @click="removeFile(index)">
+                    <text class="delete-icon">×</text>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+    name: 'FileSelector',
+    props:{
+    	title: {
+    	 	type: String,
+    		default: '上传文件'
+    	},
+		allowType:{
+			type: String,
+			default: '*'
+		}
+    },
+    data() {
+        return {
+            fileList: [],
+            // 文件扩展名映射
+            fileTypes: {
+                image: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'],
+                document: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt'],
+                audio: ['mp3', 'wav', 'ogg', 'aac'],
+                video: ['mp4', 'avi', 'mov', 'wmv', 'flv'],
+                archive: ['zip', 'rar', '7z', 'tar', 'gz'],
+                json: ['json']
+            }
+        }
+    },
+
+    methods: {
+        // 获取文件类型
+        getFileType(fileName) {
+            const extension = fileName.split('.').pop().toLowerCase()
+            for (let type in this.fileTypes) {
+                if (this.fileTypes[type].includes(extension)) return type
+            }
+            return 'other'
+        },
+
+        // 根据文件类型获取对应emoji
+        getFileEmoji(fileName) {
+            const fileType = this.getFileType(fileName)
+            const emojiMap = {
+                image: '🖼️',
+                document: '📄',
+                audio: '🎵',
+                video: '🎬',
+                archive: '📦',
+                json: '📋',
+                other: '📎'
+            }
+            return emojiMap[fileType] || '📎'
+        },
+
+        // 接收文件
+        async receiveRenderFile(result) {
+            let fileInfo = {
+                name: result.name,
+                path: ''
+            }
+
+            //#ifdef APP-PLUS
+            const fileUrl = await this.base64toPath(result.filePath, result.name)
+            fileInfo.path = fileUrl.localAbsolutePath
+            //#endif
+            //#ifdef H5
+            fileInfo.path = result.filePath
+            //#endif
+
+            this.fileList.push(fileInfo)
+            this.$emit('filesChanged', this.fileList)
+            this.$emit('fileSelected', fileInfo)
+        },
+
+        // 删除文件
+        removeFile(index) {
+            this.fileList.splice(index, 1)
+            this.$emit('filesChanged', this.fileList)
+        },
+
+        // APP端base64转本地路径
+        async base64toPath(base64, attachName) {
+            return new Promise((resolve, reject) => {
+                const filePath = `_doc/file/${attachName}`
+                plus.io.resolveLocalFileSystemURL('_doc', entry => {
+                    entry.getDirectory('file', {
+                        create: true,
+                        exclusive: false
+                    }, entry => {
+                        entry.getFile(attachName, {
+                            create: true,
+                            exclusive: false
+                        }, entry => {
+                            entry.createWriter(writer => {
+                                writer.onwrite = () => {
+                                    resolve({
+                                        relativePath: filePath,
+                                        localAbsolutePath: plus.io.convertLocalFileSystemURL(filePath)
+                                    })
+                                }
+                                writer.onerror = reject
+                                writer.seek(0)
+                                writer.writeAsBinary(this.getSymbolAfterString(base64, ','))
+                            }, reject)
+                        }, reject)
+                    }, reject)
+                }, reject)
+            })
+        },
+
+        getSymbolAfterString(val, symbolStr) {
+            return val ? val.toString().split(symbolStr)[1] || val : ''
+        }
+    }
+}
+</script>
+
+<script module="fileRender" lang="renderjs">
+export default {
+    methods: {
+        createFileInputDom(e, ownerVm) {
+            const fileInput = document.createElement('input')
+            fileInput.setAttribute('type', 'file')
+            fileInput.setAttribute('accept', this.allowType)
+            fileInput.setAttribute('multiple', 'multiple')
+            fileInput.click()
+
+            fileInput.addEventListener('change', e => {
+                if (!e.target.files.length) return
+
+                Array.from(e.target.files).forEach(file => {
+                    //#ifdef H5
+                    ownerVm.callMethod('receiveRenderFile', {
+                        name: file.name,
+                        filePath: URL.createObjectURL(file)
+                    })
+                    //#endif
+
+                    //#ifdef APP-PLUS
+                    const reader = new FileReader()
+                    reader.onload = ({target}) => {
+                        target?.result && ownerVm.callMethod('receiveRenderFile', {
+                            name: file.name,
+                            filePath: target.result
+                        })
+                    }
+                    reader.readAsDataURL(file)
+                    //#endif
+                })
+            })
+        }
+    }
+}
+</script>
+
+<style>
+/* 基础样式 */
+.main {
+    padding: 20rpx;
+}
+
+/* 上传区域样式 */
+.upload-area {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+	color: white;
+	    background: #016bf6;
+	    text-align: center;
+	    width: calc(90% + 40rpx);
+	    height: 45px;
+	    font-size: 18px;
+	    line-height: 45px;
+	    margin: 11px auto;
+	    border-radius: 22px;
+}
+
+.upload-icon {
+    width: 44rpx;
+    height: 44rpx;
+    border-radius: 4rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-bottom: 8rpx;
+}
+
+.icon-plus {
+    font-size: 28rpx;
+    font-weight: 100;
+}
+
+.upload-text {
+/*    font-size: 22rpx;
+    color: #A8A8A8; */
+}
+
+/* 文件列表样式 */
+.file-list {
+    width: 100%;
+}
+
+.file-item {
+    background-color: #FFFFFF;
+    border-radius: 8rpx;
+    padding: 20rpx;
+    margin-bottom: 16rpx;
+    display: flex;
+    align-items: center;
+}
+
+.file-type-icon {
+    width: 44rpx;
+    height: 44rpx;
+    margin-right: 16rpx;
+    font-size: 32rpx;
+    text-align: center;
+    line-height: 44rpx;
+}
+
+.file-info {
+    flex: 1;
+    overflow: hidden;
+}
+
+.file-name {
+    font-size: 22rpx;
+    color: #A8A8A8;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.delete-btn {
+    padding: 4rpx 8rpx;
+}
+
+.delete-icon {
+    font-size: 24rpx;
+    color: #C7C7C7;
+    line-height: 1;
+}
+
+.delete-icon:active {
+    color: #ff4444;
+}
+</style> 

+ 77 - 0
uni_modules/zhouquan-fileSelector/package.json

@@ -0,0 +1,77 @@
+{
+  "id": "zhouquan-fileSelector",
+  "name": "文件选择器",
+  "displayName": "文件选择器(APP、H5)",
+  "version": "1.0.1",
+  "description": "一个简单易用的文件选择器组件,支持多文件选择、文件类型识别、文件列表展示等功能。支持H5和APP平台",
+  "keywords": [
+    "文件",
+    "文件选择",
+    "多文件",
+    "文件列表"
+],
+  "repository": "",
+"engines": {
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "n",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "n",
+          "阿里": "n",
+          "百度": "n",
+          "字节跳动": "n",
+          "QQ": "n"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        }
+      }
+    }
+  }
+}