<template>
|
<view class="page"><view class="page-header"><view class="safe-space" :style="'height:' + navTop + 'px'"></view><view class="nav-row" :style="'height:' + navHeight + 'px;padding-right:' + navRight + 'px'"><view class="back-button" @tap="goBack"><image src="/static/news-assets/arrow-left.svg" mode="aspectFit"></image></view><text class="nav-title">配偶信息</text><view class="capsule-space" :style="'width:' + navWidth + 'px'"></view></view></view>
|
<scroll-view class="form-scroll" scroll-y :show-scrollbar="false"><view class="form-content">
|
<view v-if="loading" class="state-box"><text>正在加载表单</text></view><view v-else-if="loadError" class="state-box"><text>表单加载失败</text><text class="retry" @tap="loadBenefit">重新加载</text></view>
|
<view v-else-if="!available" class="state-box"><text>{{unavailableReason}}</text></view>
|
<view v-else><text class="field-label">姓名</text><view class="input-box"><input v-model="form.name" maxlength="64" placeholder="请输入姓名" placeholder-class="input-placeholder" /></view>
|
<text class="field-label">手机号</text><view class="input-box"><input v-model="form.mobile" type="number" maxlength="11" placeholder="请输入手机号" placeholder-class="input-placeholder" /></view>
|
<text class="field-label">身份证号</text><view class="input-box"><input :value="form.idCard" type="idcard" maxlength="18" placeholder="请输入身份证号" placeholder-class="input-placeholder" @input="handleIdCardInput" /></view>
|
<text class="field-label">政治面貌</text><view class="input-box"><input v-model="form.politicalStatus" maxlength="64" placeholder="请输入政治面貌" placeholder-class="input-placeholder" /></view>
|
<text class="field-label">学历</text><picker class="field-picker" :range="educationOptions" :value="educationIndex" @change="changeEducation"><view class="picker-box"><text :class="form.education == '' ? 'picker-placeholder' : ''">{{form.education == '' ? '请选择' : form.education}}</text><view class="picker-arrow"></view></view></picker>
|
<text class="field-label">毕业院校及专业</text><view class="input-box"><input v-model="form.schoolMajor" maxlength="255" placeholder="请输入毕业院校及专业" placeholder-class="input-placeholder" /></view>
|
<text class="field-label">现工作单位及职务</text><view class="input-box"><input v-model="form.workUnit" maxlength="255" placeholder="请输入现工作单位及职务" placeholder-class="input-placeholder" /></view>
|
<text class="field-label">是否为机关事业单位在编人员</text><picker class="field-picker" :range="institutionOptions" :value="institutionIndex" @change="changeInstitution"><view class="picker-box"><text :class="form.inInstitution == '' ? 'picker-placeholder' : ''">{{form.inInstitution == '' ? '请选择' : form.inInstitution}}</text><view class="picker-arrow"></view></view></picker>
|
<text class="field-label">工作经历</text><view class="textarea-box"><textarea v-model="form.workExperience" maxlength="4000" placeholder="请输入工作经历" placeholder-class="input-placeholder"></textarea></view>
|
<view :class="isSubmitting ? 'submit-button submit-button-disabled' : 'submit-button'" hover-class="submit-button-active" @tap="submitForm"><text>{{isSubmitting ? '提交中' : '提交配偶信息'}}</text></view><view class="safe-bottom"></view>
|
</view>
|
</view></scroll-view>
|
</view>
|
</template>
|
|
<script setup lang="uts">
|
import { apiEnvironment } from '../../config/api.uts'
|
import { createIdempotencyKey } from '../../services/business.uts'
|
import { getSpouseEmploymentBenefit, submitSpouseEmploymentApplication } from '../../services/portal.uts'
|
import { getSession } from '../../services/session.uts'
|
import { safeBack } from '../../utils/navigation.uts'
|
const navTop = ref(28); const navHeight = ref(32); const navWidth = ref(88); const navRight = ref(10)
|
const serviceId = ref(''); const talentId = ref(''); const loading = ref(true); const loadError = ref(false); const available = ref(false); const unavailableReason = ref('该权益暂未开放'); const isSubmitting = ref(false); const submitKey = ref('')
|
const educationOptions = ref(['']); const institutionOptions = ref(['']); const educationIndex = ref(0); const institutionIndex = ref(0)
|
const form = ref({ name: '', mobile: '', idCard: '', politicalStatus: '', education: '', schoolMajor: '', workUnit: '', inInstitution: '', workExperience: '' })
|
const normalizeIdCard = (value: string): string => {
|
const raw = value.toUpperCase().replace(/[^0-9X]/g, '')
|
const xIndex = raw.indexOf('X')
|
if (xIndex >= 17) return raw.substring(0, xIndex).replace(/[^0-9]/g, '').slice(0, 17) + 'X'
|
return raw.replace(/[^0-9]/g, '').slice(0, 18)
|
}
|
onLoad((options: any) => { // #ifdef MP-WEIXIN
|
const capsule = uni.getMenuButtonBoundingClientRect(); const info = uni.getSystemInfoSync(); navTop.value = capsule.top; navHeight.value = capsule.height; navWidth.value = capsule.width; navRight.value = info.windowWidth - capsule.right
|
// #endif
|
serviceId.value = options != null && options['serviceId'] != null ? options['serviceId'] as string : ''; const session = getSession(); if (session != null && session.talentId != null) talentId.value = session.talentId as string; if (talentId.value == '' && apiEnvironment == 'development') talentId.value = '2'; submitKey.value = createIdempotencyKey('spouse-employment'); loadBenefit()
|
})
|
const loadBenefit = () => { if (serviceId.value == '') { loading.value = false; loadError.value = true; return }; loading.value = true; loadError.value = false; getSpouseEmploymentBenefit(serviceId.value, talentId.value, (data: any) => { available.value = data.available === true; unavailableReason.value = data.unavailableReason || unavailableReason.value; const config = data.formConfig || {}; educationOptions.value = config.educationOptions instanceof Array && config.educationOptions.length > 0 ? config.educationOptions : ['高中及以下', '大专', '本科', '硕士研究生', '博士研究生']; institutionOptions.value = config.institutionOptions instanceof Array && config.institutionOptions.length > 0 ? config.institutionOptions : ['是', '否']; loading.value = false }, () => { loading.value = false; loadError.value = true }) }
|
const goBack = () => safeBack('/pages/spouse-employment/spouse-employment?serviceId=' + encodeURIComponent(serviceId.value))
|
const changeEducation = (event: any) => { const index = parseInt(event.detail.value as string); educationIndex.value = index; const next = form.value; next.education = educationOptions.value[index]; form.value = next }
|
const changeInstitution = (event: any) => { const index = parseInt(event.detail.value as string); institutionIndex.value = index; const next = form.value; next.inInstitution = institutionOptions.value[index]; form.value = next }
|
const handleIdCardInput = (event: any) => { const normalized = normalizeIdCard(event.detail.value as string); const next = form.value; next.idCard = normalized; form.value = next; return normalized }
|
const required = (value: string, label: string): boolean => { if (value.trim() != '') return true; uni.showToast({ title: '请填写' + label, icon: 'none' }); return false }
|
const submitForm = () => {
|
if (isSubmitting.value) return
|
if (talentId.value == '') { uni.showToast({ title: '请登录后提交', icon: 'none' }); return }
|
if (!required(form.value.name, '姓名')) return
|
if (!(/^1\d{10}$/).test(form.value.mobile.trim())) { uni.showToast({ title: '请填写正确的手机号', icon: 'none' }); return }
|
if (!(/^[0-9]{17}[0-9X]$/).test(form.value.idCard.trim())) { uni.showToast({ title: '请填写正确的18位身份证号', icon: 'none' }); return }
|
if (!required(form.value.politicalStatus, '政治面貌') || !required(form.value.education, '学历') || !required(form.value.schoolMajor, '毕业院校及专业') || !required(form.value.workUnit, '现工作单位及职务') || !required(form.value.inInstitution, '是否在编') || !required(form.value.workExperience, '工作经历')) return
|
isSubmitting.value = true
|
submitSpouseEmploymentApplication(serviceId.value, { talentId: Number(talentId.value), name: form.value.name.trim(), mobile: form.value.mobile.trim(), idCard: form.value.idCard.trim(), politicalStatus: form.value.politicalStatus.trim(), education: form.value.education, schoolMajor: form.value.schoolMajor.trim(), workUnit: form.value.workUnit.trim(), inInstitution: form.value.inInstitution, workExperience: form.value.workExperience.trim() }, submitKey.value, (data: any) => { isSubmitting.value = false; uni.redirectTo({ url: '/pages/spouse-employment-success/spouse-employment-success?applicationId=' + encodeURIComponent(String(data.applicationId)) + '&applicationNo=' + encodeURIComponent(data.applicationNo || '') }) }, (error) => { isSubmitting.value = false; uni.showToast({ title: error.message, icon: 'none' }) })
|
}
|
</script>
|
|
<style>
|
.page { display:flex; width:100%; height:100vh; background-color:#F4F7FB; background-image:linear-gradient(180deg,#FFF0D7 0%,#FFF2DE 250rpx,#F4F7FB 510rpx); flex-direction:column; }.page-header { position:relative; z-index:10; flex-shrink:0; }.safe-space { height:28px; }.nav-row { display:flex; box-sizing:border-box; padding-left:20rpx; position:relative; flex-direction:row; align-items:center; justify-content:space-between; }.back-button { display:flex; width:70rpx; height:64rpx; margin-left:-4rpx; justify-content:center; align-items:center; }.back-button image { width:36rpx; height:36rpx; }.nav-title { position:absolute; left:50%; top:50%; color:#171B22; font-size:37rpx; line-height:48rpx; font-weight:700; transform:translate(-50%,-50%); white-space:nowrap; }.capsule-space { height:100%; flex-shrink:0; }.form-scroll { min-height:0; flex:1; }.form-content { padding:55rpx 34rpx 0; }.field-label { display:block; margin-left:5rpx; color:#74808F; font-size:25rpx; line-height:36rpx; font-weight:600; }.field-label:not(:first-child) { margin-top:44rpx; }.input-box,.picker-box { display:flex; height:112rpx; margin-top:14rpx; box-sizing:border-box; padding:0 25rpx; border-radius:28rpx; background-color:#FFFFFF; flex-direction:row; align-items:center; }.input-box input { width:100%; color:#4E5867; font-size:28rpx; }.input-placeholder,.picker-placeholder { color:#C1C8D1; }.field-picker { display:block; }.picker-box { color:#4E5867; font-size:28rpx; justify-content:space-between; }.picker-arrow { width:14rpx; height:14rpx; margin-right:5rpx; border-right:3rpx solid #8E9AAA; border-bottom:3rpx solid #8E9AAA; flex-shrink:0; transform:rotate(45deg) translateY(-3rpx); }.textarea-box { height:272rpx; margin-top:14rpx; box-sizing:border-box; padding:22rpx 25rpx; border-radius:28rpx; background-color:#FFFFFF; }.textarea-box textarea { width:100%; height:100%; color:#4E5867; font-size:28rpx; line-height:42rpx; }.submit-button { display:flex; height:100rpx; margin:45rpx 4rpx 0; border-radius:51rpx; background-image:linear-gradient(90deg,#FF4E35,#FF8318); justify-content:center; align-items:center; }.submit-button-disabled { opacity:.62; }.submit-button text { color:#FFFFFF; font-size:29rpx; font-weight:700; }.submit-button-active { opacity:.8; transform:scale(.99); }.state-box { display:flex; min-height:400rpx; color:#8D96A5; font-size:28rpx; flex-direction:column; align-items:center; justify-content:center; }.retry { margin-top:24rpx; color:#FF7A27; }.safe-bottom { height:70rpx; height:calc(70rpx + env(safe-area-inset-bottom)); }
|
</style>
|