Kaynağa Gözat

修改部分内容

yangg 1 ay önce
ebeveyn
işleme
a0c6bcef1c

+ 554 - 153
pages/Personal/Personal.vue

@@ -197,11 +197,23 @@
 					<view class="form-row">
 						<view class="form-item">
 							<text class="label">称谓</text>
-							<input type="text" v-model="familyMemberForm.relation" placeholder="如:父亲、母亲、配偶等" />
+							<input 
+								type="text" 
+								v-model="familyMemberForm.relation" 
+								placeholder="如:父亲、母亲、配偶等" 
+								:class="{'input-error': familyMemberErrors.relation}"
+							/>
+							<text v-if="familyMemberErrors.relation" class="error-message">{{familyMemberErrors.relation}}</text>
 						</view>
 						<view class="form-item">
 							<text class="label">姓名</text>
-							<input type="text" v-model="familyMemberForm.name" placeholder="请输入姓名" />
+							<input 
+								type="text" 
+								v-model="familyMemberForm.name" 
+								placeholder="请输入姓名" 
+								:class="{'input-error': familyMemberErrors.name}"
+							/>
+							<text v-if="familyMemberErrors.name" class="error-message">{{familyMemberErrors.name}}</text>
 						</view>
 					</view>
 					
@@ -219,7 +231,13 @@
 					<view class="form-row">
 						<view class="form-item">
 							<text class="label">联系电话</text>
-							<input type="number" v-model="familyMemberForm.phone" placeholder="请输入联系电话" />
+							<input 
+								type="number" 
+								v-model="familyMemberForm.phone" 
+								placeholder="请输入联系电话" 
+								:class="{'input-error': familyMemberErrors.phone}"
+							/>
+							<text v-if="familyMemberErrors.phone" class="error-message">{{familyMemberErrors.phone}}</text>
 						</view>
 					</view>
 					
@@ -287,34 +305,64 @@
 						<view class="form-item">
 							<text class="label">起止时间</text>
 							<view class="date-range">
-								<picker mode="date" :value="educationForm.startTime" @change="bindStartTimeChange">
+								<picker 
+									mode="date" 
+									:value="educationForm.startTime" 
+									@change="bindStartTimeChange"
+									:class="{'input-error': educationErrors.startTime}"
+								>
 									<view class="picker-text">{{ educationForm.startTime || '开始时间' }}</view>
 								</picker>
 								<text class="date-separator">至</text>
-								<picker mode="date" :value="educationForm.endTime" @change="bindEndTimeChange">
+								<picker 
+									mode="date" 
+									:value="educationForm.endTime" 
+									@change="bindEndTimeChange"
+									:class="{'input-error': educationErrors.endTime}"
+								>
 									<view class="picker-text">{{ educationForm.endTime || '结束时间' }}</view>
 								</picker>
 							</view>
+							<text v-if="educationErrors.startTime" class="error-message">{{educationErrors.startTime}}</text>
+							<text v-if="educationErrors.endTime" class="error-message">{{educationErrors.endTime}}</text>
 						</view>
 					</view>
 					
 					<view class="form-row">
 						<view class="form-item">
 							<text class="label">学校名称</text>
-							<input type="text" v-model="educationForm.schoolName" placeholder="请输入学校名称" />
+							<input 
+								type="text" 
+								v-model="educationForm.schoolName" 
+								placeholder="请输入学校名称" 
+								:class="{'input-error': educationErrors.schoolName}"
+							/>
+							<text v-if="educationErrors.schoolName" class="error-message">{{educationErrors.schoolName}}</text>
 						</view>
 						<view class="form-item">
 							<text class="label">专业</text>
-							<input type="text" v-model="educationForm.major" placeholder="请输入专业" />
+							<input 
+								type="text" 
+								v-model="educationForm.major" 
+								placeholder="请输入专业" 
+								:class="{'input-error': educationErrors.major}"
+							/>
+							<text v-if="educationErrors.major" class="error-message">{{educationErrors.major}}</text>
 						</view>
 					</view>
 					
 					<view class="form-row">
 						<view class="form-item">
 							<text class="label">学历</text>
-							<picker @change="bindDegreeChange" :value="degreeIndex" :range="degreeOptions">
+							<picker 
+								@change="bindDegreeChange" 
+								:value="degreeIndex" 
+								:range="degreeOptions"
+								:class="{'input-error': educationErrors.degree}"
+							>
 								<view class="picker-text">{{ degreeOptions[degreeIndex] || '请选择学历' }}</view>
 							</picker>
+							<text v-if="educationErrors.degree" class="error-message">{{educationErrors.degree}}</text>
 						</view>
 					</view>
 					
@@ -333,11 +381,23 @@
 			<view v-if="currentStep === 6" class="form-container">
 				<view class="section-title">专业技能</view>
 				<view class="skills-container">
-					<textarea v-model="formData.skills" placeholder="请描述您的专业技能" class="skills-textarea"></textarea>
+					<textarea 
+						v-model="formData.skills" 
+						placeholder="请描述您的专业技能" 
+						class="skills-textarea"
+						:class="{'input-error': formErrors.skills}"
+					></textarea>
+					<text v-if="formErrors.skills" class="error-message">{{formErrors.skills}}</text>
 				</view>
 				<view class="section-title">受过的培训</view>
 				<view class="training-container">
-					<textarea v-model="formData.training" placeholder="请描述您接受过的培训经历" class="training-textarea"></textarea>
+					<textarea 
+						v-model="formData.training" 
+						placeholder="请描述您接受过的培训经历" 
+						class="training-textarea"
+						:class="{'input-error': formErrors.training}"
+					></textarea>
+					<text v-if="formErrors.training" class="error-message">{{formErrors.training}}</text>
 				</view>
 			</view>
 			
@@ -403,43 +463,80 @@
 						<view class="form-item">
 							<text class="label">起止时间</text>
 							<view class="date-range">
-								<picker mode="date" :value="workForm.startTime" @change="bindWorkStartTimeChange">
+								<picker 
+									mode="date" 
+									:value="workForm.startTime" 
+									@change="bindWorkStartTimeChange"
+									:class="{'input-error': workErrors.startTime}"
+								>
 									<view class="picker-text">{{ workForm.startTime || '开始时间' }}</view>
 								</picker>
 								<text class="date-separator">至</text>
-								<picker mode="date" :value="workForm.endTime" @change="bindWorkEndTimeChange">
+								<picker 
+									mode="date" 
+									:value="workForm.endTime" 
+									@change="bindWorkEndTimeChange"
+									:class="{'input-error': workErrors.endTime}"
+								>
 									<view class="picker-text">{{ workForm.endTime || '结束时间' }}</view>
 								</picker>
 							</view>
+							<text v-if="workErrors.startTime" class="error-message">{{workErrors.startTime}}</text>
+							<text v-if="workErrors.endTime" class="error-message">{{workErrors.endTime}}</text>
 						</view>
 					</view>
 					
 					<view class="form-row">
 						<view class="form-item">
 							<text class="label">单位名称</text>
-							<input type="text" v-model="workForm.companyName" placeholder="请输入单位名称" />
+							<input 
+								type="text" 
+								v-model="workForm.companyName" 
+								placeholder="请输入单位名称" 
+								:class="{'input-error': workErrors.companyName}"
+							/>
+							<text v-if="workErrors.companyName" class="error-message">{{workErrors.companyName}}</text>
 						</view>
 						<view class="form-item">
 							<text class="label">单位人数</text>
-							<input type="number" v-model="workForm.employeeCount" placeholder="请输入单位人数" />
+							<input 
+								type="number" 
+								v-model="workForm.employeeCount" 
+								placeholder="请输入单位人数"
+								:class="{'input-error': workErrors.employeeCount}"
+							/>
+							<text v-if="workErrors.employeeCount" class="error-message">{{workErrors.employeeCount}}</text>
 						</view>
 					</view>
 					
 					<view class="form-row">
 						<view class="form-item">
 							<text class="label">任职部门</text>
-							<input type="text" v-model="workForm.department" placeholder="请输入任职部门" />
+							<input 
+								type="text" 
+								v-model="workForm.department" 
+								placeholder="请输入任职部门"
+								:class="{'input-error': workErrors.department}"
+							/>
+							<text v-if="workErrors.department" class="error-message">{{workErrors.department}}</text>
 						</view>
 						<view class="form-item">
 							<text class="label">担任职务</text>
-							<input type="text" v-model="workForm.position" placeholder="请输入担任职务" />
+							<input 
+								type="text" 
+								v-model="workForm.position" 
+								placeholder="请输入担任职务"
+								:class="{'input-error': workErrors.position}"
+							/>
+							<text v-if="workErrors.position" class="error-message">{{workErrors.position}}</text>
 						</view>
 					</view>
 					
 					<view class="form-row">
 						<view class="form-item">
 							<text class="label">月总收入</text>
-							<input type="digit" v-model="workForm.monthlySalary" placeholder="请输入月总收入" />
+							<input type="number" v-model="workForm.monthlySalary" placeholder="请输入月总收入" />
+							<text v-if="workErrors.monthlySalary" class="error-message">{{workErrors.monthlySalary}}</text>
 						</view>
 					</view>
 					
@@ -447,10 +544,12 @@
 						<view class="form-item">
 							<text class="label">直接领导</text>
 							<input type="text" v-model="workForm.supervisor" placeholder="请输入直接领导姓名" />
+							<text v-if="workErrors.supervisor" class="error-message">{{workErrors.supervisor}}</text>
 						</view>
 						<view class="form-item">
 							<text class="label">领导电话</text>
 							<input type="number" v-model="workForm.supervisorPhone" placeholder="请输入领导电话" />
+							<text v-if="workErrors.supervisorPhone" class="error-message">{{workErrors.supervisorPhone}}</text>
 						</view>
 					</view>
 					
@@ -589,10 +688,85 @@ import { apiBaseUrl } from '@/common/config.js';
 				formErrors: {
 					name: '',
 					idCard: '',
-					phone: ''
+					phone: '',
+					gender: '',
+					ethnic: '',
+					currentAddress: '',
+					height: '',
+					weight: '',
+					expectedSalary: '',
+					skills: '',
+					training: ''
 				},
 				// Add loading state
 				isLoading: true,
+				familyMemberErrors: {
+					relation: '',
+					name: '',
+					phone: '',
+					workplaceOrAddress: '',
+					position: ''
+				},
+				workErrors: {
+					startTime: '',
+					endTime: '',
+					companyName: '',
+					department: '',
+					position: '',
+					employeeCount: '',
+					monthlySalary: '',
+					supervisor: '',
+					supervisorPhone: ''
+				},
+				// 在 data 中添加教育经历的错误提示对象
+				educationErrors: {
+					startTime: '',
+					endTime: '',
+					schoolName: '',
+					major: '',
+					degree: ''
+				},
+				// 添加统一的验证规则
+				validationRules: {
+					name: {
+						required: true,
+						message: '请输入姓名'
+					},
+					phone: {
+						required: true,
+						pattern: /^1[3-9]\d{9}$/,
+						message: '请输入正确的手机号码'
+					},
+					idCard: {
+						required: true,
+						pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
+						message: '请输入正确的身份证号码'
+					},
+					gender: {
+						required: true,
+						message: '请选择性别'
+					},
+					ethnic: {
+						required: true,
+						message: '请选择民族'
+					},
+					height: {
+						pattern: /^\d+(\.\d{1,2})?$/,
+						message: '请输入正确的身高(cm)'
+					},
+					weight: {
+						pattern: /^\d+(\.\d{1,2})?$/,
+						message: '请输入正确的体重(kg)'
+					},
+					expectedSalary: {
+						pattern: /^\d+(\.\d{1,2})?$/,
+						message: '请输入正确的期望薪资'
+					},
+					currentAddress: {
+						required: true,
+						message: '请输入现居住地址'
+					}
+				}
 			}
 		},
 		onLoad() {
@@ -661,55 +835,82 @@ import { apiBaseUrl } from '@/common/config.js';
 				this.formData.birthDate = e.detail.value;
 			},
 			saveFamilyMember() {
+				// 重置错误信息
+				this.resetFamilyMemberErrors();
+				
+				// 验证必填字段
+				let isValid = true;
+				
 				if (!this.familyMemberForm.relation) {
-					uni.showToast({
-						title: '请输入称谓',
-						icon: 'none'
-					});
-					return;
+					this.familyMemberErrors.relation = '请输入称谓';
+					isValid = false;
 				}
+				
 				if (!this.familyMemberForm.name) {
-					uni.showToast({
-						title: '请输入姓名',
-						icon: 'none'
-					});
-					return;
+					this.familyMemberErrors.name = '请输入姓名';
+					isValid = false;
+				}
+				
+				if (!this.familyMemberForm.workplaceOrAddress) {
+					this.familyMemberErrors.workplaceOrAddress = '请输入工作单位/家庭地址';
+					isValid = false;
 				}
+				
+				if (!this.familyMemberForm.position) {
+					this.familyMemberErrors.position = '请输入职务';
+					isValid = false;
+				}
+				
 				if (!this.familyMemberForm.phone) {
+					this.familyMemberErrors.phone = '请输入联系电话';
+					isValid = false;
+				} else if (!/^1[3-9]\d{9}$/.test(this.familyMemberForm.phone)) {
+					this.familyMemberErrors.phone = '请输入正确的手机号';
+					isValid = false;
+				}
+				
+				if (!isValid) {
 					uni.showToast({
-						title: '请输入联系电话',
+						title: '请完善所有必填信息',
 						icon: 'none'
 					});
 					return;
 				}
 				
+				// 原有的保存逻辑
 				if (this.isEditing) {
-					// 如果取消了紧急联系人身份,且该成员原本是紧急联系人,清空紧急联系人信息
-					if (!this.familyMemberForm.isEmergencyContact && 
-						this.familyMembers[this.editingIndex].isEmergencyContact) {
-						this.formData.emergencyContact = '';
-						this.formData.emergencyPhone = '';
-					}
-					
 					this.familyMembers[this.editingIndex] = {...this.familyMemberForm};
-					
 					uni.showToast({
 						title: '修改成功',
 						icon: 'success'
 					});
-					
 					this.isEditing = false;
 					this.editingIndex = -1;
 				} else {
 					this.familyMembers.push({...this.familyMemberForm});
-					
 					uni.showToast({
 						title: '添加成功',
 						icon: 'success'
 					});
 				}
 				
-				// 重置表单
+				// 重置表单和错误信息
+				this.resetFamilyMemberForm();
+			},
+			
+			// 添加重置错误信息的方法
+			resetFamilyMemberErrors() {
+				this.familyMemberErrors = {
+					relation: '',
+					name: '',
+					phone: '',
+					workplaceOrAddress: '',
+					position: ''
+				};
+			},
+			
+			// 修改重置表单的方法
+			resetFamilyMemberForm() {
 				this.familyMemberForm = {
 					relation: '',
 					name: '',
@@ -718,6 +919,7 @@ import { apiBaseUrl } from '@/common/config.js';
 					phone: '',
 					isEmergencyContact: false
 				};
+				this.resetFamilyMemberErrors();
 			},
 			editFamilyMember(index) {
 				this.isEditing = true;
@@ -784,48 +986,52 @@ import { apiBaseUrl } from '@/common/config.js';
 				this.educationForm.degree = this.degreeOptions[this.degreeIndex];
 			},
 			saveEducation() {
+				// 重置错误信息
+				this.resetEducationErrors();
+				
+				// 验证必填字段
+				let isValid = true;
+				
 				if (!this.educationForm.startTime) {
-					uni.showToast({
-						title: '请选择开始时间',
-						icon: 'none'
-					});
-					return;
+					this.educationErrors.startTime = '请选择开始时间';
+					isValid = false;
 				}
+				
 				if (!this.educationForm.endTime) {
-					uni.showToast({
-						title: '请选择结束时间',
-						icon: 'none'
-					});
-					return;
+					this.educationErrors.endTime = '请选择结束时间';
+					isValid = false;
 				}
+				
 				if (!this.educationForm.schoolName) {
-					uni.showToast({
-						title: '请输入学校名称',
-						icon: 'none'
-					});
-					return;
+					this.educationErrors.schoolName = '请输入学校名称';
+					isValid = false;
 				}
+				
 				if (!this.educationForm.major) {
-					uni.showToast({
-						title: '请输入专业',
-						icon: 'none'
-					});
-					return;
+					this.educationErrors.major = '请输入专业';
+					isValid = false;
 				}
+				
 				if (!this.educationForm.degree) {
+					this.educationErrors.degree = '请选择学历';
+					isValid = false;
+				}
+				
+				if (!isValid) {
 					uni.showToast({
-						title: '请选择学历',
+						title: '请完善所有必填信息',
 						icon: 'none'
 					});
 					return;
 				}
 				
+				// 验证通过后的保存逻辑
 				if (this.isEditingEducation) {
 					this.educationList[this.editingEducationIndex] = {...this.educationForm};
 					
 					uni.showToast({
 						title: '修改成功',
-						icon: 'success'
+							icon: 'success'
 					});
 					
 					this.isEditingEducation = false;
@@ -839,6 +1045,7 @@ import { apiBaseUrl } from '@/common/config.js';
 					});
 				}
 				
+				// 重置表单
 				this.educationForm = {
 					startTime: '',
 					endTime: '',
@@ -893,42 +1100,73 @@ import { apiBaseUrl } from '@/common/config.js';
 				this.workForm.endTime = e.detail.value;
 			},
 			saveWork() {
+				// 重置所有工作经历相关的错误信息
+				this.workErrors = {
+					startTime: '',
+					endTime: '',
+					companyName: '',
+					department: '',
+					position: '',
+					employeeCount: '',
+					monthlySalary: '',
+					supervisor: '',
+					supervisorPhone: ''
+				};
+
+				// 验证必填字段
+				let isValid = true;
+
 				if (!this.workForm.startTime) {
-					uni.showToast({
-						title: '请选择开始时间',
-						icon: 'none'
-					});
-					return;
+					this.workErrors.startTime = '请选择开始时间';
+					isValid = false;
 				}
+
 				if (!this.workForm.endTime) {
-					uni.showToast({
-						title: '请选择结束时间',
-						icon: 'none'
-					});
-					return;
+					this.workErrors.endTime = '请选择结束时间';
+					isValid = false;
 				}
+
 				if (!this.workForm.companyName) {
-					uni.showToast({
-						title: '请输入单位名称',
-						icon: 'none'
-					});
-					return;
+					this.workErrors.companyName = '请输入单位名称';
+					isValid = false;
 				}
+
 				if (!this.workForm.department) {
-					uni.showToast({
-						title: '请输入任职部门',
-						icon: 'none'
-					});
-					return;
+					this.workErrors.department = '请输入任职部门';
+					isValid = false;
 				}
+
 				if (!this.workForm.position) {
-					uni.showToast({
-						title: '请输入担任职务',
-						icon: 'none'
-					});
+					this.workErrors.position = '请输入担任职务';
+					isValid = false;
+				}
+
+				if (!this.workForm.employeeCount) {
+					this.workErrors.employeeCount = '请输入单位人数';
+					isValid = false;
+				}
+
+				if (!this.workForm.monthlySalary) {
+					this.workErrors.monthlySalary = '请输入月薪';
+					isValid = false;
+				}
+
+				if (!this.workForm.supervisor) {	
+					this.workErrors.supervisor = '请输入直属上级';
+					isValid = false;
+				}
+
+				if (!this.workForm.supervisorPhone) {
+					this.workErrors.supervisorPhone = '请输入直属上级电话';
+					isValid = false;
+				}
+
+				// 如果验证不通过,直接返回
+				if (!isValid) {
 					return;
 				}
-				
+
+				// 验证通过后的保存逻辑
 				if (this.isEditingWork) {
 					this.workList[this.editingWorkIndex] = {...this.workForm};
 					
@@ -948,6 +1186,7 @@ import { apiBaseUrl } from '@/common/config.js';
 					});
 				}
 				
+				// 重置表单
 				this.workForm = {
 					startTime: '',
 					endTime: '',
@@ -999,11 +1238,31 @@ import { apiBaseUrl } from '@/common/config.js';
 				});
 			},
 			submitForm() {
-				// 验证当前步骤
+				// 验证当前步骤
 				if (!this.validateCurrentStep()) {
 					return;
 				}
 
+				// 验证所有必填字段
+				const allRequired = [
+					'name', 'gender', 'phone', 'idCard', 'ethnic', 'currentAddress'
+				];
+
+				let isValid = true;
+				allRequired.forEach(field => {
+					if (!this.validateField(field, this.formData[field])) {
+						isValid = false;
+					}
+				});
+
+				if (!isValid) {
+					uni.showToast({
+						title: '请完善所有必填信息',
+						icon: 'none'
+					});
+					return;
+				}
+
 				// 检查必要的用户信息
 				const userInfo = uni.getStorageSync('userInfo');
 				if (!userInfo) {
@@ -1321,89 +1580,85 @@ import { apiBaseUrl } from '@/common/config.js';
 			},
 			// 验证当前步骤的必填项
 			validateCurrentStep() {
-				const validations = {
-					// 第一步:基本信息验证
-					1: () => {
-						const basicChecks = [
-							{ value: this.formData.name, message: '请输入姓名' },
-							{ value: this.formData.gender, message: '请选择性别' },
-							{ value: this.formData.phone, message: '请输入手机号' },
-							{ value: this.formData.idCard, message: '请输入身份证号' }
-						];
-
-						for (const check of basicChecks) {
-							if (!check.value) {
-								uni.showToast({ title: check.message, icon: 'none' });
-								return false;
+				let isValid = true;
+
+				switch (this.currentStep) {
+					case 1: // 基本信息
+						const basicFields = ['name', 'gender', 'phone', 'idCard', 'ethnic', 'currentAddress'];
+						basicFields.forEach(field => {
+							if (!this.validateField(field, this.formData[field])) {
+								isValid = false;
 							}
-						}
+						});
 
-						// 女性三期状态检查
+						// 特殊验证:女性三期状态
 						if (this.formData.gender === '女' && this.threePeriodIndex === -1) {
-							uni.showToast({ title: '请选择是否为三期', icon: 'none' });
-							return false;
+							this.formErrors.threePeriod = '请选择三期状态';
+							isValid = false;
 						}
 
-						return true;
-					},
+						// 可选字段验证(如果有值则验证格式)
+						if (this.formData.height) {
+							isValid = this.validateField('height', this.formData.height) && isValid;
+						}
+						if (this.formData.weight) {
+							isValid = this.validateField('weight', this.formData.weight) && isValid;
+						}
+						if (this.formData.expectedSalary) {
+							isValid = this.validateField('expectedSalary', this.formData.expectedSalary) && isValid;
+						}
+						break;
 
-					// 第二步:家庭成员验证
-					3: () => {
+					case 3: // 家庭成员
 						if (this.familyMembers.length === 0) {
-							uni.showToast({ title: '请至少添加一位家庭成员', icon: 'none' });
-							return false;
+							uni.showToast({
+								title: '请至少添加一位家庭成员',
+								icon: 'none'
+							});
+							isValid = false;
 						}
-						return true;
-					},
+						break;
 
-					// 第三步:教育经历验证
-					5: () => {
+					case 5: // 教育经历
 						if (this.educationList.length === 0) {
-							uni.showToast({ title: '请至少添加一项教育经历', icon: 'none' });
-							return false;
+							uni.showToast({
+								title: '请至少添加一项教育经历',
+								icon: 'none'
+							});
+							isValid = false;
 						}
-						return true;
-					},
+						break;
 
-					// 第四步:专业技能验证
-					6: () => {
-						if (!this.formData.skills) {
-							uni.showToast({ title: '请描述您的专业技能', icon: 'none' });
-							return false;
+					case 6: // 专业技能
+						if (!this.formData.skills?.trim()) {
+							this.formErrors.skills = '请描述您的专业技能';
+							isValid = false;
 						}
-						return true;
-					},
+						if (!this.formData.training?.trim()) {
+							this.formErrors.training = '请描述您的培训经历';
+							isValid = false;
+						}
+						break;
 
-					// 第五步:工作经历验证
-					8: () => {
+					case 8: // 工作经历
 						if (this.workList.length === 0) {
-							uni.showToast({ title: '请至少添加一项工作经历', icon: 'none' });
-							return false;
+							uni.showToast({
+								title: '请至少添加一项工作经历',
+								icon: 'none'
+							});
+							isValid = false;
 						}
+						break;
+				}
 
-						// 验证每个工作经历的必填项
-						for (let i = 0; i < this.workList.length; i++) {
-							const work = this.workList[i];
-							const workChecks = [
-								{ value: work.startTime, message: `单位${i+1}:请选择开始时间` },
-								{ value: work.endTime, message: `单位${i+1}:请选择结束时间` },
-								{ value: work.companyName, message: `单位${i+1}:请输入单位名称` },
-								{ value: work.department, message: `单位${i+1}:请输入任职部门` },
-								{ value: work.position, message: `单位${i+1}:请输入担任职务` }
-							];
-
-							for (const check of workChecks) {
-								if (!check.value) {
-									uni.showToast({ title: check.message, icon: 'none' });
-									return false;
-								}
-							}
-						}
-						return true;
-					}
-				};
+				if (!isValid) {
+					uni.showToast({
+						title: '请完善所有必填信息',
+						icon: 'none'
+					});
+				}
 
-				return validations[this.currentStep] ? validations[this.currentStep]() : true;
+				return isValid;
 			},
 			// Add method to fetch user data
 			fetchUserData() {
@@ -1605,6 +1860,38 @@ import { apiBaseUrl } from '@/common/config.js';
 					this.formData.emergencyPhone = this.familyMemberForm.phone;
 				}
 			},
+			// 添加重置教育经历错误信息的方法
+			resetEducationErrors() {
+				this.educationErrors = {
+					startTime: '',
+					endTime: '',
+					schoolName: '',
+					major: '',
+					degree: ''
+				};
+			},
+			// 添加通用验证方法
+			validateField(fieldName, value) {
+				const rule = this.validationRules[fieldName];
+				if (!rule) return true;
+
+				// 重置该字段的错误信息
+				this.formErrors[fieldName] = '';
+
+				// 必填验证
+				if (rule.required && !value) {
+					this.formErrors[fieldName] = rule.message;
+					return false;
+				}
+
+				// 正则验证
+				if (rule.pattern && !rule.pattern.test(value)) {
+					this.formErrors[fieldName] = rule.message;
+					return false;
+				}
+
+				return true;
+			},
 		},
 		// 添加监听器来清除错误信息
 		watch: {
@@ -1622,6 +1909,119 @@ import { apiBaseUrl } from '@/common/config.js';
 				if (newVal && this.formErrors.phone) {
 					this.formErrors.phone = '';
 				}
+			},
+			'formData.gender': function(newVal) {
+				if (newVal && this.formErrors.gender) {
+					this.formErrors.gender = '';
+				}
+			},
+			'formData.ethnic': function(newVal) {
+				if (newVal && this.formErrors.ethnic) {
+					this.formErrors.ethnic = '';
+				}
+			},
+			'formData.currentAddress': function(newVal) {
+				if (newVal && this.formErrors.currentAddress) {
+					this.formErrors.currentAddress = '';
+				}
+			},
+			'formData.height': function(newVal) {
+				if (newVal && this.formErrors.height) {
+					this.formErrors.height = '';
+				}
+			},
+			'formData.weight': function(newVal) {
+				if (newVal && this.formErrors.weight) {
+					this.formErrors.weight = '';
+				}
+			},
+			'formData.expectedSalary': function(newVal) {
+				if (newVal && this.formErrors.expectedSalary) {
+					this.formErrors.expectedSalary = '';
+				}
+			},
+			'familyMemberForm.relation': function(newVal) {
+				if (newVal) this.familyMemberErrors.relation = '';
+			},
+			'familyMemberForm.name': function(newVal) {
+				if (newVal) this.familyMemberErrors.name = '';
+			},
+			'familyMemberForm.phone': function(newVal) {
+				if (newVal) this.familyMemberErrors.phone = '';
+			},
+			'workForm.companyName': function(newVal) {
+				if (newVal && this.workErrors.companyName) {
+					this.workErrors.companyName = '';
+				}
+			},
+			'workForm.department': function(newVal) {
+				if (newVal && this.workErrors.department) {
+					this.workErrors.department = '';
+				}
+			},
+			'workForm.position': function(newVal) {
+				if (newVal && this.workErrors.position) {
+					this.workErrors.position = '';
+				}
+			},
+			'workForm.employeeCount': function(newVal) {
+				if (newVal && this.workErrors.employeeCount) {
+					this.workErrors.employeeCount = '';
+				}
+			},
+			'workForm.monthlySalary': function(newVal) {
+				if (newVal && this.workErrors.monthlySalary) {
+					this.workErrors.monthlySalary = '';
+				}
+			},
+			'workForm.supervisor': function(newVal) {
+				if (newVal && this.workErrors.supervisor) {
+					this.workErrors.supervisor = '';
+				}
+			},
+			'workForm.supervisorPhone': function(newVal) {
+				if (newVal && this.workErrors.supervisorPhone) {
+					this.workErrors.supervisorPhone = '';
+				}
+			},
+			'formData.training': function(newVal) {
+				if (newVal && this.formErrors.training) {
+					this.formErrors.training = '';
+				}
+			},
+			'educationForm.startTime': function(newVal) {
+				if (newVal) this.educationErrors.startTime = '';
+			},
+			'educationForm.endTime': function(newVal) {
+				if (newVal) this.educationErrors.endTime = '';
+			},
+			'educationForm.schoolName': function(newVal) {
+				if (newVal) this.educationErrors.schoolName = '';
+			},
+			'educationForm.major': function(newVal) {
+				if (newVal) this.educationErrors.major = '';
+			},
+			'educationForm.degree': function(newVal) {
+				if (newVal) this.educationErrors.degree = '';
+			},
+			// 添加对表单字段的实时验证
+			'formData': {
+				handler(newVal) {
+					// 只验证当前步骤的字段
+					const currentStepFields = {
+						1: ['name', 'gender', 'phone', 'idCard', 'ethnic', 'currentAddress', 'height', 'weight', 'expectedSalary'],
+						6: ['skills', 'training']
+					}[this.currentStep];
+
+					if (currentStepFields) {
+						currentStepFields.forEach(field => {
+							if (newVal[field] !== undefined) {
+								this.validateField(field, newVal[field]);
+							}
+						});
+					}
+				},
+				deep: true
 			}
 		},
 	}
@@ -2361,3 +2761,4 @@ import { apiBaseUrl } from '@/common/config.js';
 		margin-top: 10rpx;
 	}
 </style>
+

+ 1 - 1
pages/index/index.vue

@@ -11,7 +11,7 @@
 						<button class="detail-btn" @click.stop="viewJobDetail(job)">查看详情</button>
 					</view>
 					<view class="job-details">
-						<text class="job-salary">{{job.publish_date}}</text>
+						<text class="job-salary"></text>
 						<text class="job-location">{{job.location}}</text>
 					</view>
 					

+ 106 - 157
pages/interview-question/interview-question.vue

@@ -3019,25 +3019,13 @@ export default {
       // 检查音频URL是否有效
       if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === '') {
         console.error('无效的音频URL');
-        // 显示错误提示
-        uni.showToast({
-          title: '音频加载失败',
-          icon: 'none',
-          duration: 2000
-        });
-        
-        // 标记播放结束
-        this.isPlayingAiVoice = false;
-        
-        // 显示继续提问选项
-        this.showContinueQuestionOptions();
+        this.handleAudioPlaybackFailure();
         return;
       }
       
       try {
-        // 创建音频播放器 - 使用 uni.createInnerAudioContext 而不是直接赋值
+        // 创建音频播放器
         if (this.aiAudioPlayer) {
-          // 如果已存在,先销毁
           this.aiAudioPlayer.destroy();
         }
         
@@ -3045,141 +3033,93 @@ export default {
         this.aiAudioPlayer = uni.createInnerAudioContext();
         
         // 设置音频属性
-        this.aiAudioPlayer.autoplay = false; // 不自动播放,手动控制
-        this.aiAudioPlayer.obeyMuteSwitch = false; // 忽略静音开关
+        this.aiAudioPlayer.autoplay = false;
+        this.aiAudioPlayer.obeyMuteSwitch = false;
         
-        // 监听播放开始事件
-        this.aiAudioPlayer.onPlay(() => {
-          console.log('AI语音开始播放');
+        // 监听音频加载完成事件
+        this.aiAudioPlayer.onCanplay(() => {
+          console.log('音频已加载完成,准备播放');
+          // 获取音频时长
+          const duration = this.aiAudioPlayer.duration;
+          console.log('音频时长:', duration);
           
-          // 显示正在播放提示
-          uni.showToast({
-            title: '正在播放面试官的回复',
-            icon: 'none',
-            duration: 2000
-          });
+          // 开始播放
+          this.aiAudioPlayer.play();
         });
         
-        // 监听播放结束事件
-        this.aiAudioPlayer.onEnded(() => {
-          console.log('AI语音播放结束');
+        // 监听播放进度
+        this.aiAudioPlayer.onTimeUpdate(() => {
+          const currentTime = this.aiAudioPlayer.currentTime;
+          const duration = this.aiAudioPlayer.duration;
+          console.log(`播放进度: ${currentTime}/${duration}`);
           
-          // 标记播放结束
-          this.isPlayingAiVoice = false;
-          
-          // 清空字幕
-          this.currentSubtitle = '';
-          
-          // 销毁音频播放器
-          if (this.aiAudioPlayer) {
-            this.aiAudioPlayer.destroy();
-            this.aiAudioPlayer = null;
+          // 更新字幕显示
+          if (this.aiText) {
+            // 根据播放进度计算应该显示的文本部分
+            const textProgress = Math.floor((currentTime / duration) * this.aiText.length);
+            this.currentSubtitle = this.aiText.substring(0, textProgress);
           }
+        });
+        
+        // 监听播放结束事件
+        this.aiAudioPlayer.onEnded(() => {
+          console.log('AI语音播放完成');
           
-          // 播放结束后显示继续提问选项
-          this.showContinueQuestionOptions();
+          // 确保显示完整文本
+          this.currentSubtitle = this.aiText;
           
-          // 检查是否需要自动跳转
-          this.checkPendingNavigation();
+          // 延迟一段时间让用户看完最后的文本
+          setTimeout(() => {
+            // 标记播放结束
+            this.isPlayingAiVoice = false;
+            
+            // 清空字幕
+            this.currentSubtitle = '';
+            
+            // 销毁音频播放器
+            if (this.aiAudioPlayer) {
+              this.aiAudioPlayer.destroy();
+              this.aiAudioPlayer = null;
+            }
+            
+            // 播放结束后显示继续提问选项
+            this.showContinueQuestionOptions();
+            
+            // 检查是否需要自动跳转
+            this.checkPendingNavigation();
+          }, 2000); // 给用户2秒时间阅读最后的文本
         });
         
         // 监听播放错误事件
         this.aiAudioPlayer.onError((err) => {
           console.error('AI语音播放错误:', err);
-          
-          // 尝试使用备选方法播放
-          if (!this.hasTriedFallbackMethod) {
-            this.hasTriedFallbackMethod = true;
-            console.log('尝试使用备选方法播放音频');
-            this.tryFallbackAudioPlay();
-            return;
-          }
-          
-          // 标记播放结束
-          this.isPlayingAiVoice = false;
-          
-          // 清空字幕
-          this.currentSubtitle = '';
-          
-          // 销毁音频播放器
-          if (this.aiAudioPlayer) {
-            this.aiAudioPlayer.destroy();
-            this.aiAudioPlayer = null;
-          }
-          
-          // 显示错误提示
-          uni.showToast({
-            title: '音频播放失败,请查看文字回复',
-            icon: 'none',
-            duration: 2000
-          });
-          
-          // 播放错误时也显示继续提问选项
-          this.showContinueQuestionOptions();
-          
-          // 检查是否需要自动跳转
-          this.checkPendingNavigation();
+          this.handleAudioPlaybackError(err);
         });
         
-        // 监听音频加载事件
-        this.aiAudioPlayer.onCanplay(() => {
-          console.log('音频已准备好播放');
-          // 可以在这里添加额外的处理
-        });
-        
-        // 设置音频源
+        // 设置音频源并开始播放
         this.aiAudioPlayer.src = this.aiVoiceUrl;
         
-        // 添加超时处理,如果5秒内没有开始播放,则认为出错
-        const playTimeout = setTimeout(() => {
-          if (this.isPlayingAiVoice && this.aiAudioPlayer) {
-            console.warn('音频播放超时,尝试备选方法');
-            this.tryFallbackAudioPlay();
-          }
-        }, 5000);
-        
-        // 延迟一小段时间再播放,确保src已经设置完成
-        setTimeout(() => {
-          if (this.aiAudioPlayer) {
-            this.aiAudioPlayer.play();
-            // 播放开始后清除超时
-            clearTimeout(playTimeout);
-          }
-        }, 300);
       } catch (e) {
         console.error('播放AI语音时发生错误:', e);
-        
-        // 标记播放结束
-        this.isPlayingAiVoice = false;
-        
-        // 清空字幕
-        this.currentSubtitle = '';
-        
-        // 尝试销毁音频播放器
-        if (this.aiAudioPlayer) {
-          try {
-            this.aiAudioPlayer.destroy();
-          } catch (destroyError) {
-            console.error('销毁音频播放器失败:', destroyError);
-          }
-          this.aiAudioPlayer = null;
-        }
-        
-        // 显示错误提示
-        uni.showToast({
-          title: '音频播放失败,请查看文字回复',
-          icon: 'none',
-          duration: 2000
-        });
-        
-        // 发生错误时显示继续提问选项
-        this.showContinueQuestionOptions();
-        
-        // 检查是否需要自动跳转
-        this.checkPendingNavigation();
+        this.handleAudioPlaybackError(e);
       }
     },
 
+    // 添加新方法:处理音频播放错误
+    handleAudioPlaybackError(error) {
+      console.error('音频播放错误:', error);
+      
+      // 尝试使用备选方法
+      if (!this.hasTriedFallbackMethod) {
+        this.hasTriedFallbackMethod = true;
+        this.tryFallbackAudioPlay();
+        return;
+      }
+      
+      // 如果备选方法也失败,回退到文本显示
+      this.handleAudioPlaybackFailure();
+    },
+
     // 添加新方法:尝试备选音频播放方法
     tryFallbackAudioPlay() {
       console.log('使用备选方法播放音频:', this.aiVoiceUrl);
@@ -3780,52 +3720,61 @@ export default {
 
     // 添加新方法:检查是否有待处理的自动跳转
     checkPendingNavigation() {
-      if (this.pendingAutoNavigation && !this.isPlayingAiVoice && !this.isUploading) {
-        console.log('所有处理已完成,执行自动跳转');
+      // 确保所有处理都已完成
+      if (this.pendingAutoNavigation && 
+          !this.isPlayingAiVoice && 
+          !this.isUploading && 
+          !this.currentSubtitle) { // 确保字幕也已经清空
+        
+        console.log('所有处理已完成,准备跳转');
         
         // 重置标志
         this.pendingAutoNavigation = false;
         
-        // 延迟2秒后跳转,给用户一点时间看到最终状态
+        // 延迟跳转,给用户一点时间看到最终状态
         setTimeout(() => {
           this.navigateToNextPage();
-        }, 2000);
+        }, 1000);
       }
     },
 
     // 添加新方法:显示文本回复
     displayTextResponse() {
-      // 标记为正在"播放",防止用户操作
+      // 标记为正在"播放"
       this.isPlayingAiVoice = true;
       
       // 显示AI回复文本
-      this.currentSubtitle = this.aiText;
-      
-      // 显示提示
-      uni.showToast({
-        title: '显示面试官文字回复',
-        icon: 'none',
-        duration: 2000
-      });
+      this.currentSubtitle = '';
       
-      // 根据文本长度计算显示时间(每个字符约需要0.1秒阅读时间,最少5秒,最多15秒)
-      const textLength = this.aiText.length;
-      const displayTime = Math.min(Math.max(textLength * 100, 5000), 15000);
+      // 计算每个字的显示时间(假设每个字需要200毫秒)
+      const charDisplayTime = 200;
+      let currentIndex = 0;
       
-      // 设置定时器,显示一段时间后清除
-      setTimeout(() => {
-        // 标记播放结束
-        this.isPlayingAiVoice = false;
-        
-        // 清空字幕
-        this.currentSubtitle = '';
-        
-        // 显示继续提问选项
-        this.showContinueQuestionOptions();
-        
-        // 检查是否需要自动跳转
-        this.checkPendingNavigation();
-      }, displayTime);
+      // 使用定时器逐字显示文本
+      const textInterval = setInterval(() => {
+        if (currentIndex <= this.aiText.length) {
+          this.currentSubtitle = this.aiText.substring(0, currentIndex);
+          currentIndex++;
+        } else {
+          // 文本显示完成
+          clearInterval(textInterval);
+          
+          // 等待用户阅读完整文本
+          setTimeout(() => {
+            // 标记播放结束
+            this.isPlayingAiVoice = false;
+            
+            // 清空字幕
+            this.currentSubtitle = '';
+            
+            // 显示继续提问选项
+            this.showContinueQuestionOptions();
+            
+            // 检查是否需要自动跳转
+            this.checkPendingNavigation();
+          }, 3000); // 给用户3秒时间阅读完整文本
+        }
+      }, charDisplayTime);
     },
 
     // 添加新方法:检查不支持的音频格式

+ 4 - 4
pages/login/login.vue

@@ -1,7 +1,7 @@
 <template>
   <view class="login-container">
-    <image class="login-image" src="/static/login-image.png" mode="aspectFit"></image>
-    <view class="login-title">登录奇才,开始面试</view>
+    <image class="login-image" src="https://data.qicai321.com/minlong/8baae825-6aa1-4783-9875-44d699f297cb.jpg" mode="aspectFit"></image>
+    <view class="login-title">奇才,只选对的</view>
     <button class="login-btn" @click="handleLogin">微信登录</button>
     <view class="agreement">
       <checkbox :checked="isAgreed" @tap="toggleAgreement" color="#0039b3" />
@@ -313,7 +313,7 @@ export default {
 }
 
 .login-image {
-  width: 100%;
+  width: 90%;
 
   margin-bottom: 40rpx;
 }
@@ -321,7 +321,7 @@ export default {
 .login-title {
   font-size: 36rpx;
   font-weight: bold;
-  margin-bottom: 60rpx;
+  margin-bottom: 200rpx;
   color: #333;
 }
 

+ 1 - 3
unpackage/dist/dev/mp-weixin/common/assets.js

@@ -1,5 +1,3 @@
 "use strict";
-const _imports_0$1 = "/static/login-image.png";
 const _imports_0 = "/static/avatar.png";
-exports._imports_0 = _imports_0$1;
-exports._imports_0$1 = _imports_0;
+exports._imports_0 = _imports_0;

+ 566 - 204
unpackage/dist/dev/mp-weixin/pages/Personal/Personal.js

@@ -103,10 +103,85 @@ const _sfc_main = {
       formErrors: {
         name: "",
         idCard: "",
-        phone: ""
+        phone: "",
+        gender: "",
+        ethnic: "",
+        currentAddress: "",
+        height: "",
+        weight: "",
+        expectedSalary: "",
+        skills: "",
+        training: ""
       },
       // Add loading state
-      isLoading: true
+      isLoading: true,
+      familyMemberErrors: {
+        relation: "",
+        name: "",
+        phone: "",
+        workplaceOrAddress: "",
+        position: ""
+      },
+      workErrors: {
+        startTime: "",
+        endTime: "",
+        companyName: "",
+        department: "",
+        position: "",
+        employeeCount: "",
+        monthlySalary: "",
+        supervisor: "",
+        supervisorPhone: ""
+      },
+      // 在 data 中添加教育经历的错误提示对象
+      educationErrors: {
+        startTime: "",
+        endTime: "",
+        schoolName: "",
+        major: "",
+        degree: ""
+      },
+      // 添加统一的验证规则
+      validationRules: {
+        name: {
+          required: true,
+          message: "请输入姓名"
+        },
+        phone: {
+          required: true,
+          pattern: /^1[3-9]\d{9}$/,
+          message: "请输入正确的手机号码"
+        },
+        idCard: {
+          required: true,
+          pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
+          message: "请输入正确的身份证号码"
+        },
+        gender: {
+          required: true,
+          message: "请选择性别"
+        },
+        ethnic: {
+          required: true,
+          message: "请选择民族"
+        },
+        height: {
+          pattern: /^\d+(\.\d{1,2})?$/,
+          message: "请输入正确的身高(cm)"
+        },
+        weight: {
+          pattern: /^\d+(\.\d{1,2})?$/,
+          message: "请输入正确的体重(kg)"
+        },
+        expectedSalary: {
+          pattern: /^\d+(\.\d{1,2})?$/,
+          message: "请输入正确的期望薪资"
+        },
+        currentAddress: {
+          required: true,
+          message: "请输入现居住地址"
+        }
+      }
     };
   },
   onLoad() {
@@ -171,32 +246,39 @@ const _sfc_main = {
       this.formData.birthDate = e.detail.value;
     },
     saveFamilyMember() {
+      this.resetFamilyMemberErrors();
+      let isValid = true;
       if (!this.familyMemberForm.relation) {
-        common_vendor.index.showToast({
-          title: "请输入称谓",
-          icon: "none"
-        });
-        return;
+        this.familyMemberErrors.relation = "请输入称谓";
+        isValid = false;
       }
       if (!this.familyMemberForm.name) {
-        common_vendor.index.showToast({
-          title: "请输入姓名",
-          icon: "none"
-        });
-        return;
+        this.familyMemberErrors.name = "请输入姓名";
+        isValid = false;
+      }
+      if (!this.familyMemberForm.workplaceOrAddress) {
+        this.familyMemberErrors.workplaceOrAddress = "请输入工作单位/家庭地址";
+        isValid = false;
+      }
+      if (!this.familyMemberForm.position) {
+        this.familyMemberErrors.position = "请输入职务";
+        isValid = false;
       }
       if (!this.familyMemberForm.phone) {
+        this.familyMemberErrors.phone = "请输入联系电话";
+        isValid = false;
+      } else if (!/^1[3-9]\d{9}$/.test(this.familyMemberForm.phone)) {
+        this.familyMemberErrors.phone = "请输入正确的手机号";
+        isValid = false;
+      }
+      if (!isValid) {
         common_vendor.index.showToast({
-          title: "请输入联系电话",
+          title: "请完善所有必填信息",
           icon: "none"
         });
         return;
       }
       if (this.isEditing) {
-        if (!this.familyMemberForm.isEmergencyContact && this.familyMembers[this.editingIndex].isEmergencyContact) {
-          this.formData.emergencyContact = "";
-          this.formData.emergencyPhone = "";
-        }
         this.familyMembers[this.editingIndex] = { ...this.familyMemberForm };
         common_vendor.index.showToast({
           title: "修改成功",
@@ -211,6 +293,20 @@ const _sfc_main = {
           icon: "success"
         });
       }
+      this.resetFamilyMemberForm();
+    },
+    // 添加重置错误信息的方法
+    resetFamilyMemberErrors() {
+      this.familyMemberErrors = {
+        relation: "",
+        name: "",
+        phone: "",
+        workplaceOrAddress: "",
+        position: ""
+      };
+    },
+    // 修改重置表单的方法
+    resetFamilyMemberForm() {
       this.familyMemberForm = {
         relation: "",
         name: "",
@@ -219,6 +315,7 @@ const _sfc_main = {
         phone: "",
         isEmergencyContact: false
       };
+      this.resetFamilyMemberErrors();
     },
     editFamilyMember(index) {
       this.isEditing = true;
@@ -277,37 +374,31 @@ const _sfc_main = {
       this.educationForm.degree = this.degreeOptions[this.degreeIndex];
     },
     saveEducation() {
+      this.resetEducationErrors();
+      let isValid = true;
       if (!this.educationForm.startTime) {
-        common_vendor.index.showToast({
-          title: "请选择开始时间",
-          icon: "none"
-        });
-        return;
+        this.educationErrors.startTime = "请选择开始时间";
+        isValid = false;
       }
       if (!this.educationForm.endTime) {
-        common_vendor.index.showToast({
-          title: "请选择结束时间",
-          icon: "none"
-        });
-        return;
+        this.educationErrors.endTime = "请选择结束时间";
+        isValid = false;
       }
       if (!this.educationForm.schoolName) {
-        common_vendor.index.showToast({
-          title: "请输入学校名称",
-          icon: "none"
-        });
-        return;
+        this.educationErrors.schoolName = "请输入学校名称";
+        isValid = false;
       }
       if (!this.educationForm.major) {
-        common_vendor.index.showToast({
-          title: "请输入专业",
-          icon: "none"
-        });
-        return;
+        this.educationErrors.major = "请输入专业";
+        isValid = false;
       }
       if (!this.educationForm.degree) {
+        this.educationErrors.degree = "请选择学历";
+        isValid = false;
+      }
+      if (!isValid) {
         common_vendor.index.showToast({
-          title: "请选择学历",
+          title: "请完善所有必填信息",
           icon: "none"
         });
         return;
@@ -376,39 +467,55 @@ const _sfc_main = {
       this.workForm.endTime = e.detail.value;
     },
     saveWork() {
+      this.workErrors = {
+        startTime: "",
+        endTime: "",
+        companyName: "",
+        department: "",
+        position: "",
+        employeeCount: "",
+        monthlySalary: "",
+        supervisor: "",
+        supervisorPhone: ""
+      };
+      let isValid = true;
       if (!this.workForm.startTime) {
-        common_vendor.index.showToast({
-          title: "请选择开始时间",
-          icon: "none"
-        });
-        return;
+        this.workErrors.startTime = "请选择开始时间";
+        isValid = false;
       }
       if (!this.workForm.endTime) {
-        common_vendor.index.showToast({
-          title: "请选择结束时间",
-          icon: "none"
-        });
-        return;
+        this.workErrors.endTime = "请选择结束时间";
+        isValid = false;
       }
       if (!this.workForm.companyName) {
-        common_vendor.index.showToast({
-          title: "请输入单位名称",
-          icon: "none"
-        });
-        return;
+        this.workErrors.companyName = "请输入单位名称";
+        isValid = false;
       }
       if (!this.workForm.department) {
-        common_vendor.index.showToast({
-          title: "请输入任职部门",
-          icon: "none"
-        });
-        return;
+        this.workErrors.department = "请输入任职部门";
+        isValid = false;
       }
       if (!this.workForm.position) {
-        common_vendor.index.showToast({
-          title: "请输入担任职务",
-          icon: "none"
-        });
+        this.workErrors.position = "请输入担任职务";
+        isValid = false;
+      }
+      if (!this.workForm.employeeCount) {
+        this.workErrors.employeeCount = "请输入单位人数";
+        isValid = false;
+      }
+      if (!this.workForm.monthlySalary) {
+        this.workErrors.monthlySalary = "请输入月薪";
+        isValid = false;
+      }
+      if (!this.workForm.supervisor) {
+        this.workErrors.supervisor = "请输入直属上级";
+        isValid = false;
+      }
+      if (!this.workForm.supervisorPhone) {
+        this.workErrors.supervisorPhone = "请输入直属上级电话";
+        isValid = false;
+      }
+      if (!isValid) {
         return;
       }
       if (this.isEditingWork) {
@@ -476,6 +583,27 @@ const _sfc_main = {
       if (!this.validateCurrentStep()) {
         return;
       }
+      const allRequired = [
+        "name",
+        "gender",
+        "phone",
+        "idCard",
+        "ethnic",
+        "currentAddress"
+      ];
+      let isValid = true;
+      allRequired.forEach((field) => {
+        if (!this.validateField(field, this.formData[field])) {
+          isValid = false;
+        }
+      });
+      if (!isValid) {
+        common_vendor.index.showToast({
+          title: "请完善所有必填信息",
+          icon: "none"
+        });
+        return;
+      }
       const userInfo = common_vendor.index.getStorageSync("userInfo");
       if (!userInfo) {
         common_vendor.index.showToast({
@@ -765,77 +893,75 @@ const _sfc_main = {
     },
     // 验证当前步骤的必填项
     validateCurrentStep() {
-      const validations = {
-        // 第一步:基本信息验证
-        1: () => {
-          const basicChecks = [
-            { value: this.formData.name, message: "请输入姓名" },
-            { value: this.formData.gender, message: "请选择性别" },
-            { value: this.formData.phone, message: "请输入手机号" },
-            { value: this.formData.idCard, message: "请输入身份证号" }
-          ];
-          for (const check of basicChecks) {
-            if (!check.value) {
-              common_vendor.index.showToast({ title: check.message, icon: "none" });
-              return false;
+      var _a, _b;
+      let isValid = true;
+      switch (this.currentStep) {
+        case 1:
+          const basicFields = ["name", "gender", "phone", "idCard", "ethnic", "currentAddress"];
+          basicFields.forEach((field) => {
+            if (!this.validateField(field, this.formData[field])) {
+              isValid = false;
             }
-          }
+          });
           if (this.formData.gender === "女" && this.threePeriodIndex === -1) {
-            common_vendor.index.showToast({ title: "请选择是否为三期", icon: "none" });
-            return false;
+            this.formErrors.threePeriod = "请选择三期状态";
+            isValid = false;
           }
-          return true;
-        },
-        // 第二步:家庭成员验证
-        3: () => {
+          if (this.formData.height) {
+            isValid = this.validateField("height", this.formData.height) && isValid;
+          }
+          if (this.formData.weight) {
+            isValid = this.validateField("weight", this.formData.weight) && isValid;
+          }
+          if (this.formData.expectedSalary) {
+            isValid = this.validateField("expectedSalary", this.formData.expectedSalary) && isValid;
+          }
+          break;
+        case 3:
           if (this.familyMembers.length === 0) {
-            common_vendor.index.showToast({ title: "请至少添加一位家庭成员", icon: "none" });
-            return false;
+            common_vendor.index.showToast({
+              title: "请至少添加一位家庭成员",
+              icon: "none"
+            });
+            isValid = false;
           }
-          return true;
-        },
-        // 第三步:教育经历验证
-        5: () => {
+          break;
+        case 5:
           if (this.educationList.length === 0) {
-            common_vendor.index.showToast({ title: "请至少添加一项教育经历", icon: "none" });
-            return false;
+            common_vendor.index.showToast({
+              title: "请至少添加一项教育经历",
+              icon: "none"
+            });
+            isValid = false;
           }
-          return true;
-        },
-        // 第四步:专业技能验证
-        6: () => {
-          if (!this.formData.skills) {
-            common_vendor.index.showToast({ title: "请描述您的专业技能", icon: "none" });
-            return false;
+          break;
+        case 6:
+          if (!((_a = this.formData.skills) == null ? void 0 : _a.trim())) {
+            this.formErrors.skills = "请描述您的专业技能";
+            isValid = false;
           }
-          return true;
-        },
-        // 第五步:工作经历验证
-        8: () => {
-          if (this.workList.length === 0) {
-            common_vendor.index.showToast({ title: "请至少添加一项工作经历", icon: "none" });
-            return false;
+          if (!((_b = this.formData.training) == null ? void 0 : _b.trim())) {
+            this.formErrors.training = "请描述您的培训经历";
+            isValid = false;
           }
-          for (let i = 0; i < this.workList.length; i++) {
-            const work = this.workList[i];
-            const workChecks = [
-              { value: work.startTime, message: `单位${i + 1}:请选择开始时间` },
-              { value: work.endTime, message: `单位${i + 1}:请选择结束时间` },
-              { value: work.companyName, message: `单位${i + 1}:请输入单位名称` },
-              { value: work.department, message: `单位${i + 1}:请输入任职部门` },
-              { value: work.position, message: `单位${i + 1}:请输入担任职务` }
-            ];
-            for (const check of workChecks) {
-              if (!check.value) {
-                common_vendor.index.showToast({ title: check.message, icon: "none" });
-                return false;
-              }
-            }
+          break;
+        case 8:
+          if (this.workList.length === 0) {
+            common_vendor.index.showToast({
+              title: "请至少添加一项工作经历",
+              icon: "none"
+            });
+            isValid = false;
           }
-          return true;
-        }
-      };
-      return validations[this.currentStep] ? validations[this.currentStep]() : true;
+          break;
+      }
+      if (!isValid) {
+        common_vendor.index.showToast({
+          title: "请完善所有必填信息",
+          icon: "none"
+        });
+      }
+      return isValid;
     },
     // Add method to fetch user data
     fetchUserData() {
@@ -973,6 +1099,32 @@ const _sfc_main = {
         this.formData.emergencyContact = this.familyMemberForm.name;
         this.formData.emergencyPhone = this.familyMemberForm.phone;
       }
+    },
+    // 添加重置教育经历错误信息的方法
+    resetEducationErrors() {
+      this.educationErrors = {
+        startTime: "",
+        endTime: "",
+        schoolName: "",
+        major: "",
+        degree: ""
+      };
+    },
+    // 添加通用验证方法
+    validateField(fieldName, value) {
+      const rule = this.validationRules[fieldName];
+      if (!rule)
+        return true;
+      this.formErrors[fieldName] = "";
+      if (rule.required && !value) {
+        this.formErrors[fieldName] = rule.message;
+        return false;
+      }
+      if (rule.pattern && !rule.pattern.test(value)) {
+        this.formErrors[fieldName] = rule.message;
+        return false;
+      }
+      return true;
     }
   },
   // 添加监听器来清除错误信息
@@ -991,6 +1143,125 @@ const _sfc_main = {
       if (newVal && this.formErrors.phone) {
         this.formErrors.phone = "";
       }
+    },
+    "formData.gender": function(newVal) {
+      if (newVal && this.formErrors.gender) {
+        this.formErrors.gender = "";
+      }
+    },
+    "formData.ethnic": function(newVal) {
+      if (newVal && this.formErrors.ethnic) {
+        this.formErrors.ethnic = "";
+      }
+    },
+    "formData.currentAddress": function(newVal) {
+      if (newVal && this.formErrors.currentAddress) {
+        this.formErrors.currentAddress = "";
+      }
+    },
+    "formData.height": function(newVal) {
+      if (newVal && this.formErrors.height) {
+        this.formErrors.height = "";
+      }
+    },
+    "formData.weight": function(newVal) {
+      if (newVal && this.formErrors.weight) {
+        this.formErrors.weight = "";
+      }
+    },
+    "formData.expectedSalary": function(newVal) {
+      if (newVal && this.formErrors.expectedSalary) {
+        this.formErrors.expectedSalary = "";
+      }
+    },
+    "familyMemberForm.relation": function(newVal) {
+      if (newVal)
+        this.familyMemberErrors.relation = "";
+    },
+    "familyMemberForm.name": function(newVal) {
+      if (newVal)
+        this.familyMemberErrors.name = "";
+    },
+    "familyMemberForm.phone": function(newVal) {
+      if (newVal)
+        this.familyMemberErrors.phone = "";
+    },
+    "workForm.companyName": function(newVal) {
+      if (newVal && this.workErrors.companyName) {
+        this.workErrors.companyName = "";
+      }
+    },
+    "workForm.department": function(newVal) {
+      if (newVal && this.workErrors.department) {
+        this.workErrors.department = "";
+      }
+    },
+    "workForm.position": function(newVal) {
+      if (newVal && this.workErrors.position) {
+        this.workErrors.position = "";
+      }
+    },
+    "workForm.employeeCount": function(newVal) {
+      if (newVal && this.workErrors.employeeCount) {
+        this.workErrors.employeeCount = "";
+      }
+    },
+    "workForm.monthlySalary": function(newVal) {
+      if (newVal && this.workErrors.monthlySalary) {
+        this.workErrors.monthlySalary = "";
+      }
+    },
+    "workForm.supervisor": function(newVal) {
+      if (newVal && this.workErrors.supervisor) {
+        this.workErrors.supervisor = "";
+      }
+    },
+    "workForm.supervisorPhone": function(newVal) {
+      if (newVal && this.workErrors.supervisorPhone) {
+        this.workErrors.supervisorPhone = "";
+      }
+    },
+    "formData.training": function(newVal) {
+      if (newVal && this.formErrors.training) {
+        this.formErrors.training = "";
+      }
+    },
+    "educationForm.startTime": function(newVal) {
+      if (newVal)
+        this.educationErrors.startTime = "";
+    },
+    "educationForm.endTime": function(newVal) {
+      if (newVal)
+        this.educationErrors.endTime = "";
+    },
+    "educationForm.schoolName": function(newVal) {
+      if (newVal)
+        this.educationErrors.schoolName = "";
+    },
+    "educationForm.major": function(newVal) {
+      if (newVal)
+        this.educationErrors.major = "";
+    },
+    "educationForm.degree": function(newVal) {
+      if (newVal)
+        this.educationErrors.degree = "";
+    },
+    // 添加对表单字段的实时验证
+    "formData": {
+      handler(newVal) {
+        const currentStepFields = {
+          1: ["name", "gender", "phone", "idCard", "ethnic", "currentAddress", "height", "weight", "expectedSalary"],
+          6: ["skills", "training"]
+        }[this.currentStep];
+        if (currentStepFields) {
+          currentStepFields.forEach((field) => {
+            if (newVal[field] !== void 0) {
+              this.validateField(field, newVal[field]);
+            }
+          });
+        }
+      },
+      deep: true
     }
   }
 };
@@ -1082,27 +1353,42 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
   }, $data.isEditing ? {
     ad: common_vendor.o((...args) => $options.cancelEdit && $options.cancelEdit(...args))
   } : {}, {
-    ae: $data.familyMemberForm.relation,
-    af: common_vendor.o(($event) => $data.familyMemberForm.relation = $event.detail.value),
-    ag: $data.familyMemberForm.name,
-    ah: common_vendor.o(($event) => $data.familyMemberForm.name = $event.detail.value),
-    ai: $data.familyMemberForm.workplaceOrAddress,
-    aj: common_vendor.o(($event) => $data.familyMemberForm.workplaceOrAddress = $event.detail.value),
-    ak: $data.familyMemberForm.position,
-    al: common_vendor.o(($event) => $data.familyMemberForm.position = $event.detail.value),
-    am: $data.familyMemberForm.phone,
-    an: common_vendor.o(($event) => $data.familyMemberForm.phone = $event.detail.value),
-    ao: $data.familyMemberForm.isEmergencyContact,
-    ap: common_vendor.o((...args) => $options.handleEmergencyContactChange && $options.handleEmergencyContactChange(...args)),
-    aq: common_vendor.t($data.isEditing ? "✓" : "+"),
-    ar: common_vendor.o((...args) => $options.saveFamilyMember && $options.saveFamilyMember(...args)),
-    as: common_vendor.t($data.isEditing ? "保存修改" : "添加成员")
+    ae: $data.familyMemberErrors.relation ? 1 : "",
+    af: $data.familyMemberForm.relation,
+    ag: common_vendor.o(($event) => $data.familyMemberForm.relation = $event.detail.value),
+    ah: $data.familyMemberErrors.relation
+  }, $data.familyMemberErrors.relation ? {
+    ai: common_vendor.t($data.familyMemberErrors.relation)
+  } : {}, {
+    aj: $data.familyMemberErrors.name ? 1 : "",
+    ak: $data.familyMemberForm.name,
+    al: common_vendor.o(($event) => $data.familyMemberForm.name = $event.detail.value),
+    am: $data.familyMemberErrors.name
+  }, $data.familyMemberErrors.name ? {
+    an: common_vendor.t($data.familyMemberErrors.name)
+  } : {}, {
+    ao: $data.familyMemberForm.workplaceOrAddress,
+    ap: common_vendor.o(($event) => $data.familyMemberForm.workplaceOrAddress = $event.detail.value),
+    aq: $data.familyMemberForm.position,
+    ar: common_vendor.o(($event) => $data.familyMemberForm.position = $event.detail.value),
+    as: $data.familyMemberErrors.phone ? 1 : "",
+    at: $data.familyMemberForm.phone,
+    av: common_vendor.o(($event) => $data.familyMemberForm.phone = $event.detail.value),
+    aw: $data.familyMemberErrors.phone
+  }, $data.familyMemberErrors.phone ? {
+    ax: common_vendor.t($data.familyMemberErrors.phone)
+  } : {}, {
+    ay: $data.familyMemberForm.isEmergencyContact,
+    az: common_vendor.o((...args) => $options.handleEmergencyContactChange && $options.handleEmergencyContactChange(...args)),
+    aA: common_vendor.t($data.isEditing ? "✓" : "+"),
+    aB: common_vendor.o((...args) => $options.saveFamilyMember && $options.saveFamilyMember(...args)),
+    aC: common_vendor.t($data.isEditing ? "保存修改" : "添加成员")
   }) : {}, {
-    at: $data.currentStep === 5
+    aD: $data.currentStep === 5
   }, $data.currentStep === 5 ? common_vendor.e({
-    av: $data.educationList.length > 0
+    aE: $data.educationList.length > 0
   }, $data.educationList.length > 0 ? {
-    aw: common_vendor.f($data.educationList, (edu, index, i0) => {
+    aF: common_vendor.f($data.educationList, (edu, index, i0) => {
       return {
         a: common_vendor.t(index === 0 ? "第一学历" : "最高学历"),
         b: common_vendor.o(($event) => $options.editEducation(index), index),
@@ -1116,43 +1402,77 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
       };
     })
   } : {}, {
-    ax: $data.educationList.length < 2 || $data.isEditingEducation
+    aG: $data.educationList.length < 2 || $data.isEditingEducation
   }, $data.educationList.length < 2 || $data.isEditingEducation ? common_vendor.e({
-    ay: common_vendor.t($data.isEditingEducation ? "编辑教育经历" : $data.educationList.length === 0 ? "添加第一学历" : "添加最高学历"),
-    az: $data.isEditingEducation
+    aH: common_vendor.t($data.isEditingEducation ? "编辑教育经历" : $data.educationList.length === 0 ? "添加第一学历" : "添加最高学历"),
+    aI: $data.isEditingEducation
   }, $data.isEditingEducation ? {
-    aA: common_vendor.o((...args) => $options.cancelEditEducation && $options.cancelEditEducation(...args))
+    aJ: common_vendor.o((...args) => $options.cancelEditEducation && $options.cancelEditEducation(...args))
+  } : {}, {
+    aK: common_vendor.t($data.educationForm.startTime || "开始时间"),
+    aL: $data.educationForm.startTime,
+    aM: common_vendor.o((...args) => $options.bindStartTimeChange && $options.bindStartTimeChange(...args)),
+    aN: $data.educationErrors.startTime ? 1 : "",
+    aO: common_vendor.t($data.educationForm.endTime || "结束时间"),
+    aP: $data.educationForm.endTime,
+    aQ: common_vendor.o((...args) => $options.bindEndTimeChange && $options.bindEndTimeChange(...args)),
+    aR: $data.educationErrors.endTime ? 1 : "",
+    aS: $data.educationErrors.startTime
+  }, $data.educationErrors.startTime ? {
+    aT: common_vendor.t($data.educationErrors.startTime)
   } : {}, {
-    aB: common_vendor.t($data.educationForm.startTime || "开始时间"),
-    aC: $data.educationForm.startTime,
-    aD: common_vendor.o((...args) => $options.bindStartTimeChange && $options.bindStartTimeChange(...args)),
-    aE: common_vendor.t($data.educationForm.endTime || "结束时间"),
-    aF: $data.educationForm.endTime,
-    aG: common_vendor.o((...args) => $options.bindEndTimeChange && $options.bindEndTimeChange(...args)),
-    aH: $data.educationForm.schoolName,
-    aI: common_vendor.o(($event) => $data.educationForm.schoolName = $event.detail.value),
-    aJ: $data.educationForm.major,
-    aK: common_vendor.o(($event) => $data.educationForm.major = $event.detail.value),
-    aL: common_vendor.t($data.degreeOptions[$data.degreeIndex] || "请选择学历"),
-    aM: common_vendor.o((...args) => $options.bindDegreeChange && $options.bindDegreeChange(...args)),
-    aN: $data.degreeIndex,
-    aO: $data.degreeOptions,
-    aP: common_vendor.t($data.isEditingEducation ? "✓" : "+"),
-    aQ: common_vendor.o((...args) => $options.saveEducation && $options.saveEducation(...args)),
-    aR: common_vendor.t($data.isEditingEducation ? "保存修改" : "添加学历")
+    aU: $data.educationErrors.endTime
+  }, $data.educationErrors.endTime ? {
+    aV: common_vendor.t($data.educationErrors.endTime)
+  } : {}, {
+    aW: $data.educationErrors.schoolName ? 1 : "",
+    aX: $data.educationForm.schoolName,
+    aY: common_vendor.o(($event) => $data.educationForm.schoolName = $event.detail.value),
+    aZ: $data.educationErrors.schoolName
+  }, $data.educationErrors.schoolName ? {
+    ba: common_vendor.t($data.educationErrors.schoolName)
+  } : {}, {
+    bb: $data.educationErrors.major ? 1 : "",
+    bc: $data.educationForm.major,
+    bd: common_vendor.o(($event) => $data.educationForm.major = $event.detail.value),
+    be: $data.educationErrors.major
+  }, $data.educationErrors.major ? {
+    bf: common_vendor.t($data.educationErrors.major)
+  } : {}, {
+    bg: common_vendor.t($data.degreeOptions[$data.degreeIndex] || "请选择学历"),
+    bh: common_vendor.o((...args) => $options.bindDegreeChange && $options.bindDegreeChange(...args)),
+    bi: $data.degreeIndex,
+    bj: $data.degreeOptions,
+    bk: $data.educationErrors.degree ? 1 : "",
+    bl: $data.educationErrors.degree
+  }, $data.educationErrors.degree ? {
+    bm: common_vendor.t($data.educationErrors.degree)
+  } : {}, {
+    bn: common_vendor.t($data.isEditingEducation ? "✓" : "+"),
+    bo: common_vendor.o((...args) => $options.saveEducation && $options.saveEducation(...args)),
+    bp: common_vendor.t($data.isEditingEducation ? "保存修改" : "添加学历")
   }) : {}) : {}, {
-    aS: $data.currentStep === 6
-  }, $data.currentStep === 6 ? {
-    aT: $data.formData.skills,
-    aU: common_vendor.o(($event) => $data.formData.skills = $event.detail.value),
-    aV: $data.formData.training,
-    aW: common_vendor.o(($event) => $data.formData.training = $event.detail.value)
+    bq: $data.currentStep === 6
+  }, $data.currentStep === 6 ? common_vendor.e({
+    br: $data.formErrors.skills ? 1 : "",
+    bs: $data.formData.skills,
+    bt: common_vendor.o(($event) => $data.formData.skills = $event.detail.value),
+    bv: $data.formErrors.skills
+  }, $data.formErrors.skills ? {
+    bw: common_vendor.t($data.formErrors.skills)
   } : {}, {
-    aX: $data.currentStep === 8
+    bx: $data.formErrors.training ? 1 : "",
+    by: $data.formData.training,
+    bz: common_vendor.o(($event) => $data.formData.training = $event.detail.value),
+    bA: $data.formErrors.training
+  }, $data.formErrors.training ? {
+    bB: common_vendor.t($data.formErrors.training)
+  } : {}) : {}, {
+    bC: $data.currentStep === 8
   }, $data.currentStep === 8 ? common_vendor.e({
-    aY: $data.workList.length > 0
+    bD: $data.workList.length > 0
   }, $data.workList.length > 0 ? {
-    aZ: common_vendor.f($data.workList, (work, index, i0) => {
+    bE: common_vendor.f($data.workList, (work, index, i0) => {
       return {
         a: common_vendor.t(index + 1),
         b: common_vendor.o(($event) => $options.editWork(index), index),
@@ -1170,48 +1490,90 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
       };
     })
   } : {}, {
-    ba: $data.workList.length < 2 || $data.isEditingWork
+    bF: $data.workList.length < 2 || $data.isEditingWork
   }, $data.workList.length < 2 || $data.isEditingWork ? common_vendor.e({
-    bb: common_vendor.t($data.isEditingWork ? "编辑工作经历" : "添加工作经历"),
-    bc: $data.isEditingWork
+    bG: common_vendor.t($data.isEditingWork ? "编辑工作经历" : "添加工作经历"),
+    bH: $data.isEditingWork
   }, $data.isEditingWork ? {
-    bd: common_vendor.o((...args) => $options.cancelEditWork && $options.cancelEditWork(...args))
+    bI: common_vendor.o((...args) => $options.cancelEditWork && $options.cancelEditWork(...args))
+  } : {}, {
+    bJ: common_vendor.t($data.workForm.startTime || "开始时间"),
+    bK: $data.workForm.startTime,
+    bL: common_vendor.o((...args) => $options.bindWorkStartTimeChange && $options.bindWorkStartTimeChange(...args)),
+    bM: $data.workErrors.startTime ? 1 : "",
+    bN: common_vendor.t($data.workForm.endTime || "结束时间"),
+    bO: $data.workForm.endTime,
+    bP: common_vendor.o((...args) => $options.bindWorkEndTimeChange && $options.bindWorkEndTimeChange(...args)),
+    bQ: $data.workErrors.endTime ? 1 : "",
+    bR: $data.workErrors.startTime
+  }, $data.workErrors.startTime ? {
+    bS: common_vendor.t($data.workErrors.startTime)
+  } : {}, {
+    bT: $data.workErrors.endTime
+  }, $data.workErrors.endTime ? {
+    bU: common_vendor.t($data.workErrors.endTime)
+  } : {}, {
+    bV: $data.workErrors.companyName ? 1 : "",
+    bW: $data.workForm.companyName,
+    bX: common_vendor.o(($event) => $data.workForm.companyName = $event.detail.value),
+    bY: $data.workErrors.companyName
+  }, $data.workErrors.companyName ? {
+    bZ: common_vendor.t($data.workErrors.companyName)
+  } : {}, {
+    ca: $data.workErrors.employeeCount ? 1 : "",
+    cb: $data.workForm.employeeCount,
+    cc: common_vendor.o(($event) => $data.workForm.employeeCount = $event.detail.value),
+    cd: $data.workErrors.employeeCount
+  }, $data.workErrors.employeeCount ? {
+    ce: common_vendor.t($data.workErrors.employeeCount)
+  } : {}, {
+    cf: $data.workErrors.department ? 1 : "",
+    cg: $data.workForm.department,
+    ch: common_vendor.o(($event) => $data.workForm.department = $event.detail.value),
+    ci: $data.workErrors.department
+  }, $data.workErrors.department ? {
+    cj: common_vendor.t($data.workErrors.department)
+  } : {}, {
+    ck: $data.workErrors.position ? 1 : "",
+    cl: $data.workForm.position,
+    cm: common_vendor.o(($event) => $data.workForm.position = $event.detail.value),
+    cn: $data.workErrors.position
+  }, $data.workErrors.position ? {
+    co: common_vendor.t($data.workErrors.position)
+  } : {}, {
+    cp: $data.workForm.monthlySalary,
+    cq: common_vendor.o(($event) => $data.workForm.monthlySalary = $event.detail.value),
+    cr: $data.workErrors.monthlySalary
+  }, $data.workErrors.monthlySalary ? {
+    cs: common_vendor.t($data.workErrors.monthlySalary)
+  } : {}, {
+    ct: $data.workForm.supervisor,
+    cv: common_vendor.o(($event) => $data.workForm.supervisor = $event.detail.value),
+    cw: $data.workErrors.supervisor
+  }, $data.workErrors.supervisor ? {
+    cx: common_vendor.t($data.workErrors.supervisor)
+  } : {}, {
+    cy: $data.workForm.supervisorPhone,
+    cz: common_vendor.o(($event) => $data.workForm.supervisorPhone = $event.detail.value),
+    cA: $data.workErrors.supervisorPhone
+  }, $data.workErrors.supervisorPhone ? {
+    cB: common_vendor.t($data.workErrors.supervisorPhone)
   } : {}, {
-    be: common_vendor.t($data.workForm.startTime || "开始时间"),
-    bf: $data.workForm.startTime,
-    bg: common_vendor.o((...args) => $options.bindWorkStartTimeChange && $options.bindWorkStartTimeChange(...args)),
-    bh: common_vendor.t($data.workForm.endTime || "结束时间"),
-    bi: $data.workForm.endTime,
-    bj: common_vendor.o((...args) => $options.bindWorkEndTimeChange && $options.bindWorkEndTimeChange(...args)),
-    bk: $data.workForm.companyName,
-    bl: common_vendor.o(($event) => $data.workForm.companyName = $event.detail.value),
-    bm: $data.workForm.employeeCount,
-    bn: common_vendor.o(($event) => $data.workForm.employeeCount = $event.detail.value),
-    bo: $data.workForm.department,
-    bp: common_vendor.o(($event) => $data.workForm.department = $event.detail.value),
-    bq: $data.workForm.position,
-    br: common_vendor.o(($event) => $data.workForm.position = $event.detail.value),
-    bs: $data.workForm.monthlySalary,
-    bt: common_vendor.o(($event) => $data.workForm.monthlySalary = $event.detail.value),
-    bv: $data.workForm.supervisor,
-    bw: common_vendor.o(($event) => $data.workForm.supervisor = $event.detail.value),
-    bx: $data.workForm.supervisorPhone,
-    by: common_vendor.o(($event) => $data.workForm.supervisorPhone = $event.detail.value),
-    bz: common_vendor.t($data.isEditingWork ? "✓" : "+"),
-    bA: common_vendor.o((...args) => $options.saveWork && $options.saveWork(...args)),
-    bB: common_vendor.t($data.isEditingWork ? "保存修改" : "添加工作经历")
+    cC: common_vendor.t($data.isEditingWork ? "✓" : "+"),
+    cD: common_vendor.o((...args) => $options.saveWork && $options.saveWork(...args)),
+    cE: common_vendor.t($data.isEditingWork ? "保存修改" : "添加工作经历")
   }) : {}) : {}, {
-    bC: $options.showPrevButton
+    cF: $options.showPrevButton
   }, $options.showPrevButton ? {
-    bD: common_vendor.o((...args) => $options.prevStep && $options.prevStep(...args))
+    cG: common_vendor.o((...args) => $options.prevStep && $options.prevStep(...args))
   } : {}, {
-    bE: $options.showNextButton
+    cH: $options.showNextButton
   }, $options.showNextButton ? {
-    bF: common_vendor.o((...args) => $options.nextStep && $options.nextStep(...args))
+    cI: common_vendor.o((...args) => $options.nextStep && $options.nextStep(...args))
   } : {}, {
-    bG: $options.showSubmitButton
+    cJ: $options.showSubmitButton
   }, $options.showSubmitButton ? {
-    bH: common_vendor.o((...args) => $options.submitForm && $options.submitForm(...args))
+    cK: common_vendor.o((...args) => $options.submitForm && $options.submitForm(...args))
   } : {});
 }
 const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/Personal/Personal.wxml


+ 2 - 2
unpackage/dist/dev/mp-weixin/pages/camera/camera.js

@@ -709,7 +709,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
   } : $data.digitalHumanUrl ? {
     e: $data.digitalHumanUrl
   } : {
-    f: common_assets._imports_0$1
+    f: common_assets._imports_0
   }, {
     d: $data.digitalHumanUrl,
     g: common_vendor.f($data.questions, (question, qIndex, i0) => {
@@ -759,7 +759,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
   } : {}, {
     p: $data.interviewCompleted
   }, $data.interviewCompleted ? {
-    q: common_assets._imports_0$1,
+    q: common_assets._imports_0,
     r: common_vendor.o((...args) => $options.back && $options.back(...args))
   } : {}, {
     s: $data.loading

+ 4 - 5
unpackage/dist/dev/mp-weixin/pages/index/index.js

@@ -424,11 +424,10 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
       return {
         a: common_vendor.t(job.title),
         b: common_vendor.o(($event) => $options.viewJobDetail(job), index),
-        c: common_vendor.t(job.publish_date),
-        d: common_vendor.t(job.location),
-        e: index,
-        f: $data.selectedJobId === job.id ? 1 : "",
-        g: common_vendor.o(($event) => $options.selectJob(job), index)
+        c: common_vendor.t(job.location),
+        d: index,
+        e: $data.selectedJobId === job.id ? 1 : "",
+        f: common_vendor.o(($event) => $options.selectJob(job), index)
       };
     }),
     b: !$data.selectedJobId,

+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/index/index.wxml

@@ -1 +1 @@
-<view class="interview-container"><view class="job-list-container"><view class="job-list-title">可选职位列表</view><view class="job-list"><view wx:for="{{a}}" wx:for-item="job" wx:key="e" class="{{['job-item', job.f && 'job-selected']}}" bindtap="{{job.g}}"><view class="job-name">{{job.a}}</view><view class="job-actions"><button class="detail-btn" catchtap="{{job.b}}">查看详情</button></view><view class="job-details"><text class="job-salary">{{job.c}}</text><text class="job-location">{{job.d}}</text></view></view></view><button class="apply-btn" disabled="{{b}}" bindtap="{{c}}">申请面试</button></view></view>
+<view class="interview-container"><view class="job-list-container"><view class="job-list-title">可选职位列表</view><view class="job-list"><view wx:for="{{a}}" wx:for-item="job" wx:key="d" class="{{['job-item', job.e && 'job-selected']}}" bindtap="{{job.f}}"><view class="job-name">{{job.a}}</view><view class="job-actions"><button class="detail-btn" catchtap="{{job.b}}">查看详情</button></view><view class="job-details"><text class="job-salary"></text><text class="job-location">{{job.c}}</text></view></view></view><button class="apply-btn" disabled="{{b}}" bindtap="{{c}}">申请面试</button></view></view>

+ 59 - 91
unpackage/dist/dev/mp-weixin/pages/interview-question/interview-question.js

@@ -2048,13 +2048,7 @@ const _sfc_main = {
       this.showEndInterviewButton = false;
       if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === "") {
         console.error("无效的音频URL");
-        common_vendor.index.showToast({
-          title: "音频加载失败",
-          icon: "none",
-          duration: 2e3
-        });
-        this.isPlayingAiVoice = false;
-        this.showContinueQuestionOptions();
+        this.handleAudioPlaybackFailure();
         return;
       }
       try {
@@ -2064,84 +2058,55 @@ const _sfc_main = {
         this.aiAudioPlayer = common_vendor.index.createInnerAudioContext();
         this.aiAudioPlayer.autoplay = false;
         this.aiAudioPlayer.obeyMuteSwitch = false;
-        this.aiAudioPlayer.onPlay(() => {
-          console.log("AI语音开始播放");
-          common_vendor.index.showToast({
-            title: "正在播放面试官的回复",
-            icon: "none",
-            duration: 2e3
-          });
+        this.aiAudioPlayer.onCanplay(() => {
+          console.log("音频已加载完成,准备播放");
+          const duration = this.aiAudioPlayer.duration;
+          console.log("音频时长:", duration);
+          this.aiAudioPlayer.play();
         });
-        this.aiAudioPlayer.onEnded(() => {
-          console.log("AI语音播放结束");
-          this.isPlayingAiVoice = false;
-          this.currentSubtitle = "";
-          if (this.aiAudioPlayer) {
-            this.aiAudioPlayer.destroy();
-            this.aiAudioPlayer = null;
+        this.aiAudioPlayer.onTimeUpdate(() => {
+          const currentTime = this.aiAudioPlayer.currentTime;
+          const duration = this.aiAudioPlayer.duration;
+          console.log(`播放进度: ${currentTime}/${duration}`);
+          if (this.aiText) {
+            const textProgress = Math.floor(currentTime / duration * this.aiText.length);
+            this.currentSubtitle = this.aiText.substring(0, textProgress);
           }
-          this.showContinueQuestionOptions();
-          this.checkPendingNavigation();
+        });
+        this.aiAudioPlayer.onEnded(() => {
+          console.log("AI语音播放完成");
+          this.currentSubtitle = this.aiText;
+          setTimeout(() => {
+            this.isPlayingAiVoice = false;
+            this.currentSubtitle = "";
+            if (this.aiAudioPlayer) {
+              this.aiAudioPlayer.destroy();
+              this.aiAudioPlayer = null;
+            }
+            this.showContinueQuestionOptions();
+            this.checkPendingNavigation();
+          }, 2e3);
         });
         this.aiAudioPlayer.onError((err) => {
           console.error("AI语音播放错误:", err);
-          if (!this.hasTriedFallbackMethod) {
-            this.hasTriedFallbackMethod = true;
-            console.log("尝试使用备选方法播放音频");
-            this.tryFallbackAudioPlay();
-            return;
-          }
-          this.isPlayingAiVoice = false;
-          this.currentSubtitle = "";
-          if (this.aiAudioPlayer) {
-            this.aiAudioPlayer.destroy();
-            this.aiAudioPlayer = null;
-          }
-          common_vendor.index.showToast({
-            title: "音频播放失败,请查看文字回复",
-            icon: "none",
-            duration: 2e3
-          });
-          this.showContinueQuestionOptions();
-          this.checkPendingNavigation();
-        });
-        this.aiAudioPlayer.onCanplay(() => {
-          console.log("音频已准备好播放");
+          this.handleAudioPlaybackError(err);
         });
         this.aiAudioPlayer.src = this.aiVoiceUrl;
-        const playTimeout = setTimeout(() => {
-          if (this.isPlayingAiVoice && this.aiAudioPlayer) {
-            console.warn("音频播放超时,尝试备选方法");
-            this.tryFallbackAudioPlay();
-          }
-        }, 5e3);
-        setTimeout(() => {
-          if (this.aiAudioPlayer) {
-            this.aiAudioPlayer.play();
-            clearTimeout(playTimeout);
-          }
-        }, 300);
       } catch (e) {
         console.error("播放AI语音时发生错误:", e);
-        this.isPlayingAiVoice = false;
-        this.currentSubtitle = "";
-        if (this.aiAudioPlayer) {
-          try {
-            this.aiAudioPlayer.destroy();
-          } catch (destroyError) {
-            console.error("销毁音频播放器失败:", destroyError);
-          }
-          this.aiAudioPlayer = null;
-        }
-        common_vendor.index.showToast({
-          title: "音频播放失败,请查看文字回复",
-          icon: "none",
-          duration: 2e3
-        });
-        this.showContinueQuestionOptions();
-        this.checkPendingNavigation();
+        this.handleAudioPlaybackError(e);
       }
     },
+    // 添加新方法:处理音频播放错误
+    handleAudioPlaybackError(error) {
+      console.error("音频播放错误:", error);
+      if (!this.hasTriedFallbackMethod) {
+        this.hasTriedFallbackMethod = true;
+        this.tryFallbackAudioPlay();
+        return;
+      }
+      this.handleAudioPlaybackFailure();
+    },
     // 添加新方法:尝试备选音频播放方法
     tryFallbackAudioPlay() {
       console.log("使用备选方法播放音频:", this.aiVoiceUrl);
@@ -2552,31 +2517,34 @@ const _sfc_main = {
     },
     // 添加新方法:检查是否有待处理的自动跳转
     checkPendingNavigation() {
-      if (this.pendingAutoNavigation && !this.isPlayingAiVoice && !this.isUploading) {
-        console.log("所有处理已完成,执行自动跳转");
+      if (this.pendingAutoNavigation && !this.isPlayingAiVoice && !this.isUploading && !this.currentSubtitle) {
+        console.log("所有处理已完成,准备跳转");
         this.pendingAutoNavigation = false;
         setTimeout(() => {
           this.navigateToNextPage();
-        }, 2e3);
+        }, 1e3);
       }
     },
     // 添加新方法:显示文本回复
     displayTextResponse() {
       this.isPlayingAiVoice = true;
-      this.currentSubtitle = this.aiText;
-      common_vendor.index.showToast({
-        title: "显示面试官文字回复",
-        icon: "none",
-        duration: 2e3
-      });
-      const textLength = this.aiText.length;
-      const displayTime = Math.min(Math.max(textLength * 100, 5e3), 15e3);
-      setTimeout(() => {
-        this.isPlayingAiVoice = false;
-        this.currentSubtitle = "";
-        this.showContinueQuestionOptions();
-        this.checkPendingNavigation();
-      }, displayTime);
+      this.currentSubtitle = "";
+      const charDisplayTime = 200;
+      let currentIndex = 0;
+      const textInterval = setInterval(() => {
+        if (currentIndex <= this.aiText.length) {
+          this.currentSubtitle = this.aiText.substring(0, currentIndex);
+          currentIndex++;
+        } else {
+          clearInterval(textInterval);
+          setTimeout(() => {
+            this.isPlayingAiVoice = false;
+            this.currentSubtitle = "";
+            this.showContinueQuestionOptions();
+            this.checkPendingNavigation();
+          }, 3e3);
+        }
+      }, charDisplayTime);
     },
     // 添加新方法:检查不支持的音频格式
     checkUnsupportedAudioFormat(url) {

+ 4 - 6
unpackage/dist/dev/mp-weixin/pages/login/login.js

@@ -1,7 +1,6 @@
 "use strict";
 const common_vendor = require("../../common/vendor.js");
 const api_user = require("../../api/user.js");
-const common_assets = require("../../common/assets.js");
 const _sfc_main = {
   data() {
     return {
@@ -223,11 +222,10 @@ const _sfc_main = {
 };
 function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
   return {
-    a: common_assets._imports_0,
-    b: common_vendor.o((...args) => $options.handleLogin && $options.handleLogin(...args)),
-    c: $data.isAgreed,
-    d: common_vendor.o((...args) => $options.toggleAgreement && $options.toggleAgreement(...args)),
-    e: common_vendor.o((...args) => $options.navigateToAgreement && $options.navigateToAgreement(...args))
+    a: common_vendor.o((...args) => $options.handleLogin && $options.handleLogin(...args)),
+    b: $data.isAgreed,
+    c: common_vendor.o((...args) => $options.toggleAgreement && $options.toggleAgreement(...args)),
+    d: common_vendor.o((...args) => $options.navigateToAgreement && $options.navigateToAgreement(...args))
   };
 }
 const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);

+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/login/login.wxml

@@ -1 +1 @@
-<view class="login-container"><image class="login-image" src="{{a}}" mode="aspectFit"></image><view class="login-title">登录奇才,开始面试</view><button class="login-btn" bindtap="{{b}}">微信登录</button><view class="agreement"><checkbox checked="{{c}}" bindtap="{{d}}" color="#0039b3"/><text class="agreement-text"> 我已阅读并同意 <text class="agreement-link" bindtap="{{e}}">《用户协议》</text></text></view></view>
+<view class="login-container"><image class="login-image" src="https://data.qicai321.com/minlong/8baae825-6aa1-4783-9875-44d699f297cb.jpg" mode="aspectFit"></image><view class="login-title">奇才,只选对的</view><button class="login-btn" bindtap="{{a}}">微信登录</button><view class="agreement"><checkbox checked="{{b}}" bindtap="{{c}}" color="#0039b3"/><text class="agreement-text"> 我已阅读并同意 <text class="agreement-link" bindtap="{{d}}">《用户协议》</text></text></view></view>

+ 2 - 2
unpackage/dist/dev/mp-weixin/pages/login/login.wxss

@@ -9,14 +9,14 @@
   background-color: #FFF;
 }
 .login-image {
-  width: 100%;
+  width: 90%;
 
   margin-bottom: 40rpx;
 }
 .login-title {
   font-size: 36rpx;
   font-weight: bold;
-  margin-bottom: 60rpx;
+  margin-bottom: 200rpx;
   color: #333;
 }
 .login-btn {

+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/my/my.js

@@ -562,7 +562,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
   }, $data.userInfo.phone ? {
     e: common_vendor.t($options.formatPhone($data.userInfo.phone))
   } : {}) : {
-    f: common_assets._imports_0$1,
+    f: common_assets._imports_0,
     g: common_vendor.o((...args) => $options.goLogin && $options.goLogin(...args))
   }, {
     h: common_vendor.f($data.menuItems, (item, index, i0) => {

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor