MS-IOHQJGHXZHQD\Administrator 3 часов назад
Родитель
Сommit
9c43ee95ec

+ 29 - 11
src/App.vue

@@ -1,6 +1,6 @@
 <script>
 import { getTechnicianToken } from "@/api/newLogin";
-import { getTechnician } from "@/api/index";
+import { getTechnicianList, getTechnician } from "@/api/index";
 export default {
 	globalData: {
 		couponSelected: {}
@@ -30,7 +30,7 @@ export default {
 
 			// 已有登录态,不用登录
 			if (token) {
-				//this.getTechnicianFun()
+				this.getTechnicianFun()
 				return
 			};
 			// // 1. 没有code → 跳转微信静默授权
@@ -44,7 +44,7 @@ export default {
 
 			let params = {
 				//code: this.$utils.('code') //guo
-				code: '031Ccs1w3bRDa73fin2w3BSsSe0Ccs13'
+				code: '021LKB1w3Cj6e73aak1w3Lg1Ji1LKB1F'
 			}
 			getTechnicianToken(params).then(res => {
 
@@ -55,18 +55,36 @@ export default {
 				}
 			})
 		},
-		//查询商户信息   auditStatus 审核状态:-1-申请入住,0-待入驻,1-待审核,2-审核通过,3-审核驳回"
+		//查询商户注册和入驻信息   auditStatus 审核状态:-1-申请入住,0-待入驻,1-待审核,2-审核通过,3-审核驳回"
 		getTechnicianFun() {
+			return
 			let openid = uni.getStorageSync('wx_copenid')
 			getTechnician({ openid: openid }).then(res => {
-				
+
 				if (res.data.code == 200) {
-					if(!res.data.result)return
-					if (res.data.result.auditStatus == -1) {
-						uni.navigateTo({
-							url: '/pages/join/staff'
-						})
-					}
+					if (!res.data.result) return
+					getTechnicianList({ userId: res.data.result.id}).then(response => {
+						if (!response.data.result) return
+						if (response.data.result.merchant.auditStatus == -1 || response.data.result.auditStatus == 1 || response.data.result.auditStatus == 2 || response.data.result.auditStatus == 3) {
+							if (!response.data.result.merchantAuditFile.length) {
+								uni.navigateTo({
+									url: '/pages/join/staff?ShopInfo=' + encodeURIComponent(JSON.stringify(response.data.result))
+								})
+
+							} else {
+								uni.navigateTo({
+									url: '/pages/join/applyJoin?ShopInfo=' + encodeURIComponent(JSON.stringify(response.data.result))
+								})
+							}
+
+						} else if (response.data.result.auditStatus == 0) {
+							uni.navigateTo({
+								url: '/pages/join/applyJoin?ShopInfo=' + encodeURIComponent(JSON.stringify(response.data.result))
+							})
+						}
+
+					})
+
 
 				}
 			})

+ 18 - 0
src/api/index.js

@@ -659,6 +659,15 @@ export function getServiceCategoryList(dictType) {
         url: `/system/dict/data/type/${dictType}`
     });
 }
+//查询商户注册和入驻信息
+export function getTechnicianList(data) {
+    return request({
+        method: 'get',
+        url:'/technician/technician/getTechnicianList',
+        data
+    });
+}
+
 //查询商户信息
 export function getTechnician(data) {
     return request({
@@ -667,3 +676,12 @@ export function getTechnician(data) {
         data
     });
 }
+//入驻申请提交
+export function applyFile(data) {
+    return request({
+        method: 'post',
+        url:'/technician/technician/applyFile',
+        data
+    });
+}
+

+ 661 - 0
src/components/cropper/lxiaoxiao-cropper.vue

@@ -0,0 +1,661 @@
+<template name="cropper">
+	<view>
+		<image :src="imgSrc.imgSrc" class="my-avatar" mode="aspectFill" @click="fSelect" :style="imgStyle"></image>
+		<!-- 上传图片 -->
+		<canvas canvas-id="avatar-canvas" id="avatar-canvas" class="my-canvas" :style="{top: styleTop, height: cvsStyleHeight}"
+		 disable-scroll="false"></canvas>
+		<!-- 截取边框 -->
+		<canvas canvas-id="oper-canvas" id="oper-canvas" class="oper-canvas" :style="{top: styleTop, height: cvsStyleHeight}"
+		 disable-scroll="false" @touchstart="fStart" @touchmove="fMove" @touchend="fEnd"></canvas>
+		<view class="oper-wrapper" :style="{display: styleDisplay}">
+			<view class="btn-wrapper" v-if="showOper">
+				<view @click="fClose" hover-class="hover">取消</view>
+				<view @click="fUpload" hover-class="hover">选取</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	const tabHeight = 70;
+	export default {
+		name: "cropper",
+		data() {
+			return {
+				cvsStyleHeight: '0px',
+				styleDisplay: 'none',
+				styleTop: '-10000px',
+				prvTop: '-10000px',
+				imgStyle: {},
+				selStyle: {},
+				showOper: true,
+				imgSrc: {
+					imgSrc: ''
+				},
+				qlty: 0.9,
+				postWidthFirst: {},
+			};
+		},
+		watch: {
+			avatarSrc() {
+				this.imgSrc.imgSrc = this.avatarSrc;
+			}
+		},
+		props: {
+			avatarSrc: '',
+			avatarStyle: '',
+			selWidth: '',
+			selHeight: '',
+			expWidth: '',
+			expHeight: '',
+			minScale: '',
+			maxScale: '',
+			canScale: '',
+			noTop: '',
+			quality: '',
+			index: ''
+		},
+		created() {
+			this.ctxCanvas = uni.createCanvasContext('avatar-canvas', this);
+			this.ctxCanvasOper = uni.createCanvasContext('oper-canvas', this);
+
+			this.qlty = parseInt(this.quality) || 0.9;
+			this.imgSrc.imgSrc = this.avatarSrc;
+			this.letScale = this.canScale === 'false' ? 0 : 1;
+			this.indx = this.index || undefined;
+			this.mnScale = this.minScale || 0.3;
+			this.mxScale = this.maxScale || 4;
+			this.noBar = this.noTop ? false : true;
+			if (!!this.noBar) {
+				this.moreHeight = 0;
+				this.fWindowResize();
+			} else {
+				uni.showTabBar({
+					complete: (res) => {
+						this.moreHeight = (res.errMsg === 'showTabBar:ok') ? 50 : 0;
+						this.fWindowResize();
+					}
+				});
+			}
+		},
+		methods: {
+			fWindowResize() {
+				let sysInfo = uni.getSystemInfoSync();
+				this.platform = sysInfo.platform;
+				this.pixelRatio = sysInfo.pixelRatio;
+				this.windowWidth = sysInfo.windowWidth;
+				// #ifdef H5
+				this.drawTop = sysInfo.windowTop;
+				this.windowHeight = sysInfo.windowHeight + sysInfo.windowBottom;
+				this.cvsStyleHeight = this.windowHeight - tabHeight + 'px';
+				// #endif
+				// #ifdef MP-WEIXIN
+				this.windowHeight = sysInfo.windowHeight;
+				this.cvsStyleHeight = this.windowHeight - tabHeight + 'px';
+				this.cvsStyleHeight = this.windowHeight - tabHeight + 'px'
+				// #endif
+				this.pxRatio = this.windowWidth / 750;
+
+				let style = this.avatarStyle;
+				this.imgStyle = style;
+				this.expWidth && (this.exportWidth = this.expWidth.indexOf('rpx') >= 0 ? parseInt(this.expWidth) * this.pxRatio :
+					parseInt(this.expWidth));
+				this.expHeight && (this.exportHeight = this.expHeight.indexOf('rpx') >= 0 ? parseInt(this.expHeight) * this.pxRatio :
+					parseInt(this.expHeight));
+
+				if (this.styleDisplay === 'flex') {
+					this.fDrawInit(true);
+				}
+				this.fHideImg();
+			},
+			fSelect() {
+        let self=this;
+				if (this.fSelecting) return;
+				this.fSelecting = true;
+				setTimeout(() => {
+					this.fSelecting = false;
+				}, 500);
+
+				uni.chooseImage({
+					count: 1,
+					sizeType: ['original', 'compressed'],
+					sourceType: ['camera', 'album'],
+					success: (r) => {
+						uni.showLoading({
+							mask: true
+						});
+						let path = this.imgPath = r.tempFilePaths[0];
+						uni.getImageInfo({
+							src: path,
+							success: r => {
+								this.imgWidth = r.width;
+								this.imgHeight = r.height;
+								this.path = path;
+								if (!this.hasSel) {
+									let style = this.selStyle || {};
+									if (this.selWidth && this.selHeight) {
+										let selWidth = this.selWidth.indexOf('rpx') >= 0 ? parseInt(this.selWidth) * this.pxRatio :
+											parseInt(this.selWidth),
+											selHeight = this.selHeight.indexOf('rpx') >= 0 ? parseInt(this.selHeight) * this.pxRatio :
+											parseInt(this.selHeight);
+										style.width = parseInt(selWidth);
+										style.height = parseInt(selHeight);
+										style.top = parseInt((this.windowHeight - style.height - tabHeight) / 2);
+										style.left = parseInt((this.windowWidth - style.width) / 2);
+									} else {
+										uni.showModal({
+											title: '裁剪框的宽或高没有设置',
+											showCancel: false
+										})
+										return;
+									}
+									this.selStyle = style;
+
+								}
+
+								if (!!self.noBar) {
+									self.fDrawInit(true);
+								} else {
+									uni.hideTabBar({
+										complete: () => {
+											self.fDrawInit(true);
+										}
+									});
+								}
+							},
+							fail: () => {
+								uni.showToast({
+									title: "error3",
+									duration: 2000,
+								})
+							},
+							complete() {
+								uni.hideLoading();
+							}
+						});
+					}
+				})
+			},
+			fUpload() {
+				if (this.fUploading) return;
+				this.fUploading = true;
+				setTimeout(() => {
+					this.fUploading = false;
+				}, 1000)
+
+				let style = this.selStyle,
+					x = parseInt(style.left),
+					y = parseInt(style.top),
+					width = parseInt(style.width),
+					height = parseInt(style.height),
+					expWidth = this.exportWidth || width,
+					expHeight = this.exportHeight || height;
+
+				// #ifdef H5
+				// x *= this.pixelRatio;
+				// y *= this.pixelRatio;
+				// expWidth = width;
+				// expHeight = height;
+				// #endif
+
+				this.styleDisplay = 'none';
+				this.styleTop = '-10000px';
+				this.hasSel = false;
+				this.fHideImg();
+				uni.canvasToTempFilePath({
+					x: x,
+					y: y,
+					width: width,
+					height: height,
+					destWidth: expWidth,
+					destHeight: expHeight,
+					canvasId: 'avatar-canvas',
+					fileType: 'png',
+					quality: this.qlty,
+					success: (r) => {
+						r = r.tempFilePath;
+						// #ifdef H5
+						this.btop(r).then((r) => {
+							if (this.exportWidth && this.exportHeight) {
+								let ctxCanvas = this.ctxCanvas;
+								expWidth = this.exportWidth,
+									expHeight = this.exportHeight;
+
+								ctxCanvas.drawImage(r, 0, 0, expWidth, expHeight);
+								ctxCanvas.draw(false, () => {
+									uni.canvasToTempFilePath({
+										x: 0,
+										y: 0,
+										width: expWidth,
+										height: expHeight,
+										destWidth: expWidth,
+										destHeight: expHeight,
+										canvasId: 'avatar-canvas',
+										fileType: 'png',
+										quality: this.qlty,
+										success: (r) => {
+											r = r.tempFilePath;
+											this.btop(r).then((r) => {
+												this.$emit("upload", {
+													avatar: this.imgSrc,
+													path: r,
+													index: this.indx
+												});
+											});
+										},
+										fail: () => {
+											uni.showToast({
+												title: "error0",
+												duration: 2000,
+											})
+										}
+									});
+								});
+							} else {
+								this.$emit("upload", {
+									avatar: this.imgSrc,
+									path: r,
+									index: this.indx
+								});
+							}
+						})
+						// #endif
+						// #ifndef H5
+						this.$emit("upload", {
+							avatar: this.imgSrc,
+							path: r,
+							index: this.indx
+						});
+						// #endif
+					},
+					fail: (res) => {
+						uni.showToast({
+							title: "error1",
+							duration: 2000,
+						})
+					},
+					complete: () => {
+						this.noBar || uni.showTabBar();
+					}
+				}, this);
+			},
+			fDrawInit(ini = false) {
+				let allWidth = this.windowWidth,
+					allHeight = this.windowHeight,
+					imgWidth = this.imgWidth,
+					imgHeight = this.imgHeight,
+					imgRadio = imgWidth / imgHeight,
+					useWidth = allWidth,
+					useHeight = allHeight - tabHeight,
+					pixelRatio = this.pixelRatio,
+					selWidth = parseInt(this.selStyle.width),
+					selHeight = parseInt(this.selStyle.height);
+
+				this.fixWidth = 0;
+				this.fixHeight = 0;
+
+				if (this.fixWidth) {
+					useWidth = selWidth;
+					useHeight = useWidth / imgRadio;
+				} else if (this.fixHeight) {
+					useHeight = selHeight;
+					useWidth = useHeight * imgRadio;
+				} else if (imgRadio < 1) {
+					useWidth = selWidth;
+					useHeight = parseInt(useWidth / imgRadio);
+				} else {
+					useHeight = selHeight;
+					useWidth = parseInt(useHeight * imgRadio);
+				}
+
+				this.scaleSize = 1;
+				this.rotateDeg = 0;
+				this.posWidth = parseInt((allWidth - useWidth) / 2);
+				this.posHeight = parseInt((allHeight - useHeight - tabHeight) / 2);
+				this.useWidth = useWidth;
+				this.useHeight = useHeight;
+				let style = this.selStyle,
+					left = parseInt(style.left),
+					top = parseInt(style.top),
+					width = parseInt(style.width),
+					height = parseInt(style.height),
+					canvas = this.canvas,
+					canvasOper = this.canvasOper,
+					ctxCanvas = this.ctxCanvas,
+					ctxCanvasOper = this.ctxCanvasOper;
+				ctxCanvasOper.setFillStyle('rgba(0,0,0, 0.5)');
+				ctxCanvasOper.fillRect(0, 0, this.windowWidth, top);
+				ctxCanvasOper.fillRect(0, top, left, height);
+				ctxCanvasOper.fillRect(0, top + height, this.windowWidth, this.windowHeight - height - tabHeight - top);
+				ctxCanvasOper.fillRect(left + width, top, this.windowWidth - width - left, height);
+				ctxCanvasOper.setLineWidth(1);
+				ctxCanvasOper.setStrokeStyle('rgba(255, 255, 255,1)'); //细线的颜色
+				ctxCanvasOper.strokeRect(left, top, width, height);
+       	// #ifdef H5
+        ctxCanvasOper.draw();
+        // #endif
+				ctxCanvasOper.setLineWidth(3);
+				ctxCanvasOper.setStrokeStyle('rgba(255, 255, 255, 1)'); //粗线的颜色
+				ctxCanvasOper.moveTo(left + 20, top);
+				ctxCanvasOper.lineTo(left, top);
+				ctxCanvasOper.lineTo(left, top + 20);
+				ctxCanvasOper.moveTo(left + width - 20, top);
+				ctxCanvasOper.lineTo(left + width, top);
+				ctxCanvasOper.lineTo(left + width, top + 20);
+				ctxCanvasOper.moveTo(left + 20, top + height);
+				ctxCanvasOper.lineTo(left, top + height);
+				ctxCanvasOper.lineTo(left, top + height - 20);
+				ctxCanvasOper.moveTo(left + width - 20, top + height);
+				ctxCanvasOper.lineTo(left + width, top + height);
+				ctxCanvasOper.lineTo(left + width, top + height - 20);
+				ctxCanvasOper.stroke();
+				this.postFirst = {
+					left: left,
+					top: top,
+					width: width,
+					height: selWidth,
+					posWidth: this.posWidth,
+					posHeight: this.posHeight
+				};
+          // #ifdef MP-WEIXIN
+				ctxCanvasOper.draw(false, () => {
+					if (ini) {
+						this.styleDisplay = 'flex';
+						this.styleTop = '0';
+						ctxCanvas.setFillStyle('black');
+						this.fDrawImage();
+					}
+				});
+        // #endif
+        // #ifdef H5
+        ctxCanvasOper.draw(true, () => {
+        	if (ini) {
+        		this.styleDisplay = 'flex';
+        		this.styleTop = this.drawTop + 'px';
+        		ctxCanvas.setFillStyle('black');
+        		this.fDrawImage();
+        	}
+        });
+
+        	// #endif
+
+				this.$emit("avtinit");
+			},
+			fDrawImage() {
+				let tm_now = Date.now();
+				if ((tm_now - this.drawTm )< 20) return;
+				this.drawTm = tm_now;
+				let ctxCanvas = this.ctxCanvas;
+				ctxCanvas.fillRect(0, 0, this.windowWidth, this.windowHeight - tabHeight);
+				//中心点坐标
+				ctxCanvas.translate(this.posWidth + this.useWidth / 2, this.posHeight + this.useHeight / 2);
+				//比例缩放
+				ctxCanvas.scale(this.scaleSize, this.scaleSize);
+				ctxCanvas.drawImage(this.imgPath, -this.useWidth / 2, -this.useHeight / 2, this.useWidth, this.useHeight);
+				ctxCanvas.draw(false);
+			},
+			fHideImg() {
+				this.prvImg = '';
+				this.prvTop = '-10000px';
+				this.showOper = true;
+				this.prvImgData = null;
+				this.target = null;
+			},
+			fClose() {
+				this.styleDisplay = 'none';
+				this.styleTop = '-10000px';
+				this.hasSel = false;
+				this.fHideImg();
+				this.noBar || uni.showTabBar();
+			},
+      // #ifdef MP-WEIXIN
+			fStart(e) {
+				let touches = e.touches,
+					touch0 = touches[0],
+					touch1 = touches[1];
+
+				this.touch0 = touch0;
+				this.touch1 = touch1;
+
+				if (touch1) {
+         let x = touch1.x - touch0.x,
+         	y = touch1.y - touch0.y;
+         this.fgDistance = Math.sqrt(x * x + y * y);
+
+				}
+			},
+      // #endif
+      // #ifdef H5
+      fStart(e) {
+      	let touches = e.touches,
+      		touch0 = touches[0],
+      		touch1 = touches[1];
+
+      	this.touch0 = touch0;
+      	this.touch1 = touch1;
+
+      	if (touch1) {
+            let x = touch1.clientX - touch0.clientX,
+            	y = touch1.clientY - touch0.clientY;
+            this.fgDistance = Math.sqrt(x * x + y * y);
+      	}
+      },
+      // #endif
+      // #ifdef MP-WEIXIN
+			fMove(e) {
+				let touches = e.touches,
+					touch0 = touches[0],
+					touch1 = touches[1];
+
+				if (touch1) {
+					let x = touch1.x - touch0.x,
+						y = touch1.y - touch0.y,
+						fgDistance = Math.sqrt(x * x + y * y),
+						scaleSize = 0.005 * (fgDistance - this.fgDistance),
+						beScaleSize = this.scaleSize + scaleSize;
+
+					do {
+						if (!this.letScale) break;
+						if (beScaleSize < this.mnScale) break;
+						if (beScaleSize > this.mxScale) break;
+						this.scaleSize = beScaleSize;
+					} while (0);
+					this.fgDistance = fgDistance;
+
+					if (touch1.x !== touch0.x && this.letRotate) {
+						x = (this.touch1.y - this.touch0.y) / (this.touch1.x - this.touch0.x);
+						y = (touch1.y - touch0.y) / (touch1.x - touch0.x);
+						this.rotateDeg += Math.atan((y - x) / (1 + x * y)) * 180 / Math.PI;
+						this.touch0 = touch0;
+						this.touch1 = touch1;
+					}
+
+					this.fDrawImage();
+				} else if (this.touch0) {
+					let x = touch0.x - this.touch0.x,
+						y = touch0.y - this.touch0.y,
+						beX = this.posWidth + x,
+						beY = this.posHeight + y;
+						if (Math.abs(x) < 100 && !this.lckWidth) this.posWidth = beX;
+						if (Math.abs(y) < 100 && !this.lckHeight) this.posHeight = beY;
+					this.touch0 = touch0;
+					this.fDrawImage();
+				}
+			},
+        // #endif
+      	// #ifdef H5
+        fMove(e) {
+        	let touches = e.touches,
+        		touch0 = touches[0],
+        		touch1 = touches[1];
+
+        	if (touch1) {
+        		let x = touch1.clientX - touch0.clientX,
+        			y = touch1.clientY - touch0.clientY,
+        			fgDistance = Math.sqrt(x * x + y * y),
+        			scaleSize = 0.005 * (fgDistance - this.fgDistance),
+        			beScaleSize = this.scaleSize + scaleSize;
+
+        		do {
+        			if (!this.letScale) break;
+        			if (beScaleSize < this.mnScale) break;
+        			if (beScaleSize > this.mxScale) break;
+        			this.scaleSize = beScaleSize;
+        		} while (0);
+        		this.fgDistance = fgDistance;
+
+        		if (touch1.x !== touch0.x && this.letRotate) {
+        			x = (this.touch1.clientY - this.touch0.clientY) / (this.touch1.clientX - this.touch0.clientX);
+        			y = (touch1.clientY - touch0.clientY) / (touch1.clientX - touch0.clientX);
+        			this.rotateDeg += Math.atan((y - x) / (1 + x * y)) * 180 / Math.PI;
+        			this.touch0 = touch0;
+        			this.touch1 = touch1;
+        		}
+
+        		this.fDrawImage();
+        	} else if (this.touch0) {
+            let x=touch0.clientX - this.touch0.clientX,
+            y=touch0.clientY - this.touch0.clientY,
+        		// let x = touch0.x - this.touch0.x,
+        		// 	y = touch0.y - this.touch0.y,
+        			beX = this.posWidth + x,
+        			beY = this.posHeight + y;
+        			if (Math.abs(x) < 100 && !this.lckWidth) this.posWidth = beX;
+        			if (Math.abs(y) < 100 && !this.lckHeight) this.posHeight = beY;
+        		this.touch0 = touch0;
+        		this.fDrawImage();
+        	}
+        },
+        	// #endif
+			async fEnd(e) {
+				let self = this;
+				let touches = e.touches,
+					touch0 = touches && touches[0],
+					touch1 = touches && touches[1];
+				if (self.scaleSize < 1) {
+					let style = self.selStyle;
+					let imgRadio = self.imgWidth / self.imgHeight;
+					//高长宽短
+					if (imgRadio < 1 && self.scaleSize * self.useWidth < style.width) {
+						self.posWidth = style.left;
+						self.scaleSize = 1
+						setTimeout(function() {
+							self.fDrawImage();
+						}, 100)
+					} else if (self.scaleSize * self.useHeight < style.width) {
+						//高短宽长
+						self.posHeight = style.top;
+						self.scaleSize = 1
+						setTimeout(function() {
+							self.fDrawImage();
+						}, 100)
+					}
+				} else if (this.scaleSize == 1) {
+					let endWidth = this.posWidth - this.postFirst.posWidth,
+						firstWidth = this.postFirst.left - this.postFirst.posWidth;
+					let endHeight = this.posHeight - this.postFirst.posHeight,
+						firstHigth = this.postFirst.top - this.postFirst.posHeight;
+					if (endWidth > 0 && this.posWidth > this.postFirst.left) {
+						//右滑动过长
+						this.posWidth = this.postFirst.left;
+					} else if (endWidth < 0 && endWidth < firstWidth) {
+						//左滑动过长
+						this.posWidth = -this.postFirst.left + this.postFirst.posWidth * 2;
+					}
+
+					if (endHeight < 0 && this.posHeight < this.postFirst.top) {
+						//上滑动过长
+						this.posHeight = -this.postFirst.top + this.postFirst.posHeight * 2 ;
+					} else if (endHeight > 0 && endHeight > firstHigth) {
+						//下滑动过长
+						this.posHeight = this.postFirst.top;
+					}
+					setTimeout(function() {
+						self.fDrawImage();
+					}, 100);
+
+				}
+				if (touch0) {
+					this.touch0 = touch0;
+				} else {
+					this.touch0 = null;
+					this.touch1 = null;
+				}
+			},
+			btop(base64) {
+				return new Promise(function(resolve, reject) {
+					var arr = base64.split(','),
+						mime = arr[0].match(/:(.*?);/)[1],
+						bstr = atob(arr[1]),
+						n = bstr.length,
+						u8arr = new Uint8Array(n);
+					while (n--) {
+						u8arr[n] = bstr.charCodeAt(n);
+					}
+					return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([u8arr], {
+						type: mime
+					})));
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="less">
+	.my-canvas {
+		display: flex;
+		position: fixed !important;
+		background: #000000;
+		left: 0;
+		z-index: 100;
+		width: 100%;
+	}
+
+	.my-avatar {
+		width: 100vw;
+		height: 100vw;
+	}
+
+	.oper-canvas {
+		display: flex;
+		position: fixed !important;
+		left: 0;
+		z-index: 101;
+		width: 100%;
+	}
+
+	.oper-wrapper {
+		height: 71px;
+		position: fixed !important;
+		box-sizing: border-box;
+		width: 100%;
+		left: 0;
+		bottom: 0;
+		z-index: 200;
+		flex-direction: row;
+	}
+
+	.btn-wrapper {
+		background-color: #000000;
+		color: #ffffff;
+		display: flex;
+		height: 100%;
+		width: 100%;
+		justify-content: space-around;
+		align-items: center
+	}
+
+	.btn-wrapper view {
+		width: 160rpx;
+		height: 80rpx;
+		line-height: 80rpx;
+		text-align: center;
+		font-size: 16px;
+		color: #ffffff;
+		z-index: 300;
+	}
+
+	.hover {
+		color: #f1f1f1;
+	}
+</style>

+ 135 - 19
src/components/upload/index.vue

@@ -1,17 +1,11 @@
 <template>
-	<u-upload :name="name" 
-		:width="width" :height="height"
-		:accept="accept" :fileList="fileList" 
-		:multiple="multiple" :maxCount="maxCount" 
+	<u-upload :name="name" :disabled="disabled" :width="width" :height="height" :accept="accept" :fileList="fileList"
+		:multiple="multiple" :maxCount="maxCount"  previewFullImage="true"
 		@afterRead="afterRead" @delete="onDelete">
 		<slot name="content" :data="fileList"></slot>
-		
-     <image
-      v-if="customImg"
-      src="@/static/discover/ic_upload.png"
-      mode=""
-      :style="{width: width + 'px', height: height + 'px',borderRadius: '12rpx'}"
-    ></image>
+
+		<image v-if="customImg" src="@/static/discover/ic_upload.png" mode=""
+			:style="{ width: width + 'px', height: height + 'px', borderRadius: '12rpx' }"></image>
 	</u-upload>
 </template>
 
@@ -20,6 +14,10 @@ import { baseUrl } from '@/common/config.js';
 export default {
 	name: "",
 	props: {
+		disabled: {
+			type: Boolean,
+			default: false
+		},
 		api: {
 			type: String,
 			default: '/common/upload'
@@ -40,10 +38,10 @@ export default {
 			type: [String, Number],
 			default: uni.$u.props.upload.height
 		},
-        // 文件大小限制,单位为byte
+		// 文件大小限制,单位为byte
 		maxSize: {
 			type: [String, Number],
-            default: uni.$u.props.upload.maxSize
+			default: uni.$u.props.upload.maxSize
 		},
 		maxCount: {
 			type: Number,
@@ -63,6 +61,11 @@ export default {
 			type: Array,
 			default: () => ['mp4', 'mov', 'mkv', 'wmv']
 		},
+		// 音频格式限制
+		audioFormats: {
+			type: Array,
+			default: () => ['mp3', 'wav', 'wma', 'm4a']
+		},
 		// 图片大小限制,单位为byte
 		maxImageSize: {
 			type: Number,
@@ -73,6 +76,11 @@ export default {
 			type: Number,
 			default: 50 * 1024 * 1024 // 默认50MB
 		},
+		// 音频大小限制,单位为byte
+		maxAudioSize: {
+			type: Number,
+			default: 10 * 1024 * 1024 // 默认10MB
+		},
 		customImg: {
 			type: Boolean,
 			default: false
@@ -81,6 +89,16 @@ export default {
 			type: Array,
 			default: []
 		},
+		// 是否启用图片预览
+		previewImage: {
+			type: Boolean,
+			default: true
+		},
+		// 是否全屏预览
+		previewFullImage: {
+			type: Boolean,
+			default: true
+		},
 	},
 	data() {
 		return {
@@ -102,23 +120,29 @@ export default {
 			// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
 			let lists = [].concat(event.file);
 			let fileListLen = this[`fileList`].length;
-			
+
 			// 验证文件格式和大小
 			for (let i = 0; i < lists.length; i++) {
 				const file = lists[i];
 				const fileName = file.name.split('/').pop();
 				const fileExtension = fileName.split('.').pop().toLowerCase();
-				
-				// 根据文件扩展名判断是图片还是视频(优先使用扩展名判断)
+
+				// 根据文件扩展名判断是图片、视频还是音频(优先使用扩展名判断)
 				const isImage = this.imageFormats.includes(fileExtension);
 				const isVideo = this.videoFormats.includes(fileExtension);
-				
+				const isAudio = this.audioFormats.includes(fileExtension);
+
 				if (isImage) {
 					// 图片验证
 					if (file.size && file.size > this.maxImageSize) {
 						const maxSizeMB = (this.maxImageSize / 1024 / 1024).toFixed(1);
 						uni.$u.toast(`图片大小不能超过 ${maxSizeMB}MB`);
 						return;
+					} else {
+						// 压缩后可能是 File 对象(H5)或 URL 字符串(App/小程序)
+						const compressedResult = await this.compressImage(file.url);
+						// 保存原始 URL 用于预览,压缩结果用于上传
+						lists[i].compressedFile = compressedResult;
 					}
 				} else if (isVideo) {
 					// 视频验证
@@ -127,8 +151,15 @@ export default {
 						uni.$u.toast(`视频大小不能超过 ${maxSizeMB}MB`);
 						return;
 					}
+				} else if (isAudio) {
+					// 音频验证
+					if (file.size && file.size > this.maxAudioSize) {
+						const maxSizeMB = (this.maxAudioSize / 1024 / 1024).toFixed(1);
+						uni.$u.toast(`音频大小不能超过 ${maxSizeMB}MB`);
+						return;
+					}
 				} else {
-					// 既不是图片也不是视频,检查是否有file.type
+					// 无法判断类型或类型不支持,检查是否有file.type
 					if (file.type) {
 						if (file.type.startsWith('image/')) {
 							// 是图片但扩展名不在允许列表中
@@ -138,6 +169,10 @@ export default {
 							// 是视频但扩展名不在允许列表中
 							uni.$u.toast(`视频格式仅限 ${this.videoFormats.join(', ')}`);
 							return;
+						} else if (file.type.startsWith('audio/')) {
+							// 是音频但扩展名不在允许列表中
+							uni.$u.toast(`音频格式仅限 ${this.audioFormats.join(', ')}`);
+							return;
 						}
 					}
 					// 无法判断类型或类型不支持
@@ -145,12 +180,13 @@ export default {
 					return;
 				}
 			}
-			
+
 			lists.map((item) => {
 				this[`fileList`].push({
 					...item,
 					status: "uploading",
 					message: "上传中",
+					localUrl: item.url, // 保存原始本地路径用于预览
 				});
 			});
 			// 无预览时,使用toast
@@ -185,6 +221,85 @@ export default {
 			}
 			this.$emit('fileList', this.fileList);
 		},
+		// 图片压缩 - 支持H5、App、小程序三端
+		// 使用条件编译区分平台
+		async compressImage(url) {
+			// #ifdef H5
+			// H5 环境直接使用 Canvas 压缩
+			try {
+				return await this.canvasCompress(url, 0.8);
+			} catch (err) {
+				console.warn('Canvas 压缩失败,使用原图片:', err);
+				return url;
+			}
+			// #endif
+
+			// #ifndef H5
+			// App 和小程序使用 uni.compressImage
+			return new Promise((resolve) => {
+				uni.compressImage({
+					src: url,
+					quality: 0.8,
+					success: (res) => {
+						resolve(res.tempFilePath);
+					},
+					fail: (err) => {
+						console.warn('uni.compressImage 失败,使用原图片:', err);
+						resolve(url);
+					}
+				});
+			});
+			// #endif
+		},
+		// Canvas 图片压缩(H5 专用)
+		canvasCompress(url, quality) {
+			return new Promise((resolve, reject) => {
+				const img = new Image();
+				img.crossOrigin = 'anonymous';
+				img.onload = () => {
+					const canvas = document.createElement('canvas');
+					const ctx = canvas.getContext('2d');
+
+					// 计算压缩后的尺寸(保持宽高比)
+					const maxWidth = 1200;
+					const maxHeight = 1200;
+					let width = img.width;
+					let height = img.height;
+
+					if (width > maxWidth) {
+						height = (maxWidth / width) * height;
+						width = maxWidth;
+					}
+					if (height > maxHeight) {
+						width = (maxHeight / height) * width;
+						height = maxHeight;
+					}
+
+					canvas.width = width;
+					canvas.height = height;
+					ctx.drawImage(img, 0, 0, width, height);
+
+					// 将 Canvas 转换为 File 对象
+					canvas.toBlob((blob) => {
+						if (blob) {
+							// 确保文件名以 .jpg 结尾
+							const originalName = url.split('/').pop() || 'image';
+							const fileName = originalName.endsWith('.jpg') || originalName.endsWith('.jpeg')
+								? originalName
+								: originalName + '.jpg';
+							const file = new File([blob], fileName, { type: 'image/jpeg' });
+							resolve(file);
+						} else {
+							reject('Blob 创建失败');
+						}
+					}, 'image/jpeg', quality);
+				};
+				img.onerror = (err) => {
+					reject('图片加载失败: ' + err);
+				};
+				img.src = url;
+			});
+		},
 		uploadFilePromise(url) {
 			return new Promise((resolve, reject) => {
 				uni.uploadFile({
@@ -223,6 +338,7 @@ export default {
 				}
 			})
 		},
+		
 	}
 }
 </script>

+ 12 - 0
src/pages.json

@@ -272,6 +272,18 @@
 						}
 			}
 		},
+		{
+			"path": "pages/join/cropImage",
+			"style": {
+				"navigationBarTitleText": "裁剪照片",
+				"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
+			}
+		},
 		{
 			"path": "pages/join/introduceYourselfEdit",
 			"style": {

+ 91 - 28
src/pages/join/applyJoin.vue

@@ -12,15 +12,17 @@
                 <uni-list-item title="姓名" :rightText="baseInfo.name" />
                 <uni-list-item title="性别" :rightText="baseInfo.name" />
                 <uni-list-item title="手机号" :rightText="baseInfo.name" />
-                <uni-list-item  showArrow title="昵称" :class="{'hasText': baseInfo.name}" clickable @click="introduceYourselfEdit(baseInfo.introduceYourself)"
-                    :rightText="baseInfo.name ? baseInfo.name : '昵称'" style="color: red!important;"/>
+                <uni-list-item showArrow title="昵称" :class="{ 'hasText': baseInfo.name }" clickable
+                    @click="introduceYourselfEdit(baseInfo.introduceYourself)"
+                    :rightText="baseInfo.name ? baseInfo.name : '昵称'" style="color: red!important;" />
 
                 <uni-list-item title="入驻城市" :rightText="baseInfo.name" />
-                <uni-list-item showArrow title="简介" :class="{'hasText': baseInfo.introduceYourself}" clickable @click="introduceYourselfEdit(baseInfo.introduceYourself)"
+                <uni-list-item showArrow title="简介" :class="{ 'hasText': baseInfo.introduceYourself }" clickable
+                    @click="introduceYourselfEdit(baseInfo.introduceYourself)"
                     :rightText="baseInfo.introduceYourself ? baseInfo.introduceYourself : '简单的介绍您自己~'" />
             </uni-list>
         </view>
-        <view class="baseInfo" style="margin-top: 16rpx;height: 69vh;">
+        <view class="baseInfo" style="margin-top: 16rpx;height: 80vh;">
             <view class="title">
                 <view class="lineIcon">
                     <image src="/static/login/lineIcon.png" mode=""></image>
@@ -30,16 +32,17 @@
             </view>
             <uni-list>
 
-                <uni-list-item title="形象照" :class="{'portraitPhotoRow': baseInfo.portraitPhoto}" showArrow clickable
-                 @click="portraitPhotoFun" :rightText="baseInfo.portraitPhoto? '形象照' : '形象照'">
+                <uni-list-item title="形象照" :class="{ 'portraitPhotoRow': baseInfo.portraitPhoto }" showArrow clickable
+                    @click="portraitPhotoFun" :rightText="baseInfo.portraitPhoto ? '形象照' : '形象照'">
                     <template v-slot:footer v-if="baseInfo.portraitPhoto">
-                        <image  class="slot-image"
+                        <image class="slot-image"
                             :src="baseInfo.portraitPhoto ? baseInfo.portraitPhoto : '/static/logo.png'" mode="widthFix">
                         </image>
                     </template>
                 </uni-list-item>
-                <uni-list-item showArrow title="生活照" :rightText="baseInfo.cImgList.length > 0 ? baseInfo.cImgList.length+'项' : '去上传'"
-                    :class="{'hasText': baseInfo.cImgList.length > 0}" clickable
+                <uni-list-item showArrow title="生活照"
+                    :rightText="baseInfo.cImgList.length > 0 ? baseInfo.cImgList.length + '项' : '去上传'"
+                    :class="{ 'hasText': baseInfo.cImgList.length > 0 }" clickable
                     @click="pictureUpLoad('cImgList', '生活照', 9)" />
                 <uni-list-item showArrow title="宣传视频" :rightText="baseInfo.promotionalVideo.length > 0 ? '已上传' : '去上传'"
                     clickable @click="pictureUpLoad('promotionalVideo', '宣传视频')" />
@@ -99,12 +102,23 @@ export default {
                 promotionalVideo: [],
                 idCard: [],
                 commitDocment: [[], [], []],
-            }
+            },
+            ShopInfo: {},
 
         }
     },
-    onLoad() {
-    },
+    onLoad(options) {
+		console.log(options,'66666')
+		if (options.ShopInfo) {
+            this.ShopInfo = JSON.parse(options.ShopInfo)
+            this.baseInfo.name=this.ShopInfo.teName
+            this.baseInfo.gender=this.ShopInfo.teSex==0?'女':'男'
+            this.baseInfo.phone=this.ShopInfo.tePhone
+            this.baseInfo.nickName=this.ShopInfo.teNickName
+            this.baseInfo.city=this.ShopInfo.teAddress
+        }
+		
+	},
     onShow() {
     },
     methods: {
@@ -138,27 +152,69 @@ export default {
             uni.navigateTo({ url: '/pages/join/introduceYourselfEdit?introduceYourself=' + this.baseInfo.introduceYourself })
         },
         portraitPhotoFun() {
-            // const perResult = requestAndroidPermission('android.permission.CAMERA', {
-            //     title: '相册/相机权限申请说明',
-            //     content: '为了修改个人头像和订单评价发布信息图片视频等, 我们需要申请您设备的相机和存储权限',
-            // }, true);
             console.log('8888888')
             uni.chooseImage({
                 count: 1,
                 sizeType: ['original', 'compressed'],
                 sourceType: ['album'],
                 success: (res) => {
-                    if (res) {
-                        this.baseInfo.portraitPhoto = res.tempFilePaths[0]
+                    if (res && res.tempFilePaths.length > 0) {
+                        const filePath = res.tempFilePaths[0]
+                        
+
+                        // #ifdef MP-WEIXIN
+                        // 微信小程序使用uni.cropImage裁剪
+                        uni.cropImage({
+                            src: filePath,
+                            success: (cropRes) => {
+                                if (cropRes && cropRes.tempFilePath) {
+                                    this.baseInfo.portraitPhoto = cropRes.tempFilePath
+                                }
+                            },
+                            fail: () => {
+                                uni.showToast({
+                                    title: '裁剪失败',
+                                    icon: 'none'
+                                })
+                            }
+                        })
+                        // #endif
+
+                        // #ifdef H5
+                        // H5端跳转到自定义裁剪页面
+                        uni.navigateTo({
+                            url: `/pages/join/cropImage?imageSrc=${encodeURIComponent(filePath)}`
+                        })
+                        // #endif
                     }
+                },
+                fail: () => {
+                    uni.showToast({
+                        title: '选择图片失败',
+                        icon: 'none'
+                    })
                 }
             });
         },
 
+
         // 提交表单
         submitForm() {
             // 接口请求提交入驻资料
-            console.log('提交入驻', this.form)
+            console.log('提交入驻', this.baseInfo)
+            applyFile(this.baseInfo).then(res => {
+                if (res.data.code == 200) {
+                    uni.showToast({
+                        title: '提交成功',
+                        icon: 'success'
+                    })
+                } else {
+                    uni.showToast({
+                        title: res.data.msg,
+                        icon: 'none'
+                    })
+                }
+            })
         }
     },
     mounted() {
@@ -178,10 +234,11 @@ export default {
         padding: 0 !important;
 
     }
+
     .uni-icons {
         color: #1D2129 !important;
         font-size: 26rpx !important;
-        margin-right: -10rpx!important;
+        margin-right: -10rpx !important;
         margin-top: 6rpx;
     }
 
@@ -207,7 +264,7 @@ export default {
 
 
 
-    
+
 
 }
 
@@ -219,20 +276,24 @@ export default {
         color: #C9CDD4 !important;
     }
 }
+
 ::v-deep .hasText {
     .uni-list-item__extra-text {
-        color: #4E5969!important;
+        color: #4E5969 !important;
     }
-   
+
 }
-::v-deep .slot-image{
+
+::v-deep .slot-image {
     width: 58px;
     height: 58px;
+    
     border-radius: 50%;
 
 }
-::v-deep .portraitPhotoRow{
-    .uni-list-item__content-title{
+
+::v-deep .portraitPhotoRow {
+    .uni-list-item__content-title {
         margin-top: 13rpx;
     }
 
@@ -240,8 +301,9 @@ export default {
 
 .applyJoin {
     background-color: #F7F8FA;
-    min-height: 100vh;
-  
+    height: 100vh;
+    margin-bottom: 300rpx;
+
 
     ::v-deep .uni-list-item {
         height: 106rpx;
@@ -308,6 +370,7 @@ export default {
         position: fixed;
         bottom: 0;
         height: 136rpx;
+
         button {
             color: #FFFFFF;
             width: 654rpx;

+ 131 - 52
src/pages/join/commitDocumentEdit.vue

@@ -1,37 +1,116 @@
 <template>
-    <view>
-        <view class="images">
-            <view>承诺书
-                <view>请上传 大小不超过 10MB 格式为 pdf/jpg/jpeg/png 的文件</view>
-                <Upload accept="file" :maxSize="10240" :maxCount="2" @fileList="onUpload($event, 'commitment')" :fileList="commitment"/>
+    <view class="commitDocument">
+        <view>
+            <view class="content">
+                <view class="title">承诺书</view>
+                <view class="tip">请上传 大小不超过 2MB 格式为 jpg/jpeg/png 的文件</view>
+                <Upload :maxCount="9" @fileList="onUpload($event, 'commitment')" :fileList="commitment">
+                    <view class="upload-block" slot="content">
+                        <view class="icon-bg">
+                            <image src="/static/login/cameraIcon.png" mode="widthFix"
+                                style="width: 52rpx;height: 52rpx;">
+                            </image>
+                            <view style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;margin-top: -13rpx;">上传</view>
+
+                        </view>
+
+                    </view>
+
+
+                </Upload>
             </view>
-            <view>承诺录音
-                <view>请上传 大小不超过 10MB 格式为 mp3/wav/wma 的文件</view>
-                <Upload accept="file" :maxSize="10240" :maxCount="2" @fileList="onUpload($event, 'recording')" :fileList="recording"/>
+            <view class="content">
+                <view class="title">承诺录音</view>
+                <view class="tip">请上传 大小不超过 10MB 格式为 mp3/wav/wma 的文件</view>
+                <Upload :accept="audio" :maxCount="1" @fileList="onUpload($event, 'recording')" :fileList="recording">
+                    <view class="upload-block" slot="content">
+                        <view class="icon-bg">
+                            <image src="/static/login/cameraIcon.png" mode="widthFix"
+                                style="width: 52rpx;height: 52rpx;">
+                            </image>
+                            <view style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;margin-top: -13rpx;">上传</view>
+
+                        </view>
+
+                    </view>
+
+
+                </Upload>
             </view>
-            <view>承诺录像
-                <view>请上传 大小不超过 50MB 格式为 mp4/mov/mkv/wmv 的文件</view>
-                <Upload accept="file" :maxSize="51200" :maxCount="2" @fileList="onUpload($event, 'videoRecording')"  :fileList="videoRecording"/>
+            <view class="content">
+                <view class="title">承诺录像</view>
+                <view class="tip">请上传 大小不超过 50MB 格式为 mp4/mov/mkv/wmv 的文件</view>
+                <view v-if="videoRecording.length > 0">
+                    <uni-icons class="icon iconfont icon-cuo" type="trash-filled" size="20"
+                        @tap="delectVideo"></uni-icons>
+                    <video ref="myVideo" :src="videoRecording[0].mediaUrl" class="video-container" controls></video>
+                </view>
+                <Upload v-else :accept="'video'" :maxCount="1" @fileList="onUpload($event, 'videoRecording')"
+                    :fileList="videoRecording">
+                    <view class="upload-block" slot="content">
+                        <view class="icon-bg">
+                            <image src="/static/login/cameraIcon.png" mode="widthFix"
+                                style="width: 52rpx;height: 52rpx;">
+                            </image>
+                            <view style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;margin-top: -13rpx;">上传</view>
+
+                        </view>
+
+                    </view>
+
+
+                </Upload>
+                <!-- <view class="media-area">
+                    <view v-if="formData.videoUrl">
+                        <uni-icons class="icon iconfont icon-cuo" type="trash-filled" size="20"
+                            @tap="delectVideo"></uni-icons>
+                        <video ref="myVideo" :src="formData.videoUrl" class="video-container" controls></video>
+                    </view>
+                    <clUpload v-else v-model="fileList" :action="uploadApi" :headers="headers" :count="maxCount"
+                        :listStyle="{
+                            columnGap: '20rpx',
+                            rowGap: '20rpx',
+                            width: '130rpx',
+                            radius: '12rpx',
+                        }" :imageFormData="{
+                            count: 9,
+                            size: 2,
+                        }" :videoFromData="{
+                                count: 1,
+                                size: 50,
+                            }" :maxVideo="1" :fileType="mediaType" addImg="/static/discover/ic_upload.png"
+                        deleteImg="/static/discover/ic_delete.png" @onSuccess="onSuccess"
+                        @onMediaTypeSelect="selectMediaType" @onError="onCancel"></clUpload>
+                </view> -->
             </view>
 
             <view class="footer-bar">
-                <u-button shape="circle" :customStyle="{
+                <u-button :customStyle="{
+                    padding: '24rpx 48rpx',
                     color: '#fff',
-                    background: 'var(--theme-color-gradient)'
-                }" @click="onSubmit">确认修改</u-button>
+                    background: 'var(--theme-color-gradient)',
+                    width: '654rpx',
+                    height: '88rpx',
+                    background: '#333335',
+                    borderRadius: '60rpx 60rpx 60rpx 60rpx',
+                }" @click="onSubmit">保存</u-button>
             </view>
         </view>
     </view>
 </template>
 
 <script>
-
+import clUpload from '@/components/cl-upload/cl-upload/cl-upload.vue'
 import Upload from '@/components/upload/index.vue';
 
 export default {
-    components: { Upload },
+    components: { Upload, clUpload },
     data() {
         return {
+            videoUrl: '',
+            fileList: [],
+            mediaType: 'all', // 默认为图片模式,上传第一个文件后确定类型
+            uploadApi: baseUrl + '/common/upload', // 默认使用图片上传接口
             fieldName: '',
             commitment: [],
             recording: [],
@@ -44,7 +123,7 @@ export default {
         if (query.fieldName) this.fieldName = query.fieldName
         if (query.fieldVal) {
             let fieldVal = JSON.parse(query.fieldVal)
-            console.log(fieldVal,'fieldVal')
+            console.log(fieldVal, 'fieldVal')
             this.commitment = fieldVal[0] ? fieldVal[0] : []
             this.recording = fieldVal[1] ? fieldVal[1] : []
             this.videoRecording = fieldVal[2] ? fieldVal[2] : []
@@ -85,6 +164,41 @@ export default {
 </script>
 
 <style scoped lang="scss">
+.commitDocument {
+    height: 100vh;
+    background-color: #F7F8FA;
+
+    .content {
+        background-color: #fff;
+        padding: 32rpx;
+
+        .upload-block {
+            width: 160rpx;
+            height: 160rpx;
+            background-color: #F7F8FA;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            border-radius: 12rpx;
+        }
+
+        .title {
+            font-weight: 500;
+            font-size: 30rpx;
+            color: #1D2129;
+        }
+
+        .tip {
+            margin-top: 16rpx;
+            font-weight: 400;
+            font-size: 26rpx;
+            color: #86909C;
+            margin-bottom: 16rpx;
+        }
+    }
+
+}
+
 /* 身份证上传样式 */
 .id-upload-row {
     gap: 10rpx;
@@ -92,39 +206,4 @@ export default {
     justify-content: space-between;
     margin-bottom: 20rpx;
 }
-
-.upload-block {
-    // width: 100%;
-    height: 220rpx;
-    background-color: #f9f9f9;
-    border-radius: 12rpx;
-    border: 1rpx dashed #eee;
-    display: flex;
-    align-items: center;
-    flex-direction: column;
-    justify-content: center;
-    position: relative;
-    overflow: hidden;
-
-    &.full-width {
-        width: 100%;
-        height: 240rpx;
-    }
-
-    .icon-bg {
-        width: 60rpx;
-        height: 60rpx;
-        background-color: #00cba3;
-        border-radius: 50%;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        margin-bottom: 16rpx;
-    }
-
-    .up-text {
-        font-size: 24rpx;
-        color: #666;
-    }
-}
 </style>

+ 480 - 0
src/pages/join/cropImage.vue

@@ -0,0 +1,480 @@
+<template>
+  <view class="crop-page">
+    <view class="crop-header">
+      <view class="header-btn cancel" @click="cancel">取消</view>
+      <view class="header-title">照片裁剪</view>
+      <view class="header-btn confirm" @click="confirm">确定</view>
+    </view>
+
+    <view class="crop-container" ref="cropContainer">
+      <!-- 原图显示区域 -->
+      <image class="original-image" :src="imageSrc" mode="aspectFit"></image>
+
+      <!-- 裁剪框遮罩 -->
+      <view class="crop-mask"></view>
+
+      <!-- 裁剪框 -->
+      <view class="crop-box" :style="{
+        left: cropBox.x + 'px',
+        top: cropBox.y + 'px',
+        width: cropBox.size + 'px',
+        height: cropBox.size + 'px'
+      }" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd" @mousedown="onMouseDown">
+        <!-- 九宫格线 -->
+        <view class="grid-lines">
+          <view class="grid-line horizontal"></view>
+          <view class="grid-line horizontal"></view>
+          <view class="grid-line vertical"></view>
+          <view class="grid-line vertical"></view>
+        </view>
+
+        <!-- 四角控制点 -->
+        <view class="corner-tl" @touchstart.stop="onCornerStart('tl', $event)"
+          @mousedown.stop="onCornerMouseDown('tl', $event)"></view>
+        <view class="corner-tr" @touchstart.stop="onCornerStart('tr', $event)"
+          @mousedown.stop="onCornerMouseDown('tr', $event)"></view>
+        <view class="corner-bl" @touchstart.stop="onCornerStart('bl', $event)"
+          @mousedown.stop="onCornerMouseDown('bl', $event)"></view>
+        <view class="corner-br" @touchstart.stop="onCornerStart('br', $event)"
+          @mousedown.stop="onCornerMouseDown('br', $event)"></view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      imageSrc: '',
+      cropBox: {
+        x: 0,
+        y: 0,
+        size: 200
+      },
+      imageSize: {
+        width: 0,
+        height: 0
+      },
+      containerSize: {
+        width: 0,
+        height: 0
+      },
+      displayWidth: 0,
+      displayHeight: 0,
+      imageOffsetX: 0,
+      imageOffsetY: 0,
+      scale: 1,
+      touchStart: {},
+      resizeStart: {},
+      isDragging: false,
+      isResizing: false
+    }
+  },
+  onLoad(options) {
+    this.imageSrc = decodeURIComponent(options.imageSrc)
+    this.initCropBox()
+  },
+  onReady() {
+    this.getImageInfo()
+  },
+  methods: {
+    initCropBox() {
+      this.cropBox.size = 200
+    },
+    getImageInfo() {
+      uni.getImageInfo({
+        src: this.imageSrc,
+        success: (res) => {
+          this.imageSize.width = res.width
+          this.imageSize.height = res.height
+          this.calculateCropBox()
+        },
+        fail: () => {
+          // 如果获取图片信息失败,使用默认尺寸
+          this.imageSize.width = 1000
+          this.imageSize.height = 1000
+          this.calculateCropBox()
+        }
+      })
+    },
+    calculateCropBox() {
+      const sysInfo = uni.getSystemInfoSync()
+      
+      // header高度约为 88rpx = 44px
+      const headerHeight = 44
+      
+      this.containerSize.width = sysInfo.windowWidth
+      this.containerSize.height = sysInfo.windowHeight - headerHeight
+
+      // 计算图片缩放比例(aspectFit模式)
+      this.scale = Math.min(
+        this.containerSize.width / this.imageSize.width,
+        this.containerSize.height / this.imageSize.height
+      )
+
+      // 图片实际显示尺寸
+      this.displayWidth = this.imageSize.width * this.scale
+      this.displayHeight = this.imageSize.height * this.scale
+
+      // 图片居中偏移(考虑状态栏和header)
+      this.imageOffsetX = (this.containerSize.width - this.displayWidth) / 2
+      this.imageOffsetY = (this.containerSize.height - this.displayHeight) / 2
+      
+      // 如果图片比容器小,确保偏移量不为负
+      this.imageOffsetX = Math.max(0, this.imageOffsetX)
+      this.imageOffsetY = Math.max(0, this.imageOffsetY)
+
+      // 裁剪框最大尺寸(不超过图片显示尺寸)
+      const maxBoxSize = Math.min(200, Math.min(this.displayWidth, this.displayHeight))
+      this.cropBox.size = Math.max(80, maxBoxSize)
+      
+      // 裁剪框初始位置(居中在图片上)
+      this.cropBox.x = this.imageOffsetX + (this.displayWidth - this.cropBox.size) / 2
+      this.cropBox.y = this.imageOffsetY + (this.displayHeight - this.cropBox.size) / 2
+      
+      // 调试信息
+      console.log('容器高度:', this.containerSize.height)
+      console.log('图片显示高度:', this.displayHeight)
+      console.log('图片Y偏移:', this.imageOffsetY)
+      console.log('裁剪框初始Y:', this.cropBox.y)
+      console.log('裁剪框最大Y:', this.imageOffsetY + this.displayHeight - this.cropBox.size)
+    },
+    onTouchStart(e) {
+      const touch = e.touches[0]
+      this.touchStart = {
+        x: touch.clientX,
+        y: touch.clientY,
+        boxX: this.cropBox.x,
+        boxY: this.cropBox.y
+      }
+      this.isDragging = true
+    },
+    onTouchMove(e) {
+      if (!this.isDragging) return
+      e.preventDefault()
+
+      const touch = e.touches[0]
+      const deltaX = touch.clientX - this.touchStart.x
+      const deltaY = touch.clientY - this.touchStart.y
+
+      let newX = this.touchStart.boxX + deltaX
+      let newY = this.touchStart.boxY + deltaY
+
+      // 限制裁剪框在图片显示区域内
+      const maxX = this.imageOffsetX + this.displayWidth - this.cropBox.size
+      const maxY = this.imageOffsetY + this.displayHeight - this.cropBox.size
+      
+      // 确保边界值有效
+      const effectiveMinX = Math.min(this.imageOffsetX, maxX)
+      const effectiveMaxX = Math.max(this.imageOffsetX, maxX)
+      const effectiveMinY = Math.min(this.imageOffsetY, maxY)
+      const effectiveMaxY = Math.max(this.imageOffsetY, maxY)
+      
+      newX = Math.max(effectiveMinX, Math.min(newX, effectiveMaxX))
+      newY = Math.max(effectiveMinY, Math.min(newY, effectiveMaxY))
+
+      this.cropBox.x = newX
+      this.cropBox.y = newY
+    },
+    onTouchEnd() {
+      this.isDragging = false
+      this.isResizing = false
+    },
+    onMouseDown(e) {
+      this.touchStart = {
+        x: e.clientX,
+        y: e.clientY,
+        boxX: this.cropBox.x,
+        boxY: this.cropBox.y
+      }
+      this.isDragging = true
+      this.isResizing = false
+
+      document.addEventListener('mousemove', this.onMouseMove)
+      document.addEventListener('mouseup', this.onMouseUp)
+    },
+    onMouseMove(e) {
+      if (!this.isDragging && !this.isResizing) return
+
+      if (this.isDragging && !this.isResizing) {
+        const deltaX = e.clientX - this.touchStart.x
+        const deltaY = e.clientY - this.touchStart.y
+
+        let newX = this.touchStart.boxX + deltaX
+        let newY = this.touchStart.boxY + deltaY
+
+        // 限制裁剪框在图片显示区域内
+        const maxX = this.imageOffsetX + this.displayWidth - this.cropBox.size
+        const maxY = this.imageOffsetY + this.displayHeight - this.cropBox.size
+        
+        // 确保边界值有效
+        const effectiveMinX = Math.min(this.imageOffsetX, maxX)
+        const effectiveMaxX = Math.max(this.imageOffsetX, maxX)
+        const effectiveMinY = Math.min(this.imageOffsetY, maxY)
+        const effectiveMaxY = Math.max(this.imageOffsetY, maxY)
+        
+        newX = Math.max(effectiveMinX, Math.min(newX, effectiveMaxX))
+        newY = Math.max(effectiveMinY, Math.min(newY, effectiveMaxY))
+
+        this.cropBox.x = newX
+        this.cropBox.y = newY
+      } else if (this.isResizing) {
+        this.handleResize(e.clientX, e.clientY)
+      }
+    },
+    onMouseUp() {
+      this.isDragging = false
+      this.isResizing = false
+      document.removeEventListener('mousemove', this.onMouseMove)
+      document.removeEventListener('mouseup', this.onMouseUp)
+    },
+    onCornerStart(corner, e) {
+      const touch = e.touches[0]
+      this.resizeStart = {
+        x: touch.clientX,
+        y: touch.clientY,
+        boxX: this.cropBox.x,
+        boxY: this.cropBox.y,
+        boxSize: this.cropBox.size,
+        corner: corner
+      }
+      this.isResizing = true
+      this.isDragging = false
+
+      document.addEventListener('touchmove', this.onCornerTouchMove)
+      document.addEventListener('touchend', this.onCornerTouchEnd)
+    },
+    onCornerTouchMove(e) {
+      if (!this.isResizing) return
+      e.preventDefault()
+      const touch = e.touches[0]
+      this.handleResize(touch.clientX, touch.clientY)
+    },
+    onCornerTouchEnd() {
+      this.isResizing = false
+      document.removeEventListener('touchmove', this.onCornerTouchMove)
+      document.removeEventListener('touchend', this.onCornerTouchEnd)
+    },
+    onCornerMouseDown(corner, e) {
+      this.resizeStart = {
+        x: e.clientX,
+        y: e.clientY,
+        boxX: this.cropBox.x,
+        boxY: this.cropBox.y,
+        boxSize: this.cropBox.size,
+        corner: corner
+      }
+      this.isResizing = true
+      this.isDragging = false
+
+      document.addEventListener('mousemove', this.onCornerMouseMove)
+      document.addEventListener('mouseup', this.onCornerMouseUp)
+    },
+    onCornerMouseMove(e) {
+      if (!this.isResizing) return
+      this.handleResize(e.clientX, e.clientY)
+    },
+    onCornerMouseUp() {
+      this.isResizing = false
+      document.removeEventListener('mousemove', this.onCornerMouseMove)
+      document.removeEventListener('mouseup', this.onCornerMouseUp)
+    },
+    handleResize(clientX, clientY) {
+      const deltaX = clientX - this.resizeStart.x
+      const deltaY = clientY - this.resizeStart.y
+      const corner = this.resizeStart.corner
+
+      let newSize = this.resizeStart.boxSize
+      let newX = this.resizeStart.boxX
+      let newY = this.resizeStart.boxY
+
+      const minSize = 80
+      const maxSize = Math.min(this.displayWidth, this.displayHeight)
+
+      switch (corner) {
+        case 'br':
+          // 右下角:向右下方拖动放大
+          newSize = Math.max(minSize, Math.min(maxSize, this.resizeStart.boxSize + deltaX))
+          break
+        case 'bl':
+          // 左下角:向左拖动放大,X位置右移
+          newSize = Math.max(minSize, Math.min(maxSize, this.resizeStart.boxSize - deltaX))
+          newX = this.resizeStart.boxX + deltaX
+          break
+        case 'tr':
+          // 右上角:向上拖动放大,Y位置下移
+          newSize = Math.max(minSize, Math.min(maxSize, this.resizeStart.boxSize - deltaY))
+          newY = this.resizeStart.boxY + deltaY
+          break
+        case 'tl':
+          // 左上角:向左上方拖动放大,X右移,Y下移
+          const deltaTL = Math.max(-deltaX, -deltaY)
+          newSize = Math.max(minSize, Math.min(maxSize, this.resizeStart.boxSize + deltaTL))
+          newX = this.resizeStart.boxX + deltaX
+          newY = this.resizeStart.boxY + deltaY
+          break
+      }
+
+      // 确保位置在图片边界内
+      newX = Math.max(this.imageOffsetX, Math.min(newX, this.imageOffsetX + this.displayWidth - newSize))
+      newY = Math.max(this.imageOffsetY, Math.min(newY, this.imageOffsetY + this.displayHeight - newSize))
+
+      this.cropBox.size = newSize
+      this.cropBox.x = newX
+      this.cropBox.y = newY
+    },
+    cancel() {
+      uni.navigateBack()
+    },
+    confirm() {
+      uni.showLoading({ title: '裁剪中...' })
+
+      const canvas = document.createElement('canvas')
+      const ctx = canvas.getContext('2d')
+      canvas.width = this.cropBox.size
+      canvas.height = this.cropBox.size
+
+      const img = new Image()
+      img.crossOrigin = 'anonymous'
+      img.src = this.imageSrc
+
+      img.onload = () => {
+        // 计算裁剪区域在原图中的坐标
+        const boxInImageX = this.cropBox.x - this.imageOffsetX
+        const boxInImageY = this.cropBox.y - this.imageOffsetY
+        
+        const cropX = boxInImageX / this.scale
+        const cropY = boxInImageY / this.scale
+        const cropSize = this.cropBox.size / this.scale
+
+        // 确保裁剪区域在原图范围内
+        const actualCropX = Math.max(0, cropX)
+        const actualCropY = Math.max(0, cropY)
+        const actualCropSize = Math.min(cropSize, img.width - actualCropX, img.height - actualCropY)
+
+        ctx.drawImage(img, actualCropX, actualCropY, actualCropSize, actualCropSize, 0, 0, canvas.width, canvas.height)
+
+        const croppedImage = canvas.toDataURL('image/png')
+
+        uni.hideLoading()
+        
+        // 更新上一页数据
+        const pages = getCurrentPages()
+        if (pages.length >= 2) {
+          const prevPage = pages[pages.length - 2]
+          if (prevPage && prevPage.$data && prevPage.$data.baseInfo) {
+            prevPage.$data.baseInfo.portraitPhoto = croppedImage
+          }
+        }
+        
+        uni.$emit('cropSuccess', croppedImage)
+        uni.navigateBack()
+      }
+
+      img.onerror = () => {
+        uni.hideLoading()
+        uni.showToast({ title: '裁剪失败', icon: 'none' })
+        uni.navigateBack()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.crop-page {
+  width: 100%;
+  height: 100vh;
+  background: #1a1a1a;
+  display: flex;
+  flex-direction: column;
+}
+
+.crop-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20rpx 30rpx;
+  background: #333;
+}
+
+.header-btn {
+  font-size: 32rpx;
+  padding: 10rpx 20rpx;
+
+  &.cancel { color: #999; }
+  &.confirm { color: #4CAF50; font-weight: bold; }
+}
+
+.header-title {
+  font-size: 34rpx;
+  color: #fff;
+  font-weight: bold;
+}
+
+.crop-container {
+  flex: 1;
+  position: relative;
+  overflow: hidden;
+}
+
+.original-image {
+  width: 100%;
+  height: 100%;
+}
+
+.crop-mask {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.7);
+}
+
+.crop-box {
+  position: absolute;
+  border: 2px solid #fff;
+  box-sizing: border-box;
+  z-index: 10;
+  cursor: move;
+  touch-action: none;
+  user-select: none;
+
+  .grid-lines {
+    width: 100%;
+    height: 100%;
+    position: relative;
+
+    .grid-line {
+      position: absolute;
+      background: rgba(255, 255, 255, 0.5);
+
+      &.horizontal {
+        width: 100%; height: 1px; top: 33.33%;
+        &:nth-child(2) { top: 66.66%; }
+      }
+
+      &.vertical {
+        width: 1px; height: 100%; left: 33.33%;
+        &:nth-child(4) { left: 66.66%; }
+      }
+    }
+  }
+
+  .corner-tl, .corner-tr, .corner-bl, .corner-br {
+    position: absolute;
+    width: 30rpx;
+    height: 30rpx;
+    border: 3px solid #fff;
+    background: #333;
+    cursor: nwse-resize;
+  }
+
+  .corner-tl { top: -15rpx; left: -15rpx; border-right: none; border-bottom: none; }
+  .corner-tr { top: -15rpx; right: -15rpx; border-left: none; border-bottom: none; cursor: nesw-resize; }
+  .corner-bl { bottom: -15rpx; left: -15rpx; border-right: none; border-top: none; cursor: nesw-resize; }
+  .corner-br { bottom: -15rpx; right: -15rpx; border-left: none; border-top: none; }
+}
+</style>

+ 135 - 33
src/pages/join/idCardEdit.vue

@@ -1,36 +1,98 @@
 <template>
-    <view>
-        <view class="images">
-            <view class="id-upload-row">
-                <Upload name="idCardFront" width="187rpx" height="220rpx" :maxCount="1"
-                    @fileList="onUpload($event, 'idCardFront')" :fileList="idCardFront">
-                    <view class="upload-block" slot="content">
-                        <view class="icon-bg"><u-icon name="camera-fill" color="#fff" size="20"></u-icon></view>
-                        <text class="up-text">身份证人像面</text>
+    <view class="idCardEdit">
+        <view class="content">
+            <view class="id-upload-row" style="margin-bottom: 32rpx;">
+                <view style="width: 334rpx;height: 264rpx;position: relative;">
+                    <Upload name="idCardFront" width="334rpx" height="210rpx" :maxCount="1"
+                        @fileList="onUpload($event, 'idCardFront')" :fileList="idCardFront">
+                        <view class="upload-block" slot="content">
+
+                            <view class="icon-bg">
+                                <image src="/static/login/cameraIcon.png" mode="widthFix" width="54.64rpx"
+                                    height="52rpx">
+                                </image>
+                                <!-- <u-icon name="camera-fill" color="#fff" size="20"></u-icon> -->
+                            </view>
+
+                        </view>
+
+                    </Upload>
+                    <view class="options">
+                        <view style="display: flex;align-items: center;">
+                            <image src="/static/login/deleteIcon.png" style="width: 24rpx; height: 24rpx;"
+                                mode="widthFix">
+                            </image>
+
+                            <view class="options-text">删除</view>
+                        </view>
+
+                        <view style="height: 32rpx;border: 0.5rpx solid #FFFFFF;"></view>
+                        <view style="display: flex;align-items: center;">
+                            <image src="/static/login/lookGigIcon.png" style="width: 24rpx; height: 24rpx;"
+                                mode="widthFix">
+                            </image>
+                            <view class="options-text">查看</view>
+                        </view>
+
+
+
                     </view>
-                </Upload>
+                    <view class="up-text">身份证人像面</view>
+                </view>
+
+                <view style="width: 334rpx;height: 264rpx;">
+                    <Upload name="idCardBack" width="187rpx" height="220rpx" :maxCount="1"
+                        @fileList="onUpload($event, 'idCardBack')" :fileList="idCardBack">
+                        <view class="upload-block" slot="content">
+                            <view class="icon-bg">
+                                <image src="/static/login/cameraIcon.png" mode="widthFix" width="54.64rpx"
+                                    height="52rpx">
+                                </image>
+                                <!-- <u-icon name="camera-fill" color="#fff" size="20"></u-icon> -->
+                            </view>
+                        </view>
+                    </Upload>
+
+                    <view class="up-text">身份证国徽面</view>
+                </view>
+
+
+
+            </view>
+
+            <view style="width: 334rpx;height: 284rpx;">
                 <Upload name="idCardBack" width="187rpx" height="220rpx" :maxCount="1"
-                    @fileList="onUpload($event, 'idCardBack')" :fileList="idCardBack">
-                    <view class="upload-block" slot="content">
-                        <view class="icon-bg"><u-icon name="camera-fill" color="#fff" size="20"></u-icon></view>
-                        <text class="up-text">身份证国徽面</text>
+                    @fileList="onUpload($event, 'idCardHand')" :fileList="idCardHand">
+                    <view class="upload-block  full-width" slot="content">
+                        <view class="icon-bg">
+                            <image src="/static/login/cameraIcon.png" mode="widthFix" width="54.64rpx" height="52rpx">
+                            </image>
+                            <!-- <u-icon name="camera-fill" color="#fff" size="20"></u-icon> -->
+                        </view>
                     </view>
                 </Upload>
+
+                <view class="up-text">手持身份证照片</view>
             </view>
 
-            <Upload name="idCardHand" width="187rpx" height="220rpx" :maxCount="1"
+            <!-- <Upload name="idCardHand" width="187rpx" height="220rpx" :maxCount="1"
                 @fileList="onUpload($event, 'idCardHand')" :fileList="idCardHand">
                 <view class="upload-block full-width" slot="content">
                     <view class="icon-bg"><u-icon name="camera-fill" color="#fff" size="20"></u-icon></view>
                     <text class="up-text">手持身份证照片</text>
                 </view>
-            </Upload>
+            </Upload> -->
 
             <view class="footer-bar">
-                <u-button shape="circle" :customStyle="{
+                <u-button :customStyle="{
+                    padding: '24rpx 48rpx',
                     color: '#fff',
-                    background: 'var(--theme-color-gradient)'
-                }" @click="onSubmit">确认修改</u-button>
+                    background: 'var(--theme-color-gradient)',
+                    width: '654rpx',
+                    height: '88rpx',
+                    background: '#333335',
+                    borderRadius: '60rpx 60rpx 60rpx 60rpx',
+                }" @click="onSubmit">保存</u-button>
             </view>
         </view>
     </view>
@@ -56,9 +118,9 @@ export default {
         if (query.fieldName) this.fieldName = query.fieldName
         if (query.fieldVal) {
             let fieldVal = JSON.parse(query.fieldVal)
-            this.idCardFront=fieldVal[0]?[fieldVal[0]]:[]
-            this.idCardBack=fieldVal[1]?[fieldVal[1]]:[]
-            this.idCardHand=fieldVal[2]?[fieldVal[2]]:[]
+            this.idCardFront = fieldVal[0] ? [fieldVal[0]] : []
+            this.idCardBack = fieldVal[1] ? [fieldVal[1]] : []
+            this.idCardHand = fieldVal[2] ? [fieldVal[2]] : []
         }
 
         // console.log(this.fileList, 'query')
@@ -87,7 +149,7 @@ export default {
             // 上一页实例
             const prevPage = pages[pages.length - 2]
             // 直接修改上一页data里的字段
-            prevPage.$data.baseInfo[this.fieldName] = [...this.idCardFront,...this.idCardBack,...this.idCardHand]
+            prevPage.$data.baseInfo[this.fieldName] = [...this.idCardFront, ...this.idCardBack, ...this.idCardHand]
             uni.navigateBack()
         }
 
@@ -96,17 +158,61 @@ export default {
 </script>
 
 <style scoped lang="scss">
+.idCardEdit {
+    height: 100vh;
+    background-color: #F7F8FA;
+
+    .content {
+        width: 100%;
+        background-color: #fff;
+        padding: 32rpx;
+
+        .up-text {
+            margin-top: 16rpx;
+            font-weight: 400;
+            font-size: 28rpx;
+            color: #86909C;
+            line-height: 28rpx;
+            text-align: center;
+        }
+
+        .options {
+            padding: 0 44rpx;
+            position: absolute;
+            top: 158rpx;
+            width: 334rpx;
+            height: 52rpx;
+            background: rgba(0, 0, 0, 0.1);
+            border-radius: 0rpx 0rpx 12rpx 12rpx;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+
+            .options-text{
+                margin-left: 4rpx;
+                font-weight: 400;
+                font-size: 24rpx;
+                color: #FFFFFF;
+            }
+        }
+
+    }
+
+}
+
+::v-deep .u-upload__success {
+    display: none;
+}
+
 /* 身份证上传样式 */
 .id-upload-row {
-    gap: 10rpx;
     display: flex;
     justify-content: space-between;
-    margin-bottom: 20rpx;
 }
 
 .upload-block {
     // width: 100%;
-    height: 220rpx;
+    height: 210rpx;
     background-color: #f9f9f9;
     border-radius: 12rpx;
     border: 1rpx dashed #eee;
@@ -124,18 +230,14 @@ export default {
 
     .icon-bg {
         width: 60rpx;
-        height: 60rpx;
-        background-color: #00cba3;
-        border-radius: 50%;
+        height: 54rpx;
+
         display: flex;
         align-items: center;
         justify-content: center;
-        margin-bottom: 16rpx;
     }
 
-    .up-text {
-        font-size: 24rpx;
-        color: #666;
-    }
+
+
 }
 </style>

+ 1 - 1
src/pages/join/introduceYourselfEdit.vue

@@ -13,7 +13,7 @@
                 height: '88rpx',
                 background: '#333335',
                 borderRadius: '60rpx 60rpx 60rpx 60rpx',
-            }" @click="onSubmit">确认修改</u-button>
+            }" @click="onSubmit">保存</u-button>
         </view>
     </view>
 </template>

+ 50 - 7
src/pages/join/lifePhotosEdit.vue

@@ -2,8 +2,19 @@
     <view class="lifePhotosEdit">
         <view class="u-cell-group">
             <!-- <Upload :maxCount="1" @fileList="onUpload($event, 'cImgList')" /> -->
-            <Upload :accept="title == '宣传视频' ? 'file' : 'image'" :maxSize="title == '宣传视频' ? 51200 : 10240"
-                :maxCount="maxCount" :width="80" :height="80" @fileList="onUpload" :fileList="fileList" />
+            <Upload :accept="title == '宣传视频' ? 'video' : 'image'" :maxCount="maxCount" :width="78" :height="78"
+                @fileList="onUpload" :fileList="fileList">
+                <view class="upload-block" slot="content">
+
+                    <view class="icon-bg">
+                        <image src="/static/login/cameraIcon.png" mode="widthFix" style="width: 52rpx;height: 52rpx;" >
+                        </image>
+                        <view style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;margin-top: -13rpx;">上传</view>
+                        
+                    </view>
+
+                </view>
+            </Upload>
 
             <view class="tagText" v-if="title == '生活照'">简单介绍自己的生活照,可以说说自己的基本信息,工作场景,等等;
                 或者上传自己清晰露脸半身照/全身照/工作照。最多上传{{ maxCount }}张</view>
@@ -14,10 +25,15 @@
 
 
             <view class="footer-bar">
-                <u-button shape="circle" :customStyle="{
+                <u-button :customStyle="{
+                    padding: '24rpx 48rpx',
                     color: '#fff',
-                    background: 'var(--theme-color-gradient)'
-                }" @click="onSubmit">确认修改</u-button>
+                    background: 'var(--theme-color-gradient)',
+                    width: '654rpx',
+                    height: '88rpx',
+                    background: '#333335',
+                    borderRadius: '60rpx 60rpx 60rpx 60rpx',
+                }" @click="onSubmit">保存</u-button>
             </view>
         </view>
     </view>
@@ -103,11 +119,38 @@ export default {
         color: #86909C;
     }
 
+
+
     ::v-deep .u-cell-group {
         padding: 32rpx;
         background-color: #fff;
-        .u-upload__button{
-            margin:0!important;
+        .upload-block{
+            width: 160rpx;
+            height: 160rpx;
+            background-color: #F7F8FA ;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            border-radius: 12rpx;
+        }
+
+        .u-upload__wrap {
+            display: flex;
+            flex-wrap: wrap;
+            justify-content: flex-start;
+            gap: 14rpx;
+        }
+
+        .u-upload__button {
+            margin: 0 !important;
+        }
+
+        .u-upload__wrap__preview {
+            margin: 0 !important;
+        }
+
+        .u-upload__success {
+            display: none;
         }
     }
 }

+ 98 - 46
src/pages/join/staff.vue

@@ -4,10 +4,12 @@
 			<image src="/static/login/banner.png" mode=""></image>
 		</view>
 		<view class="top">
-			<view v-if="ShopInfo" class="checkBox" :style="{
-				borderColor: ShopInfo.auditStatus == 1 ? '#F76560' : '#FF7D00',
-				color: ShopInfo.auditStatus === 1 ? '#F53F3F' : '#FF7D00', background: status === 1 ? '#FFF5F5' : '#FFF8EC'
-			}">
+			<view v-if="ShopInfo.merchant.auditStatus == 1 || ShopInfo.merchant.auditStatus == 2" class="checkBox"
+				:style="{
+					borderColor: ShopInfo.merchant.auditStatus == 1 ? '#F76560' : '#FF7D00',
+					color: ShopInfo.merchant.auditStatus === 1 ? '#F53F3F' : '#FF7D00',
+					background: ShopInfo.merchant.auditStatus === 1 ? '#FFF5F5' : '#FFF8EC'
+				}">
 				<view class="checkStatus">审核中</view>
 				<view class="text">入驻审核中,审核结果将会在9个工作日通知您</view>
 			</view>
@@ -20,7 +22,8 @@
 			</view>
 			<view class="content">
 				<view class="input-box">
-					<u-input v-model="form.teName" border="none" placeholder="输入真实姓名" class="input-item"
+					<u-input :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false" v-model="form.teName"
+						border="none" placeholder="输入真实姓名" class="input-item"
 						placeholder-style="font-weight: 400;font-size: 30rpx;color: #C9CDD4;text-align: right;">
 						<template slot="prefix">
 							<view class="label">
@@ -31,7 +34,7 @@
 				</view>
 				<view class="input-box service">
 					<view class="label">性别</view>
-					<u-radio-group v-model="form.teSex">
+					<u-radio-group v-model="form.teSex" :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false">
 						<u-radio activeColor="#333335" v-for="(item, index) in sex" :key="index" :name="item.value"
 							:label="item.label" :customStyle="{ margin: '0 12rpx' }" />
 					</u-radio-group>
@@ -39,7 +42,8 @@
 
 
 				<view class="input-box">
-					<u-input v-model="form.tePhone" border="none" maxlength='11' placeholder="请输入手机号" class="input-item"
+					<u-input :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false" v-model="form.tePhone"
+						border="none" maxlength='11' placeholder="请输入手机号" class="input-item"
 						placeholder-style="font-weight: 400;font-size: 30rpx;color: #C9CDD4;text-align: right;">
 						<template slot="prefix">
 							<view class="label">
@@ -48,8 +52,9 @@
 						</template>
 					</u-input>
 				</view>
-				<view class="input-box">
-					<u-input v-model="form.phoneMsg" type="number" border="none" maxlength="6" placeholder="输入短信验证码"
+				<view class="input-box" v-if="this.ShopInfo.merchant.auditStatus != 1">
+					<u-input :disabled="ShopInfo.merchant.auditStatus == -1 ? true : false" v-model="form.phoneMsg"
+						type="number" border="none" maxlength="6" placeholder="输入短信验证码"
 						placeholder-style="font-weight: 400;font-size: 30rpx;color: #C9CDD4;text-align: right;margin-right: 42rpx;"
 						class="input-item code-input">
 						<template slot="prefix">
@@ -71,14 +76,14 @@
 
 				<view class="input-box">
 					<view class="label" style="width: 50%;">合作意向城市</view>
-					<view class="inp select" @click="show = true">
-						<view class="text" :style="{ color: form.teAddress ? '#4E5969Z' : '#C9CDD4' }">{{ form.teAddress
-							|| '选择城市' }}</view>
+					<view class="inp select" @click="ShopInfo.merchant.auditStatus == 1 ? show = false : show = true">
+						<view class="text" :style="{ color: form.provinceName ? '#4E5969' : '#C9CDD4' }">{{
+							form.provinceName || '选择城市' }}</view>
 						<img src="/static/login/arrowIcon.png" alt="" />
 					</view>
 
 					<u-popup :show="show" mode="bottom" border-radius="16rpx 16rpx 0 0"
-						:style="{ height: '600rpx', zIndex: 9999,}">
+						:style="{ height: '600rpx', zIndex: 9999, }">
 
 						<u-picker :show="show" confirmColor="#fff" title="合作意向城市" :columns="[cityList]" keyName="label"
 							:style="{ zIndex: 0, }" @confirm="onSelect" @cancel="cancel"></u-picker>
@@ -86,51 +91,56 @@
 				</view>
 				<view class="input-box service">
 					<view class="label">开通服务</view>
-					<u-radio-group v-model="form.openService">
+					<u-radio-group v-model="form.openService" :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false">
 						<u-radio activeColor="#333335" v-for="(item, index) in serveArr" :key="index"
 							:name="item.dictValue" :label="item.dictLabel" :customStyle="{ fontSize: '20rpx' }" />
 					</u-radio-group>
 				</view>
-
-				<!-- <view class="page-section">
-					<view class="name">合作意向城市</view>
-					<view class="inp select" @click="show = true">
-						<text>{{ form.teAddress }}</text>
-						<img src="/static/identify/down.png" alt="" />
-					</view>
-					<u-picker :show="show" :columns="[cityList]" keyName="label" @cancel="show = false"
-						@confirm="onSelect"></u-picker>
-				</view> -->
-
-				<!-- <view class="page-section">
-					<view class="name">您所在的位置:</view>
-					<view class="weui-cells weui-cells_after-title location" @click="getAddress">
-						<text class="point" v-if="!form.address">请选择</text>
-						<text class="point active" v-else>{{form.address}}{{form.name}}</text>
-					</view>
-				</view> -->
-				<view class="updata" style="border:0;">
-					<view class="name">工作形象照</view>
+				<!-- :width="80" :height="80"  -->
+				<view class="updata">
+					<view class="name">形象照</view>
 
 					<view class="images">
-						<Upload :maxImageSize=2097152 :maxCount="2" :width="80" :height="80" :fileList="avatarList"
-							@fileList="onUpload($event)" />
+						<Upload :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false" :maxCount="2"
+							:fileList="avatarList" @fileList="onUpload($event)"
+							 />
 					</view>
 					<view class="title">
 						请上传本人2张近期照片,图片大小不超过2M(建议清晰正脸照)
 					</view>
 				</view>
+				<!-- <view class="updata" style="border:0;">
+					<view class="name">工作形象照</view>
+					<view class="title">
+						请上传本人近期照片,图片大小不超过10M (建议清晰正脸照)
+					</view>
+					<view class="images">
+						<Upload
+							:maxCount="2"
+							@fileList="onUpload1($event, 'cImgList')"
+						/>
+					</view>
+				</view> -->
 			</view>
 
 
 		</view>
-		<view class="submits">
+		<view class="submits" v-if="this.ShopInfo.merchant.auditStatus != 1">
 
 			<view class="btn" @click="submit">
 				提交
 			</view>
 			<text>平台不会通过任何渠道泄漏你的个人信息,请放心输入</text>
 		</view>
+		<view class="keFu" @click="callKeFu">
+			<view class="keFuContent">
+				<view style="display: flex;justify-content: center;align-items: center;margin-top: 5rpx;">
+					<img src="/static/login/serviceIcon.png" style="width: 44rpx;height: 44rpx;" />
+				</view>
+				<view style="font-weight: 400;font-size: 20rpx;color: #1D2129;text-align: center;margin-top: -10rpx;">客服
+				</view>
+			</view>
+		</view>
 
 
 		<!-- 图形验证码弹窗 -->
@@ -185,6 +195,7 @@ export default {
 	},
 	data() {
 		return {
+			//auditStatus 审核状态:-1-申请入住,0-待入驻,1-待审核,2-审核通过,3-审核驳回"
 			status: 1,
 			imgCode: '',        // 用户填写的图形验证码
 			captchaImg: '',     // 图形验证码图片地址
@@ -222,7 +233,12 @@ export default {
 			avatarList: [],
 			CodeSendNum: 0,
 			form: {
-				teAreaCode: '',
+				provinceCode: '',
+				provinceName: '',
+				cityCode: '',
+				cityName: '',
+				districtCode: '',
+				districtName: '',
 				cOpenid: uni.getStorageSync('wx_copenid'),
 				teName: '',
 				//cNickName: '',
@@ -239,20 +255,22 @@ export default {
 				//name: '0',
 				//cOpenId: '',
 				//cBhList: '',
-				teAddress: ''
+				//teAddress: ''
 			},
 			token: '',
 			uuid: '',
-			ShopInfo: {}
+			ShopInfo: {merchant:{auditStatus: 0}}
 		}
 	},
 	onLoad(options) {
+		console.log(options, '66666')
 		if (options.ShopInfo) this.ShopInfo = JSON.parse(options.ShopInfo)
+		console.log(this.ShopInfo, 'ShopInfo')
 		this.isLogin = !!uni.getStorageSync('access-token');
 	},
 	onShow() {
-		//this.getServiceCategoryList()
-		//this.getCity()
+		this.getServiceCategoryList()
+		this.getCity()
 
 		//this.getinfo()
 		// let city = uni.getStorageSync('selectCity')
@@ -261,6 +279,10 @@ export default {
 		// this.form.city = uni.getStorageSync('selectCity')
 	},
 	methods: {
+		// upload事件
+		onUpload1(e, t) {
+			this.form[t] = e.map(item => item.url).join()
+		},
 		//查询商户信息 auditStatus 审核状态:-1-申请入住,0-待入驻,1-待审核,2-审核通过,3-审核驳回"
 		getTechnicianFun() {
 			let openid = uni.getStorageSync('wx_copenid')
@@ -339,6 +361,7 @@ export default {
 		},
 		//获取验证码
 		getCode() {
+
 			if (!/^1[3456789]\d{9}$/.test(this.form.tePhone)) {
 				uni.showToast({
 					title: '请输入正确的手机号',
@@ -391,6 +414,7 @@ export default {
 		onUpload(e) {
 			this.avatarList = e;
 		},
+		
 		//提交
 		submit() {
 			console.log(this.avatarList, 'avatarList')
@@ -430,7 +454,7 @@ export default {
 				});
 				return
 			}
-			if (this.form.teAddress == '') {
+			if (this.form.provinceName == '') {
 				uni.showToast({
 					title: '请选择城市',
 					icon: 'none'
@@ -478,7 +502,8 @@ export default {
 		//获取城市
 		getCity() {
 			getCityList().then(res => {
-				this.cityList = res.data.data.map(({
+				console.log(res)
+				this.cityList = res.data.data.records.map(({
 					deptId,
 					deptName
 				}) => ({
@@ -497,8 +522,8 @@ export default {
 		onSelect(e) {
 			console.log(e)
 			if (!e.value[0]) return
-			this.form.teAddress = e.value[0].label
-			this.form.teAreaCode = e.value[0].value
+			this.form.provinceName = e.value[0].label
+			this.form.provinceCode = e.value[0].value
 			//this.form.deptId = e.value[0].value
 			this.show = false
 		},
@@ -532,6 +557,10 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+::v-deep .u-upload__success {
+	display: none;
+}
+
 ::v-deep .u-picker {
 	bottom: 136rpx;
 	background-color: #ffffff;
@@ -923,4 +952,27 @@ export default {
 		}
 	}
 }
+
+.keFu {
+	position: fixed;
+	right: 0;
+	bottom: 290rpx;
+	width: 100rpx;
+	height: 100rpx;
+	background: linear-gradient(263deg, rgba(69, 255, 215, 0.4) 0%, rgba(127, 255, 189, 0.4) 100%);
+	border-radius: 50%;
+	//opacity: 0.4;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+
+	.keFuContent {
+		width: 76rpx;
+		height: 76rpx;
+		background: linear-gradient(263deg, rgba(69, 255, 215, 0.5) 0%, rgba(127, 255, 189, 0.5) 100%);
+		border-radius: 50%;
+		//opacity: 0.5;
+
+	}
+}
 </style>

BIN
src/static/login/deleteIcon.png


BIN
src/static/login/lookGigIcon.png


BIN
src/static/login/luYinIcon.png