优化个人中心页面
This commit is contained in:
@@ -22,157 +22,180 @@
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<view class="content-one">
|
||||
<view>
|
||||
<view class="content-title">
|
||||
<view class="title-lf">
|
||||
<view class="lf-h1">请您完善求职名片</view>
|
||||
<view class="lf-text">个人信息仅用于推送优质内容</view>
|
||||
</view>
|
||||
<view class="title-ri">
|
||||
<text style="color: #256bfa">1</text>
|
||||
<text>/2</text>
|
||||
</view>
|
||||
<!-- 固定标题 -->
|
||||
<view class="content-title">
|
||||
<view class="title-lf">
|
||||
<view class="lf-h1">请您完善求职名片</view>
|
||||
<view class="lf-text">个人信息仅用于推送优质内容</view>
|
||||
</view>
|
||||
<view class="content-input" :class="{ 'input-error': nameError }">
|
||||
<view class="input-titile">姓名</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.name"
|
||||
maxlength="18"
|
||||
placeholder="请输入姓名"
|
||||
@input="validateName"
|
||||
/>
|
||||
<view v-if="nameError" class="error-message">{{ nameError }}</view>
|
||||
<view class="title-ri">
|
||||
<text style="color: #256bfa">1</text>
|
||||
<text>/2</text>
|
||||
</view>
|
||||
<view class="content-sex" :class="{ 'input-error': sexError }">
|
||||
<view class="sex-titile">性别</view>
|
||||
<view class="sext-ri">
|
||||
<view
|
||||
class="sext-box"
|
||||
:class="{ 'sext-boxactive': fromValue.sex === 0 }"
|
||||
@click="changeSex(0)"
|
||||
>
|
||||
男
|
||||
</view>
|
||||
<view
|
||||
class="sext-box"
|
||||
:class="{ 'sext-boxactive': fromValue.sex === 1 }"
|
||||
@click="changeSex(1)"
|
||||
>
|
||||
女
|
||||
</view>
|
||||
<!-- 可滚动内容区域 -->
|
||||
<scroll-view class="scroll-content" scroll-y>
|
||||
<view class="scroll-inner">
|
||||
<view class="content-input" :class="{ 'input-error': nameError }">
|
||||
<view class="input-titile">姓名</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.name"
|
||||
maxlength="18"
|
||||
placeholder="请输入姓名"
|
||||
@input="validateName"
|
||||
/>
|
||||
<view v-if="nameError" class="error-message">{{ nameError }}</view>
|
||||
</view>
|
||||
<view class="content-input" :class="{ 'input-error': passwordError }">
|
||||
<view class="input-titile">密码</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.ytjPassword"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
maxlength="8"
|
||||
@input="validatePassword"
|
||||
/>
|
||||
<view v-if="passwordError" class="error-message">{{ passwordError }}</view>
|
||||
<view v-if="fromValue.ytjPassword && !passwordError" class="success-message">✓ 密码格式正确</view>
|
||||
</view>
|
||||
<view class="content-sex" :class="{ 'input-error': sexError }">
|
||||
<view class="sex-titile">性别</view>
|
||||
<view class="sext-ri">
|
||||
<view
|
||||
class="sext-box"
|
||||
:class="{ 'sext-boxactive': fromValue.sex === 0 }"
|
||||
@click="changeSex(0)"
|
||||
>
|
||||
男
|
||||
</view>
|
||||
<view
|
||||
class="sext-box"
|
||||
:class="{ 'sext-boxactive': fromValue.sex === 1 }"
|
||||
@click="changeSex(1)"
|
||||
>
|
||||
女
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="sexError" class="error-message">{{ sexError }}</view>
|
||||
<view class="content-input" :class="{ 'input-error': ageError }">
|
||||
<view class="input-titile">年龄</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.age"
|
||||
maxlength="3"
|
||||
placeholder="请输入年龄"
|
||||
@input="validateAge"
|
||||
/>
|
||||
<view v-if="ageError" class="error-message">{{ ageError }}</view>
|
||||
</view>
|
||||
<view class="content-input" :class="{ 'input-error': experienceError }" @click="changeExperience">
|
||||
<view class="input-titile">工作经验</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.workExperience"
|
||||
disabled
|
||||
placeholder="请选择您的工作经验"
|
||||
/>
|
||||
<view v-if="experienceError" class="error-message">{{ experienceError }}</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeEducation">
|
||||
<view class="input-titile">学历</view>
|
||||
<input class="input-con" v-model="state.educationText" disabled placeholder="本科" />
|
||||
</view>
|
||||
<view class="content-input" :class="{ 'input-error': idCardError }">
|
||||
<view class="input-titile">身份证</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.idCard"
|
||||
maxlength="18"
|
||||
placeholder="请输入身份证号码"
|
||||
@input="validateIdCard"
|
||||
/>
|
||||
<view v-if="idCardError" class="error-message">{{ idCardError }}</view>
|
||||
<view v-if="fromValue.idCard && !idCardError" class="success-message">✓ 身份证格式正确</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="sexError" class="error-message">{{ sexError }}</view>
|
||||
<view class="content-input" :class="{ 'input-error': ageError }">
|
||||
<view class="input-titile">年龄</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.age"
|
||||
maxlength="3"
|
||||
placeholder="请输入年龄"
|
||||
@input="validateAge"
|
||||
/>
|
||||
<view v-if="ageError" class="error-message">{{ ageError }}</view>
|
||||
</view>
|
||||
<view class="content-input" :class="{ 'input-error': experienceError }" @click="changeExperience">
|
||||
<view class="input-titile">工作经验</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.workExperience"
|
||||
disabled
|
||||
placeholder="请选择您的工作经验"
|
||||
/>
|
||||
<view v-if="experienceError" class="error-message">{{ experienceError }}</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeEducation">
|
||||
<view class="input-titile">学历</view>
|
||||
<input class="input-con" v-model="state.educationText" disabled placeholder="本科" />
|
||||
</view>
|
||||
<view class="content-input" :class="{ 'input-error': idCardError }">
|
||||
<view class="input-titile">身份证</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.idCard"
|
||||
maxlength="18"
|
||||
placeholder="请输入身份证号码"
|
||||
@input="validateIdCard"
|
||||
/>
|
||||
<view v-if="idCardError" class="error-message">{{ idCardError }}</view>
|
||||
<view v-if="fromValue.idCard && !idCardError" class="success-message">✓ 身份证格式正确</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="next-btn" @tap="nextStep">下一步</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- 固定按钮 -->
|
||||
<view class="next-btn" @tap="nextStep">下一步</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<view class="content-one">
|
||||
<view>
|
||||
<view class="content-title">
|
||||
<view class="title-lf">
|
||||
<view class="lf-h1">请您完善求职名片</view>
|
||||
<view class="lf-text">个人信息仅用于推送优质内容</view>
|
||||
</view>
|
||||
<view class="title-ri">
|
||||
<text style="color: #256bfa">2</text>
|
||||
<text>/2</text>
|
||||
</view>
|
||||
<!-- 固定标题 -->
|
||||
<view class="content-title">
|
||||
<view class="title-lf">
|
||||
<view class="lf-h1">请您完善求职名片</view>
|
||||
<view class="lf-text">个人信息仅用于推送优质内容</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeArea">
|
||||
<view class="input-titile">求职区域</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.areaText"
|
||||
disabled
|
||||
placeholder="请选择您的求职区域"
|
||||
/>
|
||||
</view>
|
||||
<view class="content-input" @click="changeJobs">
|
||||
<view class="input-titile">求职岗位</view>
|
||||
<input
|
||||
class="input-con"
|
||||
disabled
|
||||
v-if="!state.jobsText.length"
|
||||
placeholder="请选择您的求职岗位"
|
||||
/>
|
||||
<view class="input-nx" @click="changeJobs" v-else>
|
||||
<view class="nx-item" v-for="item in state.jobsText">{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSkillLevel">
|
||||
<view class="input-titile">技能等级</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.skillLevelText"
|
||||
disabled
|
||||
placeholder="请选择您的技能等级"
|
||||
/>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSkills">
|
||||
<view class="input-titile">技能名称</view>
|
||||
<input
|
||||
class="input-con"
|
||||
disabled
|
||||
v-if="!state.skillsText.length"
|
||||
placeholder="请选择您的技能名称"
|
||||
/>
|
||||
<view class="input-nx" @click="changeSkills" v-else>
|
||||
<view class="nx-item" v-for="(item, index) in state.skillsText" :key="index">{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSalay">
|
||||
<view class="input-titile">期望薪资</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.salayText"
|
||||
disabled
|
||||
placeholder="请选择您的期望薪资"
|
||||
/>
|
||||
<view class="title-ri">
|
||||
<text style="color: #256bfa">2</text>
|
||||
<text>/2</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="next-btn" @tap="complete">开启求职之旅</view>
|
||||
<!-- 可滚动内容区域 -->
|
||||
<scroll-view class="scroll-content" scroll-y>
|
||||
<view class="scroll-inner">
|
||||
<view class="content-input" @click="changeArea">
|
||||
<view class="input-titile">求职区域</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.areaText"
|
||||
disabled
|
||||
placeholder="请选择您的求职区域"
|
||||
/>
|
||||
</view>
|
||||
<view class="content-input" @click="changeJobs">
|
||||
<view class="input-titile">求职岗位</view>
|
||||
<input
|
||||
class="input-con"
|
||||
disabled
|
||||
v-if="!state.jobsText.length"
|
||||
placeholder="请选择您的求职岗位"
|
||||
/>
|
||||
<view class="input-nx" @click="changeJobs" v-else>
|
||||
<view class="nx-item" v-for="(item, index) in state.jobsText" :key="index">{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSkillLevel">
|
||||
<view class="input-titile">技能等级</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.skillLevelText"
|
||||
disabled
|
||||
placeholder="请选择您的技能等级"
|
||||
/>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSkills">
|
||||
<view class="input-titile">技能名称</view>
|
||||
<input
|
||||
class="input-con"
|
||||
disabled
|
||||
v-if="!state.skillsText.length"
|
||||
placeholder="请选择您的技能名称"
|
||||
/>
|
||||
<view class="input-nx" @click="changeSkills" v-else>
|
||||
<view class="nx-item" v-for="(item, index) in state.skillsText" :key="index">{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSalay">
|
||||
<view class="input-titile">期望薪资</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.salayText"
|
||||
disabled
|
||||
placeholder="请选择您的期望薪资"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</scroll-view>
|
||||
<!-- 固定按钮 -->
|
||||
<view class="next-btn" @tap="complete">开启求职之旅</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
@@ -184,13 +207,14 @@
|
||||
<script setup>
|
||||
import SelectJobs from '@/components/selectJobs/selectJobs.vue';
|
||||
import SelectPopup from '@/components/selectPopup/selectPopup.vue';
|
||||
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
||||
import { reactive, inject, watch, ref, onMounted, onUnmounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
import useDictStore from '@/stores/useDictStore';
|
||||
const { $api, navTo, config, IdCardValidator } = inject('globalFunction');
|
||||
const { loginSetToken, getUserResume } = useUserStore();
|
||||
const { getDictSelectOption, oneDictData } = useDictStore();
|
||||
const dictStore = useDictStore();
|
||||
const { getDictSelectOption, oneDictData, complete: dictComplete, getDictData } = dictStore;
|
||||
|
||||
// #ifdef H5
|
||||
const injectedOpenSelectPopup = inject('openSelectPopup', null);
|
||||
@@ -242,6 +266,7 @@ const fromValue = reactive({
|
||||
age: '',
|
||||
skillLevel: '',
|
||||
skills: '',
|
||||
ytjPassword: '',
|
||||
});
|
||||
|
||||
// 输入校验相关
|
||||
@@ -250,9 +275,73 @@ const nameError = ref('');
|
||||
const ageError = ref('');
|
||||
const sexError = ref('');
|
||||
const experienceError = ref('');
|
||||
const passwordError = ref('');
|
||||
|
||||
onLoad((parmas) => {
|
||||
getTreeselect();
|
||||
// 初始化学历显示文本
|
||||
initEducationText();
|
||||
});
|
||||
|
||||
// 初始化学历显示文本
|
||||
function initEducationText() {
|
||||
// 等待字典数据加载完成
|
||||
const checkDictData = () => {
|
||||
if (complete.value && dictStore.state.education && dictStore.state.education.length > 0) {
|
||||
// 字典数据已加载,设置学历显示文本
|
||||
if (fromValue.education) {
|
||||
const educationValue = Number(fromValue.education);
|
||||
state.educationText = dictStore.dictLabel('education', educationValue);
|
||||
}
|
||||
} else {
|
||||
// 如果字典数据未加载,等待一段时间后重试
|
||||
setTimeout(() => {
|
||||
if (complete.value && dictStore.state.education && dictStore.state.education.length > 0) {
|
||||
if (fromValue.education) {
|
||||
const educationValue = Number(fromValue.education);
|
||||
state.educationText = dictStore.dictLabel('education', educationValue);
|
||||
}
|
||||
} else {
|
||||
// 如果还是未加载,尝试加载字典数据
|
||||
getDictSelectOption('education').then((data) => {
|
||||
dictStore.state.education = data;
|
||||
if (fromValue.education) {
|
||||
const educationValue = Number(fromValue.education);
|
||||
state.educationText = dictStore.dictLabel('education', educationValue);
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.error('加载学历字典数据失败:', error);
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
checkDictData();
|
||||
}
|
||||
|
||||
// 技能选择回调函数
|
||||
const handleSkillSelected = (skills) => {
|
||||
if (Array.isArray(skills) && skills.length > 0) {
|
||||
// 更新技能显示和值,技能字段值传name
|
||||
state.skillsText = skills;
|
||||
fromValue.skills = skills.join(',');
|
||||
} else {
|
||||
// 如果返回空数组,清空选择
|
||||
state.skillsText = [];
|
||||
fromValue.skills = '';
|
||||
}
|
||||
};
|
||||
|
||||
// 监听页面显示,接收从技能查询页面返回的数据
|
||||
onShow(() => {
|
||||
// 通过事件总线接收技能选择结果
|
||||
uni.$on('skillSelected', handleSkillSelected);
|
||||
});
|
||||
|
||||
// 页面卸载时移除事件监听
|
||||
onUnmounted(() => {
|
||||
uni.$off('skillSelected', handleSkillSelected);
|
||||
});
|
||||
|
||||
onMounted(() => {});
|
||||
@@ -300,15 +389,72 @@ function validateIdCard() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用身份证校验器进行校验
|
||||
const result = IdCardValidator.validate(idCard);
|
||||
|
||||
if (result.valid) {
|
||||
idCardError.value = '';
|
||||
// 检查IdCardValidator是否存在,如果不存在提供简单的替代验证
|
||||
if (IdCardValidator && typeof IdCardValidator.validate === 'function') {
|
||||
const result = IdCardValidator.validate(idCard);
|
||||
if (result.valid) {
|
||||
idCardError.value = '';
|
||||
} else {
|
||||
idCardError.value = result.message;
|
||||
}
|
||||
} else {
|
||||
idCardError.value = result.message;
|
||||
// 简单的身份证验证规则:18位,最后一位可以是X
|
||||
const idCardRegex = /(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||||
if (idCardRegex.test(idCard)) {
|
||||
idCardError.value = '';
|
||||
} else {
|
||||
idCardError.value = '身份证号码格式不正确';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 密码实时校验
|
||||
function validatePassword() {
|
||||
const password = (fromValue.ytjPassword || '').trim();
|
||||
|
||||
// 如果为空,清除错误信息
|
||||
if (!password) {
|
||||
passwordError.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验规则:长度8位,包含大小写字母和数字,至少各有一个
|
||||
if (password.length !== 8) {
|
||||
passwordError.value = '密码长度必须为8位';
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否包含大写字母
|
||||
const hasUpperCase = /[A-Z]/.test(password);
|
||||
// 检查是否包含小写字母
|
||||
const hasLowerCase = /[a-z]/.test(password);
|
||||
// 检查是否包含数字
|
||||
const hasNumber = /[0-9]/.test(password);
|
||||
|
||||
if (!hasUpperCase) {
|
||||
passwordError.value = '密码必须包含至少一个大写字母';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasLowerCase) {
|
||||
passwordError.value = '密码必须包含至少一个小写字母';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasNumber) {
|
||||
passwordError.value = '密码必须包含至少一个数字';
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否只包含字母和数字
|
||||
if (!/^[A-Za-z0-9]+$/.test(password)) {
|
||||
passwordError.value = '密码只能包含大小写字母和数字';
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验通过
|
||||
passwordError.value = '';
|
||||
}
|
||||
function changeExperience() {
|
||||
openSelectPopup({
|
||||
title: '工作经验',
|
||||
@@ -327,13 +473,51 @@ function changeExperience() {
|
||||
});
|
||||
}
|
||||
|
||||
function changeEducation() {
|
||||
async function changeEducation() {
|
||||
// 确保字典数据已加载
|
||||
if (!complete.value || !dictStore.state.education || dictStore.state.education.length === 0) {
|
||||
// 如果字典数据未加载,先加载数据
|
||||
try {
|
||||
await getDictSelectOption('education').then((data) => {
|
||||
dictStore.state.education = data;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('加载学历字典数据失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 等待数据加载完成后再获取数据
|
||||
let educationData = oneDictData('education');
|
||||
|
||||
// 如果数据还是为空,等待一下再试
|
||||
if (!educationData || educationData.length === 0) {
|
||||
// 使用 nextTick 确保数据已渲染
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
educationData = oneDictData('education');
|
||||
if (!educationData || educationData.length === 0) {
|
||||
$api.msg('学历数据加载中,请稍后再试');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 将当前学历值转换为数字类型,用于查找默认索引
|
||||
const currentEducation = fromValue.education ? Number(fromValue.education) : null;
|
||||
// 查找当前学历在数据中的索引
|
||||
let defaultIndex = [0];
|
||||
if (currentEducation !== null && educationData && educationData.length > 0) {
|
||||
const index = educationData.findIndex(item => Number(item.value) === currentEducation);
|
||||
if (index >= 0) {
|
||||
defaultIndex = [index];
|
||||
}
|
||||
}
|
||||
|
||||
openSelectPopup({
|
||||
title: '学历',
|
||||
maskClick: true,
|
||||
data: [oneDictData('education')],
|
||||
data: [educationData],
|
||||
defaultIndex: defaultIndex,
|
||||
success: (_, [value]) => {
|
||||
fromValue.area = value.value;
|
||||
fromValue.education = String(value.value); // 确保存储为字符串
|
||||
state.educationText = value.label;
|
||||
},
|
||||
});
|
||||
@@ -405,93 +589,12 @@ function changeSkillLevel() {
|
||||
});
|
||||
}
|
||||
|
||||
// 技能名称选择
|
||||
// 技能名称选择 - 跳转到模糊查询页面
|
||||
function changeSkills() {
|
||||
const skills = [
|
||||
// 前端开发
|
||||
{ label: 'HTML', value: 'html' },
|
||||
{ label: 'CSS', value: 'css' },
|
||||
{ label: 'JavaScript', value: 'javascript' },
|
||||
{ label: 'TypeScript', value: 'typescript' },
|
||||
{ label: 'React', value: 'react' },
|
||||
{ label: 'Vue', value: 'vue' },
|
||||
{ label: 'Angular', value: 'angular' },
|
||||
{ label: 'jQuery', value: 'jquery' },
|
||||
{ label: 'Bootstrap', value: 'bootstrap' },
|
||||
{ label: 'Sass/Less', value: 'sass' },
|
||||
{ label: 'Webpack', value: 'webpack' },
|
||||
{ label: 'Vite', value: 'vite' },
|
||||
|
||||
// 后端开发
|
||||
{ label: 'Java', value: 'java' },
|
||||
{ label: 'Python', value: 'python' },
|
||||
{ label: 'Node.js', value: 'nodejs' },
|
||||
{ label: 'PHP', value: 'php' },
|
||||
{ label: 'C#', value: 'csharp' },
|
||||
{ label: 'Go', value: 'go' },
|
||||
{ label: 'Ruby', value: 'ruby' },
|
||||
{ label: 'Spring Boot', value: 'springboot' },
|
||||
{ label: 'Django', value: 'django' },
|
||||
{ label: 'Express', value: 'express' },
|
||||
{ label: 'Laravel', value: 'laravel' },
|
||||
|
||||
// 数据库
|
||||
{ label: 'MySQL', value: 'mysql' },
|
||||
{ label: 'PostgreSQL', value: 'postgresql' },
|
||||
{ label: 'MongoDB', value: 'mongodb' },
|
||||
{ label: 'Redis', value: 'redis' },
|
||||
{ label: 'Oracle', value: 'oracle' },
|
||||
{ label: 'SQL Server', value: 'sqlserver' },
|
||||
|
||||
// 移动开发
|
||||
{ label: 'React Native', value: 'reactnative' },
|
||||
{ label: 'Flutter', value: 'flutter' },
|
||||
{ label: 'iOS开发', value: 'ios' },
|
||||
{ label: 'Android开发', value: 'android' },
|
||||
{ label: '微信小程序', value: 'miniprogram' },
|
||||
{ label: 'uni-app', value: 'uniapp' },
|
||||
|
||||
// 云计算与运维
|
||||
{ label: 'Docker', value: 'docker' },
|
||||
{ label: 'Kubernetes', value: 'kubernetes' },
|
||||
{ label: 'AWS', value: 'aws' },
|
||||
{ label: '阿里云', value: 'aliyun' },
|
||||
{ label: 'Linux', value: 'linux' },
|
||||
{ label: 'Nginx', value: 'nginx' },
|
||||
|
||||
// 设计工具
|
||||
{ label: 'Photoshop', value: 'photoshop' },
|
||||
{ label: 'Figma', value: 'figma' },
|
||||
{ label: 'Sketch', value: 'sketch' },
|
||||
{ label: 'Adobe XD', value: 'adobexd' },
|
||||
|
||||
// 其他技能
|
||||
{ label: 'Git', value: 'git' },
|
||||
{ label: 'Jenkins', value: 'jenkins' },
|
||||
{ label: 'Jira', value: 'jira' },
|
||||
{ label: '项目管理', value: 'projectmanagement' },
|
||||
{ label: '数据分析', value: 'dataanalysis' },
|
||||
{ label: '人工智能', value: 'ai' },
|
||||
{ label: '机器学习', value: 'machinelearning' }
|
||||
];
|
||||
|
||||
// 获取当前已选中的技能
|
||||
const currentSelectedValues = fromValue.skills ? fromValue.skills.split(',') : [];
|
||||
|
||||
openSelectPopup({
|
||||
title: '技能名称',
|
||||
maskClick: true,
|
||||
data: [skills],
|
||||
multiSelect: true,
|
||||
rowLabel: 'label',
|
||||
rowKey: 'value',
|
||||
defaultValues: currentSelectedValues,
|
||||
success: (selectedValues, selectedItems) => {
|
||||
const selectedSkills = selectedItems.map(item => item.value);
|
||||
const selectedLabels = selectedItems.map(item => item.label);
|
||||
fromValue.skills = selectedSkills.join(',');
|
||||
state.skillsText = selectedLabels;
|
||||
},
|
||||
// 将当前已选中的技能名称传递给查询页面
|
||||
const selectedSkills = state.skillsText || [];
|
||||
uni.navigateTo({
|
||||
url: `/pages/complete-info/skill-search?selected=${encodeURIComponent(JSON.stringify(selectedSkills))}`
|
||||
});
|
||||
}
|
||||
|
||||
@@ -500,6 +603,7 @@ function nextStep() {
|
||||
validateName();
|
||||
validateAge();
|
||||
validateIdCard();
|
||||
validatePassword();
|
||||
|
||||
if (fromValue.sex !== 0 && fromValue.sex !== 1) {
|
||||
sexError.value = '请选择性别';
|
||||
@@ -518,6 +622,16 @@ function nextStep() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 密码校验
|
||||
if (!fromValue.ytjPassword) {
|
||||
$api.msg('请输入密码');
|
||||
return;
|
||||
}
|
||||
if (passwordError.value) {
|
||||
$api.msg(passwordError.value);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查所有错误状态
|
||||
if (nameError.value) return;
|
||||
if (sexError.value) return;
|
||||
@@ -528,10 +642,23 @@ function nextStep() {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = IdCardValidator.validate(fromValue.idCard);
|
||||
if (!result.valid) {
|
||||
$api.msg(result.message);
|
||||
return;
|
||||
// 检查IdCardValidator是否存在,如果不存在提供简单的替代验证
|
||||
let isValid = false;
|
||||
if (IdCardValidator && typeof IdCardValidator.validate === 'function') {
|
||||
const result = IdCardValidator.validate(fromValue.idCard);
|
||||
isValid = result.valid;
|
||||
if (!isValid) {
|
||||
$api.msg(result.message);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 简单的身份证验证规则:18位,最后一位可以是X
|
||||
const idCardRegex = /(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||||
if (!idCardRegex.test(fromValue.idCard)) {
|
||||
$api.msg('身份证号码格式不正确');
|
||||
return;
|
||||
}
|
||||
isValid = true;
|
||||
}
|
||||
|
||||
tabCurrent.value += 1;
|
||||
@@ -579,8 +706,26 @@ function loginTest() {
|
||||
}
|
||||
|
||||
function complete() {
|
||||
const result = IdCardValidator.validate(fromValue.idCard);
|
||||
if (result.valid) {
|
||||
// 检查IdCardValidator是否存在,如果不存在提供简单的替代验证
|
||||
let isValid = false;
|
||||
if (IdCardValidator && typeof IdCardValidator.validate === 'function') {
|
||||
const result = IdCardValidator.validate(fromValue.idCard);
|
||||
isValid = result.valid;
|
||||
if (!isValid) {
|
||||
$api.msg('身份证号码格式不正确');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 简单的身份证验证规则:18位,最后一位可以是X
|
||||
const idCardRegex = /(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||||
if (!idCardRegex.test(fromValue.idCard)) {
|
||||
$api.msg('身份证号码格式不正确');
|
||||
return;
|
||||
}
|
||||
isValid = true;
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
// 构建 experiencesList 数组
|
||||
const experiencesList = [];
|
||||
if (fromValue.skills && fromValue.skillLevel) {
|
||||
@@ -608,7 +753,8 @@ function complete() {
|
||||
area: fromValue.area,
|
||||
jobTitleId: fromValue.jobTitleId,
|
||||
salaryMin: fromValue.salaryMin,
|
||||
salaryMax: fromValue.salaryMax
|
||||
salaryMax: fromValue.salaryMax,
|
||||
ytjPassword: fromValue.ytjPassword
|
||||
},
|
||||
experiencesList: experiencesList
|
||||
};
|
||||
@@ -739,16 +885,17 @@ function complete() {
|
||||
margin-top: 70rpx;
|
||||
text-align: center;
|
||||
.content-one
|
||||
padding: 60rpx 28rpx;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between
|
||||
height: calc(100% - 120rpx)
|
||||
height: 100%
|
||||
.content-title
|
||||
flex-shrink: 0
|
||||
padding: 60rpx 28rpx 0
|
||||
display: flex
|
||||
justify-content: space-between;
|
||||
align-items: center
|
||||
margin-bottom: 70rpx
|
||||
margin-bottom: 40rpx
|
||||
.title-lf
|
||||
font-size: 44rpx;
|
||||
color: #000000;
|
||||
@@ -841,9 +988,18 @@ function complete() {
|
||||
color: #256BFA
|
||||
background: rgba(37,107,250,0.1);
|
||||
border: 2rpx solid #256BFA;
|
||||
.scroll-content
|
||||
flex: 1
|
||||
overflow: hidden
|
||||
height: 0 // 关键:让flex布局正确计算高度
|
||||
.scroll-inner
|
||||
padding: 0 28rpx
|
||||
padding-bottom: 40rpx
|
||||
.next-btn
|
||||
width: 100%;
|
||||
flex-shrink: 0
|
||||
width: calc(100% - 56rpx);
|
||||
height: 90rpx;
|
||||
margin: 0 28rpx 40rpx;
|
||||
background: #256BFA;
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
font-weight: 500;
|
||||
|
||||
Reference in New Issue
Block a user