1058 lines
29 KiB
Vue
1058 lines
29 KiB
Vue
<template>
|
||
<view class="">
|
||
<up-navbar title="骑手注册" leftIcon="" placeholder>
|
||
</up-navbar>
|
||
<view class="page">
|
||
<up-form ref="riderForm" :model="form" :rules="rules" labelPosition="left" labelWidth="90">
|
||
<view class="section-title">基础信息</view>
|
||
|
||
<up-form-item label="真实姓名" prop="username" :required="true">
|
||
<up-input v-model="form.username" placeholder="请输入您的姓名" />
|
||
</up-form-item>
|
||
|
||
<up-form-item label="身份证号" prop="idNumber" :required="true">
|
||
<up-input v-model="form.idNumber" placeholder="数字开头18位号码" maxlength="18" />
|
||
</up-form-item>
|
||
|
||
<up-form-item label="生效日期" prop="idStartTime" :required="true">
|
||
<view class="expiry-row">
|
||
<up-input :disabled="true" v-model="form.idStartTime" placeholder="选择生效日期" maxlength="18" @click="startTimeShow = true" />
|
||
<up-datetime-picker v-model:show="startTimeShow" v-model="idStartTime" mode="date" placeholder="请选择身份证生效日期" @confirm="changeData($event, 'start')" />
|
||
</view>
|
||
</up-form-item>
|
||
|
||
<up-form-item label="失效日期" prop="idEndTime" :required="true">
|
||
<view class="expiry-row">
|
||
<up-radio-group v-model="form.idValidType" direction="horizontal">
|
||
<up-radio :name="1" label="长期有效"></up-radio>
|
||
<up-radio :name="2" label="选择失效日期"></up-radio>
|
||
</up-radio-group>
|
||
<up-input v-if="form.idValidType === 2" :disabled="true" v-model="form.idEndTime" placeholder="选择失效日期" maxlength="18" @click="endTimeShow = true" />
|
||
<up-datetime-picker v-model:show="endTimeShow" v-model="idEndTime" mode="date"
|
||
placeholder="选择失效日期" @confirm="changeData($event, 'end')" />
|
||
</view>
|
||
</up-form-item>
|
||
|
||
<up-form-item label="性别" prop="gender" :required="true">
|
||
<up-radio-group v-model="form.gender" direction="horizontal">
|
||
<up-radio :name="1" label="男"></up-radio>
|
||
<up-radio :name="2" label="女"></up-radio>
|
||
</up-radio-group>
|
||
</up-form-item>
|
||
|
||
<up-form-item label="紧急联系人姓名" prop="emergencyContactName" :required="true">
|
||
<up-input v-model="form.emergencyContactName" placeholder="请输入" />
|
||
</up-form-item>
|
||
|
||
<up-form-item label="紧急联系人手机" prop="emergencyContactPhone" :required="true">
|
||
<up-input v-model="form.emergencyContactPhone" placeholder="请输入" type="tel" maxlength="11" />
|
||
</up-form-item>
|
||
|
||
<up-form-item label="上传身份证正反面" prop="idImages" :required="true">
|
||
<view class="upload-row">
|
||
<view class="upload-box">
|
||
<up-upload :max-count="1" :show-file-list="false" @afterRead="onUploadFront">
|
||
<view class="upload-placeholder" v-if="!frontImage">
|
||
<up-icon name="+" />
|
||
</view>
|
||
<up-image v-else width="120" height="80" :src="frontImage" mode="aspectFill" />
|
||
</up-upload>
|
||
<text class="hint">人像面</text>
|
||
</view>
|
||
<view class="upload-box">
|
||
<up-upload :max-count="1" :show-file-list="false" @afterRead="onUploadBack">
|
||
<view class="upload-placeholder" v-if="!backImage">
|
||
<up-icon name="+" />
|
||
</view>
|
||
<up-image v-else width="120" height="80" :src="backImage" mode="aspectFill" />
|
||
</up-upload>
|
||
<text class="hint">国徽面</text>
|
||
</view>
|
||
</view>
|
||
</up-form-item>
|
||
|
||
<view class="section-title">接单选择</view>
|
||
<up-form-item label="职业身份" prop="occupationType" :required="true">
|
||
<up-radio-group v-model="form.occupationType" direction="horizontal">
|
||
<up-radio :name="1" label="在校学生"></up-radio>
|
||
<up-radio :name="2" label="社会人员/职工"></up-radio>
|
||
</up-radio-group>
|
||
</up-form-item>
|
||
|
||
<!-- 学生视图:兼职意愿、可兼职时段、健康证 -->
|
||
<template v-if="form.occupationType === 1">
|
||
<up-form-item label="兼职意愿" prop="employmentType" :required="true">
|
||
<up-input :disabled="true" v-model="partTimeLabel" placeholder="选择兼职意愿" maxlength="18" @click="employmentTypeShow = true" />
|
||
<up-picker v-model:show="employmentTypeShow" :columns="partTimeOptions" v-model="partTimeLabel"
|
||
@confirm="onPartTimeConfirm"></up-picker>
|
||
</up-form-item>
|
||
|
||
<up-form-item label="请选择可兼职时段" prop="partTimePeriods">
|
||
<view class="choose-row" @click="timeShow1 = true">
|
||
<text class="muted">{{ partTimePeriodsLabel }}</text>
|
||
<text class="status"
|
||
:class="{empty: form.partTimePeriods.length===0}">{{ form.partTimePeriods.length===0 ? '待完善 >' : '已完善' }}</text>
|
||
</view>
|
||
</up-form-item>
|
||
|
||
<up-popup :show="timeShow1" mode="bottom" @close="timeShow1 = false">
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<text>选择可兼职时段</text>
|
||
</view>
|
||
<view class="popup-body">
|
||
<!-- 网格:每行为一天,三段时段按钮可切换选中 -->
|
||
<view class="time-grid">
|
||
<view class="time-row" v-for="(day, dayIndex) in days" :key="dayIndex">
|
||
<view class="day-label">{{ day }}</view>
|
||
<view class="slots">
|
||
<view class="slot-btn" :class="{selected: isSlotSelected(dayIndex, 0)}"
|
||
@click="toggleSlot(dayIndex, 0)" key="m">08:00~13:00</view>
|
||
<view class="slot-btn" :class="{selected: isSlotSelected(dayIndex, 1)}"
|
||
@click="toggleSlot(dayIndex, 1)" key="a">13:00~17:30</view>
|
||
<view class="slot-btn" :class="{selected: isSlotSelected(dayIndex, 2)}"
|
||
@click="toggleSlot(dayIndex, 2)" key="e">17:00~22:30</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="popup-footer">
|
||
<up-button plain @click="onCancelTime">取消</up-button>
|
||
<up-button type="primary" @click="onSaveTime">保存</up-button>
|
||
</view>
|
||
</view>
|
||
</up-popup>
|
||
</template>
|
||
|
||
<!-- 社会人员/职工视图:类别、意向城市、健康证 -->
|
||
<template v-else>
|
||
<up-form-item label="类别" prop="category" :required="true">
|
||
<up-picker hasInput :columns="categoryOptions" @confirm="onCategoryConfirm">
|
||
<template #trigger>
|
||
<up-input readonly v-model="categoryLabel" placeholder="请选择类别" />
|
||
</template>
|
||
</up-picker>
|
||
</up-form-item>
|
||
|
||
<up-form-item label="意向城市" prop="city" :required="true">
|
||
<up-input readonly v-model="cityLabel" placeholder="请选择" @tap="regionShow = true" />
|
||
</up-form-item>
|
||
</template>
|
||
|
||
<!-- 健康证(学生/社会人员皆可上传) -->
|
||
<up-form-item label="健康证" prop="healthCert">
|
||
<view class="health-row" @click="openHealthPopup">
|
||
<view class="health-left">上传健康证</view>
|
||
<view class="health-right">
|
||
<up-icon name="arrow-right" color="#6c6c6c" size="21"></up-icon>
|
||
</view>
|
||
</view>
|
||
</up-form-item>
|
||
|
||
<view class="submit-row">
|
||
<up-button type="primary" @click="onSubmit">保存并下一步,完善工资结算信息</up-button>
|
||
</view>
|
||
</up-form>
|
||
</view>
|
||
|
||
<!-- 健康证信息弹框 -->
|
||
<up-popup :show="popupShow" mode="bottom" @close="onCancelHealth" :round="16" safeAreaInsetBottom>
|
||
<view class="health-popup">
|
||
<view class="health-popup-header">
|
||
<text class="title">上传健康证</text>
|
||
</view>
|
||
<view class="health-popup-body">
|
||
<view class="field-row">
|
||
<text class="label">编号:</text>
|
||
<up-input v-model="healthNumber" placeholder="请输入健康证编号" class="field-input" />
|
||
</view>
|
||
<view class="field-row">
|
||
<text class="label">类别:</text>
|
||
<up-input v-model="healthCategory" placeholder="请输入健康证类别" class="field-input" />
|
||
</view>
|
||
<view class="field-row date-row">
|
||
<text class="label">有效日期:</text>
|
||
<up-datetime-picker hasInput v-model="healthValidStart" mode="date" placeholder="年/月/日"
|
||
class="date-input" />
|
||
<text class="dash"> — </text>
|
||
<up-datetime-picker hasInput v-model="healthValidEnd" mode="date" placeholder="年/月/日" class="date-input" />
|
||
</view>
|
||
|
||
<view class="upload-list">
|
||
<text class="upload-title">上传健康证:</text>
|
||
<view class="upload-row-inner">
|
||
<view v-for="(img, idx) in healthImages" :key="idx" class="upload-item">
|
||
<up-image :src="img" class="upload-thumb" mode="aspectFill" />
|
||
<view class="remove-btn" @click.stop="removeHealthImage(idx)">×</view>
|
||
</view>
|
||
<up-upload :max-count="1" :show-file-list="false" @afterRead="onUploadHealth">
|
||
<view class="upload-add" v-if="healthImages.length < 4">
|
||
<up-icon name="+" />
|
||
</view>
|
||
</up-upload>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="health-popup-footer">
|
||
<up-button plain @click="onCancelHealth">取消</up-button>
|
||
<up-button type="primary" class="save-btn" @click="onSaveHealth">保存</up-button>
|
||
</view>
|
||
</view>
|
||
</up-popup>
|
||
<su-region-picker :show="regionShow" @confirm="onRegionConfirm" @cancel="regionShow = false" />
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
reactive,
|
||
ref,
|
||
computed,
|
||
watch,
|
||
onBeforeMount
|
||
} from 'vue'
|
||
import AreaApi from '@/sheep/api/system/area';
|
||
import { baseUrl, apiPath } from '@/sheep/config';
|
||
// import SuRegionPicker from 'sheep/ui/su-region-picker/su-region-picker.vue'
|
||
import dayjs from 'dayjs';
|
||
|
||
const form = reactive({
|
||
username: '',
|
||
idNumber: '',
|
||
idStartTime: '',
|
||
idEndTime: '',
|
||
idValidType: 2, // 1=长期 2=非长期
|
||
gender: 1, // 1=男 2=女
|
||
emergencyContactName: '',
|
||
emergencyContactPhone: '',
|
||
idImages: [],
|
||
// 接单选择相关字段
|
||
occupationType: 1, // 1=在校学生 2=社会人员/职工
|
||
employmentType: 1, // 1=全职 2=兼职
|
||
partTimePeriods: [],
|
||
healthCertificateUrl: '',
|
||
// 健康证详情字段(弹窗保存到这里)
|
||
healthCertificateNo: '',
|
||
healthCertificateType: 1,
|
||
healthCertificateStartTime: '',
|
||
healthCertificateEndTime: '',
|
||
// 社会人员/职工视图字段
|
||
category: '',
|
||
city: '',
|
||
// 银行相关字段(用于下一个页面)
|
||
bankProvince: '',
|
||
bankProvinceCode: '',
|
||
bankCity: '',
|
||
bankCityCode: '',
|
||
bankDistrict: '',
|
||
bankDistrictCode: '',
|
||
bankCardNumber: '',
|
||
cardholderName: '',
|
||
bankAccountPhone: '',
|
||
code: '',
|
||
})
|
||
|
||
const startTimeShow = ref(false)
|
||
const endTimeShow = ref(false)
|
||
const employmentTypeShow = ref(false)
|
||
|
||
|
||
const idStartTime = ref('')
|
||
const idEndTime = ref('')
|
||
|
||
const timeShow1 = ref(false)
|
||
const partTimeOptions = reactive([
|
||
['长期(至少1学期)', '非长期(临时/偶尔兼职)']
|
||
])
|
||
const partTimeLabel = ref([])
|
||
const categoryOptions = [
|
||
['全职', '兼职']
|
||
]
|
||
const categoryLabel = ref([])
|
||
const cityOptions = [{
|
||
text: '请选择城市',
|
||
value: ''
|
||
},
|
||
{
|
||
text: '北京市',
|
||
value: 'beijing'
|
||
},
|
||
{
|
||
text: '上海市',
|
||
value: 'shanghai'
|
||
},
|
||
]
|
||
const cityLabel = ref('')
|
||
const regionShow = ref(false)
|
||
// 可选时段网格数据与选择状态
|
||
const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
||
const timeSlots = ['08:00~13:00', '13:00~17:30', '17:00~22:30']
|
||
// 使用二维布尔数组表示选择状态:selectedGrid[dayIndex][slotIndex] = true/false
|
||
const selectedGrid = reactive(Array.from({
|
||
length: days.length
|
||
}, () => [false, false, false]))
|
||
// 弹窗临时副本,打开时拷贝 selectedGrid 到 tempSelected,用于取消恢复
|
||
const tempSelected = reactive(Array.from({
|
||
length: days.length
|
||
}, () => [false, false, false]))
|
||
|
||
const popupShow = ref(false)
|
||
|
||
const changeData = (data, type) => {
|
||
if (type == 'start') {
|
||
form.idStartTime = dayjs(data.value).format('YYYY-MM-DD');
|
||
startTimeShow.value = false;
|
||
}else {
|
||
form.idEndTime = dayjs(data.value).format('YYYY-MM-DD');
|
||
endTimeShow.value = false;
|
||
}
|
||
console.log("this.form", form);
|
||
}
|
||
|
||
function isSlotSelected(dayIndex, slotIndex) {
|
||
return tempSelected[dayIndex][slotIndex]
|
||
}
|
||
|
||
function toggleSlot(dayIndex, slotIndex) {
|
||
tempSelected[dayIndex][slotIndex] = !tempSelected[dayIndex][slotIndex]
|
||
}
|
||
|
||
function onCancelTime() {
|
||
// 恢复原选中状态并关闭弹窗
|
||
for (let i = 0; i < days.length; i++) {
|
||
for (let j = 0; j < timeSlots.length; j++) {
|
||
tempSelected[i][j] = selectedGrid[i][j]
|
||
}
|
||
}
|
||
timeShow1.value = false
|
||
}
|
||
|
||
function onSaveTime() {
|
||
// 将 tempSelected 同步到 selectedGrid 和 form.partTimePeriods(保存为可读文本)
|
||
const selections = []
|
||
for (let i = 0; i < days.length; i++) {
|
||
for (let j = 0; j < timeSlots.length; j++) {
|
||
selectedGrid[i][j] = tempSelected[i][j]
|
||
if (tempSelected[i][j]) {
|
||
selections.push(`${days[i]} ${timeSlots[j]}`)
|
||
}
|
||
}
|
||
}
|
||
form.partTimePeriods = selections
|
||
timeShow1.value = false
|
||
}
|
||
|
||
// 打开弹窗时将当前选择拷贝到 tempSelected
|
||
watch(timeShow1, (val) => {
|
||
if (val) {
|
||
for (let i = 0; i < days.length; i++) {
|
||
for (let j = 0; j < timeSlots.length; j++) {
|
||
tempSelected[i][j] = selectedGrid[i][j]
|
||
}
|
||
}
|
||
}
|
||
})
|
||
|
||
const rules = {
|
||
username: [{
|
||
required: true,
|
||
message: '请输入真实姓名'
|
||
}],
|
||
idNumber: [{
|
||
required: true,
|
||
message: '请输入身份证号'
|
||
},
|
||
{
|
||
pattern: /^[0-9A-Za-z]{15,18}$/,
|
||
message: '请输入正确的身份证号'
|
||
},
|
||
],
|
||
idStartTime: [{
|
||
required: true,
|
||
message: '请选择生效日期'
|
||
}],
|
||
idEndTime: [{
|
||
validator(value) {
|
||
if (form.idValidType === 2 && !value) {
|
||
return false
|
||
}
|
||
return true
|
||
},
|
||
message: '请选择失效日期',
|
||
}, ],
|
||
gender: [{
|
||
required: true,
|
||
message: '请选择性别'
|
||
}],
|
||
emergencyContactName: [{
|
||
required: true,
|
||
message: '请输入紧急联系人姓名'
|
||
}],
|
||
emergencyContactPhone: [{
|
||
required: true,
|
||
message: '请输入紧急联系人手机'
|
||
},
|
||
{
|
||
pattern: /^1\d{10}$/,
|
||
message: '请输入正确的手机号码'
|
||
},
|
||
],
|
||
idImages: [{
|
||
required: true,
|
||
validator(value) {
|
||
console.log("form.idImages身份证:", form.idImages);
|
||
// 校验是否上传了正反面两张图片
|
||
if (!Array.isArray(form.idImages)) {
|
||
return false;
|
||
}
|
||
const frontUrl = form.idImages[0] || '';
|
||
const backUrl = form.idImages[1] || '';
|
||
if (!frontUrl || !backUrl) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
message: '请上传身份证正面和背面照片',
|
||
}],
|
||
}
|
||
|
||
const riderForm = ref(null)
|
||
const frontImage = ref('')
|
||
const backImage = ref('')
|
||
const healthCert = ref('')
|
||
// 健康证弹窗临时状态
|
||
const healthImages = reactive([])
|
||
const healthNumber = ref('')
|
||
const healthCategory = ref('')
|
||
const healthValidStart = ref('')
|
||
const healthValidEnd = ref('')
|
||
const partTimePeriodsLabel = computed(() => {
|
||
return form.partTimePeriods.length ? form.partTimePeriods.join('、') : ''
|
||
})
|
||
|
||
// 上传单个文件到 OSS
|
||
async function uploadFile(filePath) {
|
||
const token = uni.getStorageSync('token');
|
||
return new Promise((resolve, reject) => {
|
||
uni.uploadFile({
|
||
url: baseUrl + apiPath + '/app/file/uploadOss', // 上传接口地址
|
||
header: {
|
||
'Authorization': token
|
||
},
|
||
filePath: filePath,
|
||
name: 'file',
|
||
success: (res) => {
|
||
if (res.statusCode === 200) {
|
||
try {
|
||
const data = JSON.parse(res.data);
|
||
if (data.code === 0 && data.data) {
|
||
resolve(data.data);
|
||
} else {
|
||
console.error('上传失败:', data.msg);
|
||
resolve(null);
|
||
}
|
||
} catch (e) {
|
||
console.error('解析上传响应失败:', e);
|
||
resolve(null);
|
||
}
|
||
} else {
|
||
console.error('上传失败:', res.statusCode);
|
||
resolve(null);
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('上传请求失败:', err);
|
||
reject(err);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// 上传图片处理
|
||
async function handleUpload(file, isFront = true) {
|
||
const url = file?.url || file?.path || file?.thumb || '';
|
||
|
||
if (!url) {
|
||
console.error('未找到图片路径');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
uni.showLoading({ title: '上传中...' });
|
||
|
||
// 上传到 OSS
|
||
const uploadedUrl = await uploadFile(url);
|
||
|
||
uni.hideLoading();
|
||
|
||
if (uploadedUrl) {
|
||
if (isFront) {
|
||
frontImage.value = uploadedUrl;
|
||
form.idImages = [uploadedUrl, form.idImages[1] || ''];
|
||
} else {
|
||
backImage.value = uploadedUrl;
|
||
form.idImages = [form.idImages[0] || '', uploadedUrl];
|
||
}
|
||
} else {
|
||
uni.showToast({
|
||
title: '图片上传失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
console.error('上传图片异常:', error);
|
||
uni.showToast({
|
||
title: '上传失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
|
||
function onUploadFront(event) {
|
||
const { file } = Array.isArray(event) ? event[0] : (event.detail || event);
|
||
console.log("文件:", file);
|
||
handleUpload(file, true);
|
||
}
|
||
|
||
function onUploadBack(event) {
|
||
const { file } = Array.isArray(event) ? event[0] : (event.detail || event);
|
||
handleUpload(file, false);
|
||
}
|
||
|
||
// 健康证图片处理(支持多图)
|
||
async function handleUploadHealth(file) {
|
||
const url = file?.url || file?.path || file?.thumb || '';
|
||
|
||
if (!url) {
|
||
console.error('未找到图片路径');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
uni.showLoading({ title: '上传中...' });
|
||
|
||
// 上传到 OSS
|
||
const uploadedUrl = await uploadFile(url);
|
||
|
||
uni.hideLoading();
|
||
|
||
if (uploadedUrl) {
|
||
// 限制最多 4 张预览图
|
||
if (healthImages.length < 4) {
|
||
healthImages.push(uploadedUrl);
|
||
}
|
||
healthCert.value = uploadedUrl;
|
||
// 保存到表单字段
|
||
form.healthCertificateUrl = uploadedUrl;
|
||
} else {
|
||
uni.showToast({
|
||
title: '图片上传失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
console.error('上传图片异常:', error);
|
||
uni.showToast({
|
||
title: '上传失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
|
||
function onUploadHealth(event) {
|
||
const { file } = Array.isArray(event) ? event[0] : (event.detail || event);
|
||
handleUploadHealth(file);
|
||
}
|
||
|
||
function onPartTimeConfirm(selected) {
|
||
const first = Array.isArray(selected) ? selected[0] : selected
|
||
if (first && (first.value || first.text)) {
|
||
const text = first.text || first.value
|
||
// 兼职意愿转换:全职->1, 兼职->2
|
||
const intentMap = {
|
||
'长期(至少1学期)': 1,
|
||
'非长期(临时/偶尔兼职)': 2
|
||
}
|
||
form.employmentType = intentMap[text] || 1
|
||
partTimeLabel.value = text
|
||
employmentTypeShow.value = false
|
||
}
|
||
}
|
||
|
||
function onCategoryConfirm(selected) {
|
||
const first = Array.isArray(selected) ? selected[0] : selected
|
||
if (first && (first.value || first.text)) {
|
||
form.category = first.value || first.text
|
||
categoryLabel.value = first.text || first.value
|
||
}
|
||
}
|
||
|
||
function onCityConfirm(selected) {
|
||
const first = Array.isArray(selected) ? selected[0] : selected
|
||
if (first && (first.value || first.text)) {
|
||
form.city = first.value || first.text
|
||
cityLabel.value = first.text || first.value
|
||
}
|
||
}
|
||
|
||
function onRegionConfirm(result) {
|
||
// result: { province_name, province_id, city_name, city_id, district_name, district_id }
|
||
form.city = result
|
||
cityLabel.value = `${result.province_name || ''} ${result.city_name || ''} ${result.district_name || ''}`.trim()
|
||
regionShow.value = false
|
||
}
|
||
|
||
function openHealthPopup() {
|
||
// 从表单恢复到弹窗临时状态
|
||
healthImages.splice(0, healthImages.length)
|
||
if (form.healthCertificateUrl) {
|
||
healthImages.push(form.healthCertificateUrl)
|
||
}
|
||
healthNumber.value = form.healthCertificateNo || ''
|
||
healthCategory.value = form.healthCertificateType?.toString() || ''
|
||
healthValidStart.value = form.healthCertificateStartTime || ''
|
||
healthValidEnd.value = form.healthCertificateEndTime || ''
|
||
popupShow.value = true
|
||
}
|
||
|
||
function removeHealthImage(index) {
|
||
if (index >= 0 && index < healthImages.length) {
|
||
healthImages.splice(index, 1)
|
||
}
|
||
}
|
||
|
||
function onCancelHealth() {
|
||
// 直接关闭弹窗,放弃临时更改
|
||
popupShow.value = false
|
||
}
|
||
|
||
function onSaveHealth() {
|
||
// 保存弹窗数据回表单
|
||
form.healthCertificateUrl = healthImages.length ? healthImages[0] : ''
|
||
healthCert.value = form.healthCertificateUrl
|
||
form.healthCertificateNo = healthNumber.value
|
||
// 类别转换:食品卫生类->1, 医疗卫生类->2, 教育类->3
|
||
const categoryMap = {
|
||
'食品卫生类': 1,
|
||
'医疗卫生类': 2,
|
||
'教育类': 3
|
||
}
|
||
const categoryText = healthCategory.value.trim()
|
||
form.healthCertificateType = categoryMap[categoryText] || 1
|
||
form.healthCertificateStartTime = healthValidStart.value
|
||
form.healthCertificateEndTime = healthValidEnd.value
|
||
popupShow.value = false
|
||
}
|
||
|
||
async function onSubmit() {
|
||
console.log("form.idStartTime", form.idStartTime);
|
||
try {
|
||
await riderForm.value.validate()
|
||
console.log('提交表单', JSON.parse(JSON.stringify(form)))
|
||
|
||
// 构建提交给后端的数据(包含两个页面的字段)
|
||
const submitData = {
|
||
// 第一个页面的字段
|
||
username: form.username,
|
||
idNumber: form.idNumber,
|
||
idStartTime: form.idStartTime,
|
||
idEndTime: form.idEndTime,
|
||
idValidType: form.idValidType,
|
||
gender: form.gender,
|
||
emergencyContactName: form.emergencyContactName,
|
||
emergencyContactPhone: form.emergencyContactPhone,
|
||
idFrontUrl: form.idImages[0] || '',
|
||
idBackUrl: form.idImages[1] || '',
|
||
occupationType: form.occupationType,
|
||
employmentType: form.employmentType,
|
||
partTimePeriods: form.partTimePeriods,
|
||
healthCertificateUrl: form.healthCertificateUrl,
|
||
healthCertificateNo: form.healthCertificateNo,
|
||
healthCertificateType: form.healthCertificateType,
|
||
healthCertificateStartTime: form.healthCertificateStartTime,
|
||
healthCertificateEndTime: form.healthCertificateEndTime,
|
||
// 第二个页面的字段(先缓存空值,会在下个页面填充)
|
||
bankAccountPhone: form.bankAccountPhone || '',
|
||
bankCardNumber: form.bankCardNumber || '',
|
||
bankCity: form.bankCity || '',
|
||
bankCityCode: form.bankCityCode || '',
|
||
bankDistrict: form.bankDistrict || '',
|
||
bankDistrictCode: form.bankDistrictCode || '',
|
||
bankProvince: form.bankProvince || '',
|
||
bankProvinceCode: form.bankProvinceCode || '',
|
||
cardholderName: form.cardholderName || '',
|
||
code: form.code || '',
|
||
}
|
||
|
||
// 将注册信息临时存储,供结算页继续使用
|
||
try {
|
||
uni.setStorageSync('riderRegisterData', JSON.stringify(submitData))
|
||
} catch (err) {
|
||
console.warn('存储注册信息失败', err)
|
||
}
|
||
// 跳转到工资结算账户信息页面
|
||
uni.navigateTo({
|
||
url: '/pages/registered/accountInfo'
|
||
})
|
||
} catch (e) {
|
||
console.warn('表单校验未通过', e)
|
||
}
|
||
}
|
||
|
||
const rightClick = () => {
|
||
console.log('rightClick');
|
||
};
|
||
|
||
onBeforeMount(() => {
|
||
// 尝试从缓存恢复数据
|
||
try {
|
||
const saved = uni.getStorageSync('riderRegisterData') || null
|
||
if (saved) {
|
||
// 恢复表单数据
|
||
form.username = saved.username || ''
|
||
form.idNumber = saved.idNumber || ''
|
||
form.idStartTime = saved.idStartTime || ''
|
||
form.idEndTime = saved.idEndTime || ''
|
||
form.idValidType = saved.idValidType || 2
|
||
form.gender = saved.gender || 1
|
||
form.emergencyContactName = saved.emergencyContactName || ''
|
||
form.emergencyContactPhone = saved.emergencyContactPhone || ''
|
||
|
||
// 恢复身份证图片
|
||
if (saved.idFrontUrl) {
|
||
form.idImages[0] = saved.idFrontUrl
|
||
frontImage.value = saved.idFrontUrl
|
||
}
|
||
if (saved.idBackUrl) {
|
||
form.idImages[1] = saved.idBackUrl
|
||
backImage.value = saved.idBackUrl
|
||
}
|
||
|
||
form.occupationType = saved.occupationType || 1
|
||
form.employmentType = saved.employmentType || 1
|
||
form.partTimePeriods = saved.partTimePeriods || []
|
||
|
||
// 恢复健康证数据
|
||
form.healthCertificateUrl = saved.healthCertificateUrl || ''
|
||
form.healthCertificateNo = saved.healthCertificateNo || ''
|
||
form.healthCertificateType = saved.healthCertificateType || 1
|
||
form.healthCertificateStartTime = saved.healthCertificateStartTime || ''
|
||
form.healthCertificateEndTime = saved.healthCertificateEndTime || ''
|
||
}
|
||
} catch (err) {
|
||
console.warn('读取缓存数据失败', err)
|
||
}
|
||
|
||
if (!!uni.getStorageSync('areaData')) {
|
||
return;
|
||
}
|
||
// 提前加载省市区数据
|
||
AreaApi.getAreaTree().then((res) => {
|
||
if (res.code === 0) {
|
||
uni.setStorageSync('areaData', res.data);
|
||
}
|
||
});
|
||
});
|
||
|
||
// 监听表单数据变化,自动保存到缓存
|
||
watch(form, () => {
|
||
try {
|
||
uni.setStorageSync('riderRegisterData', {
|
||
username: form.username,
|
||
idNumber: form.idNumber,
|
||
idStartTime: form.idStartTime,
|
||
idEndTime: form.idEndTime,
|
||
idValidType: form.idValidType,
|
||
gender: form.gender,
|
||
emergencyContactName: form.emergencyContactName,
|
||
emergencyContactPhone: form.emergencyContactPhone,
|
||
idFrontUrl: form.idImages[0] || '',
|
||
idBackUrl: form.idImages[1] || '',
|
||
occupationType: form.occupationType,
|
||
employmentType: form.employmentType,
|
||
partTimePeriods: form.partTimePeriods,
|
||
healthCertificateUrl: form.healthCertificateUrl,
|
||
healthCertificateNo: form.healthCertificateNo,
|
||
healthCertificateType: form.healthCertificateType,
|
||
healthCertificateStartTime: form.healthCertificateStartTime,
|
||
healthCertificateEndTime: form.healthCertificateEndTime,
|
||
// 银行信息(如果已经在第二个页面填写了)
|
||
bankAccountPhone: form.bankAccountPhone || '',
|
||
bankCardNumber: form.bankCardNumber || '',
|
||
bankCity: form.bankCity || '',
|
||
bankCityCode: form.bankCityCode || '',
|
||
bankDistrict: form.bankDistrict || '',
|
||
bankDistrictCode: form.bankDistrictCode || '',
|
||
bankProvince: form.bankProvince || '',
|
||
bankProvinceCode: form.bankProvinceCode || '',
|
||
cardholderName: form.cardholderName || '',
|
||
code: form.code || '',
|
||
})
|
||
} catch (err) {
|
||
console.warn('保存缓存数据失败', err)
|
||
}
|
||
}, { deep: true })
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page {
|
||
padding: 38rpx;
|
||
background: #fff;
|
||
}
|
||
|
||
.section-title {
|
||
padding: 10px 0;
|
||
color: #666;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.expiry-row {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
}
|
||
|
||
.upload-row {
|
||
display: flex;
|
||
gap: 12px;
|
||
}
|
||
|
||
.upload-box {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.upload-placeholder {
|
||
width: 88px;
|
||
height: 60px;
|
||
border: 1px dashed #ddd;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.thumb {
|
||
width: 160rpx;
|
||
height: 120rpx;
|
||
border-radius: 5rpx;
|
||
}
|
||
|
||
.hint {
|
||
margin-top: 6px;
|
||
color: #999;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.submit-row {
|
||
margin-top: 20px;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
.time-grid {
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.time-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.day-label {
|
||
width: 90rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.slots {
|
||
display: flex;
|
||
gap: 10px;
|
||
flex: 1;
|
||
}
|
||
|
||
.slot-btn {
|
||
padding: 8px 12px;
|
||
border-radius: 6px;
|
||
background: #f5f5f5;
|
||
color: #333;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.slot-btn.selected {
|
||
background: #09aaff;
|
||
color: #fff;
|
||
}
|
||
|
||
.popup-footer {
|
||
display: flex;
|
||
gap: 10px;
|
||
padding: 12px;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.popup-content {
|
||
padding: 50rpx 20rpx 20rpx;
|
||
}
|
||
|
||
.popup-body {
|
||
padding: 10rpx 15rpx 20rpx;
|
||
}
|
||
|
||
/* 健康证相关样式 */
|
||
.health-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
width: 100%;
|
||
padding-right: 10rpx;
|
||
}
|
||
|
||
.health-left {
|
||
color: #333;
|
||
}
|
||
|
||
.health-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10rpx;
|
||
}
|
||
|
||
.health-thumbs {
|
||
display: flex;
|
||
gap: 10rpx;
|
||
align-items: center;
|
||
}
|
||
|
||
.health-thumb-wrap {
|
||
width: 88px;
|
||
height: 88px;
|
||
}
|
||
|
||
.health-thumb {
|
||
width: 88px;
|
||
height: 88px;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
.health-add {
|
||
width: 88px;
|
||
height: 88px;
|
||
border: 1px dashed #ddd;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 6px;
|
||
color: #999;
|
||
}
|
||
|
||
.health-popup {
|
||
padding: 30rpx 30rpx 30rpx;
|
||
background: #fff;
|
||
}
|
||
|
||
.health-popup-header .title {
|
||
font-weight: 700;
|
||
font-size: 32rpx;
|
||
text-align: center;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.health-popup-body {
|
||
padding: 10rpx 0 20rpx;
|
||
}
|
||
|
||
.field-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 38rpx;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.label {
|
||
width: 90rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.field-input {
|
||
flex: 1;
|
||
}
|
||
|
||
.date-row .date-input {
|
||
width: 35%;
|
||
}
|
||
|
||
.dash {
|
||
width: 10rpx;
|
||
text-align: center;
|
||
color: #999;
|
||
}
|
||
|
||
.upload-list {
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.upload-title {
|
||
color: #333;
|
||
margin-bottom: 8px;
|
||
display: block;
|
||
}
|
||
|
||
.upload-row-inner {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.upload-item {
|
||
position: relative;
|
||
width: 88px;
|
||
height: 88px;
|
||
}
|
||
|
||
.upload-thumb {
|
||
width: 88px;
|
||
height: 88px;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
.remove-btn {
|
||
position: absolute;
|
||
top: -6px;
|
||
right: -6px;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
color: #fff;
|
||
width: 24px;
|
||
height: 24px;
|
||
border-radius: 12px;
|
||
text-align: center;
|
||
line-height: 24px;
|
||
font-size: 18px;
|
||
}
|
||
|
||
.upload-add {
|
||
width: 88px;
|
||
height: 88px;
|
||
border: 1px dashed #ddd;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 6px;
|
||
color: #999;
|
||
}
|
||
|
||
.health-popup-footer {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding-top: 16px;
|
||
gap: 12px;
|
||
}
|
||
|
||
.save-btn {
|
||
width: 240rpx;
|
||
align-self: center;
|
||
}
|
||
</style> |