fjrcloud-community-app/pages/index/auth-form.vue

553 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 业主认证表单页 -->
<template>
<s-layout title="业主认证">
<view class="auth-page">
<scroll-view scroll-y class="form-scroll">
<!-- 小区名称 -->
<view class="form-item">
<text class="form-label">小区名称</text>
<view class="form-value">
<text class="value-text">融侨馨苑</text>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 序号楼号/单元/ -->
<view class="form-item form-row">
<text class="form-label">序号</text>
<view class="row-inputs">
<view class="col-item">
<input class="col-input" v-model="state.form.building" />
<text class="col-label">号楼</text>
</view>
<view class="col-item">
<input class="col-input" v-model="state.form.unit" />
<text class="col-label">单元</text>
</view>
<view class="col-item">
<input class="col-input" v-model="state.form.room" />
<text class="col-label">号</text>
</view>
</view>
</view>
<!-- 是否产权人 -->
<view class="form-item">
<text class="form-label">是否产权人</text>
<view class="checkbox-group">
<label class="checkbox-item" @tap="state.form.isOwner = true">
<view :class="['checkbox-box', { active: state.form.isOwner }]">
<text v-if="state.form.isOwner" class="check-mark">✓</text>
</view>
<text class="checkbox-text">是</text>
</label>
<label class="checkbox-item" @tap="state.form.isOwner = false">
<view :class="['checkbox-box', { active: !state.form.isOwner && state.form.isOwner !== null }]">
<text v-if="!state.form.isOwner && state.form.isOwner !== null" class="check-mark">✓</text>
</view>
<text class="checkbox-text">否</text>
</label>
</view>
</view>
<!-- 与产权人关系 -->
<view class="form-item">
<text class="form-label">与产权人关系</text>
<view class="form-value" @tap="showRelationPicker">
<text class="value-text placeholder-color">{{ state.form.relation || '请输入' }}</text>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 姓名 -->
<view class="form-item">
<text class="form-label">姓名</text>
<view class="form-value">
<input
v-model="state.form.name"
class="form-input"
placeholder="请输入姓名"
placeholder-class="placeholder"
placeholder-style="color: #333333"
/>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 手机号 -->
<view class="form-item">
<text class="form-label">手机号</text>
<view class="form-value">
<input
v-model="state.form.phone"
class="form-input"
type="number"
maxlength="11"
placeholder="请输入手机号"
placeholder-class="placeholder"
placeholder-style="color: #333333"
/>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 证件类型 -->
<view class="form-item">
<text class="form-label">证件类型</text>
<view class="form-value" @tap="showIdTypePicker">
<text class="value-text placeholder-color">{{ state.form.idType || '请选择证件类型' }}</text>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 证件号 -->
<view class="form-item">
<text class="form-label">证件号</text>
<view class="form-value">
<input
v-model="state.form.idNumber"
class="form-input"
placeholder="请输入证件号"
placeholder-class="placeholder"
placeholder-style="color: #333333"
/>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 性别 -->
<view class="form-item">
<text class="form-label">性别</text>
<view class="form-value" @tap="showGenderPicker">
<text class="value-text placeholder-color">{{ state.form.gender || '请选择' }}</text>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 出生日期 -->
<view class="form-item">
<text class="form-label">出生日期</text>
<view class="form-value" @click="triggerDatePicker">
<uni-datetime-picker
ref="datePickerRef"
v-model="state.form.birthday"
type="date"
:border="false"
@change="onDateChange"
class="form-date"
/>
<image class="arrow-icon" src="/static/img/right-icon-black.png" mode="aspectFit" />
</view>
</view>
<!-- 上传附件 -->
<view class="form-section-title">
<text>上传附件</text>
</view>
<view class="upload-area">
<view class="upload-btn" @tap="handleUpload">
<view class="upload-icon-wrapper">
<text class="upload-folder-icon">📁</text>
</view>
<text class="upload-text">选择文件</text>
</view>
</view>
</scroll-view>
<!-- 底部按钮 -->
<view class="bottom-btn-wrapper">
<button class="submit-btn" @tap="handleSubmit"></button>
</view>
</view>
</s-layout>
</template>
<script setup>
import { reactive, ref } from 'vue';
// 表单数据
const state = reactive({
form: {
community: '融侨馨苑',
building: '',
unit: '',
room: '',
isOwner: true,
relation: '',
name: '',
phone: '',
idType: '',
idNumber: '',
gender: '',
birthday: ''
}
});
// 显示关系选择器
const showRelationPicker = () => {
uni.showActionSheet({
itemList: ['本人', '配偶', '父母', '子女', '其他'],
success: (res) => {
const relations = ['本人', '配偶', '父母', '子女', '其他'];
state.form.relation = relations[res.tapIndex];
}
});
};
// 显示证件类型选择器
const showIdTypePicker = () => {
uni.showActionSheet({
itemList: ['身份证', '护照', '军官证', '港澳通行证'],
success: (res) => {
const types = ['身份证', '护照', '军官证', '港澳通行证'];
state.form.idType = types[res.tapIndex];
}
});
};
// 显示性别选择器
const showGenderPicker = () => {
uni.showActionSheet({
itemList: ['男', '女'],
success: (res) => {
state.form.gender = res.tapIndex === 0 ? '男' : '女';
}
});
};
// 日期选择回调
const onDateChange = (e) => {
console.log('选择的日期:', e);
};
// 点击整行触发日期选择器
const datePickerRef = ref(null);
const triggerDatePicker = () => {
if (datePickerRef.value) {
// uni-datetime-picker 内部有 show 方法可以打开弹窗
const picker = datePickerRef.value.$children?.[0] || datePickerRef.value;
if (picker.show) {
picker.show();
}
}
};
// 上传附件
const handleUpload = () => {
uni.chooseMessageFile({
count: 1,
type: 'file',
success: (res) => {
console.log('选择文件:', res.tempFiles[0]);
}
});
};
// 提交表单
const handleSubmit = () => {
console.log('提交表单:', state.form);
// 跳转到提交成功页
uni.redirectTo({
url: '/pages/index/auth-success'
});
};
</script>
<style lang="scss" scoped>
/* 页面容器 */
.auth-page {
background-color: #F5F5F5;
}
/* 表单滚动区域 */
.form-scroll {
height: calc(100vh - 176rpx - 250rpx);
padding-top: 20rpx;
}
/* 表单项 - 上下结构 */
.form-item {
background-color: #FFFFFF;
padding: 24rpx 32rpx;
display: flex;
flex-direction: column;
border-bottom: 1rpx solid #F0F0F0;
}
/* 标签文字 - 上方 */
.form-label {
font-size: 28rpx;
color: #333333;
font-weight: 500;
margin-bottom: 16rpx;
}
/* 值区域 - 下方 */
.form-value {
display: flex;
align-items: center;
.value-text {
font-size: 28rpx;
flex: 1;
// 已选中值:深色加粗
&:not(.placeholder-color) {
color: #222222;
font-weight: 600;
}
}
.placeholder-color {
color: #666666;
}
.form-input {
flex: 1;
font-size: 28rpx;
color: #666666;
}
.form-date{
width:100%;
}
.arrow-icon, .calendar-icon {
width: 24rpx;
height: 24rpx;
opacity: 0.4;
}
.calendar-icon {
opacity: 0.6;
}
/* 右侧箭头图标(日期字段用) */
.date-arrow-icon {
width: 24rpx;
height: 24rpx;
opacity: 0.4;
flex-shrink: 0;
margin-left: 8rpx;
}
}
/* 占位符样式 */
:deep(.placeholder) {
color: #666666 !important;
}
/* 日期选择器 - 融入表单整体风格 + 橙色主题 */
.form-value {
:deep(.uni-date-editor--x) {
padding: 0 !important;
border: none !important;
background: transparent !important;
}
:deep(.uni-date-x) {
border: none !important;
justify-content: flex-start !important;
background: transparent !important;
padding: 0 !important;
}
:deep(.uni-date__x-input) {
font-size: 28rpx !important;
color: #333333 !important;
padding-left: 0 !important;
background: transparent !important;
&::placeholder {
color: #CCCCCC !important;
}
}
/* 隐藏日历图标、清除图标 */
:deep(.uni-icons),
:deep(.uni-date__icon-clear) {
display: none !important;
}
}
/* 全局覆盖 datetime-picker 弹窗橙色主题 */
:deep(.uni-datetime-picker--btn) {
background-color: #FF6B35 !important;
}
/* 选中日期 - 蓝色圆圈 → 橙色 */
:deep(.uni-calendar-item--checked) {
background-color: #FF6B35 !important;
border-color: #fff !important;
}
/* 今天标记点 - 红色 → 橙色 */
:deep(.uni-calendar-item--isDay) {
background-color: #FF6B35 !important;
}
/* 范围选中的起止日期 */
:deep(.uni-calendar-item--before-checked),
:deep(.uni-calendar-item--after-checked) {
background-color: #FF6B35 !important;
}
/* 序号行 - 三列:文字和输入框同行 */
.form-row {
.row-inputs {
display: flex;
align-items: center;
.col-item {
display: flex;
align-items: center;
margin-right: 24rpx;
flex:1;
&:last-child {
margin-right: 0;
}
.col-label {
font-size: 26rpx;
color: #666666;
margin-left: 8rpx;
}
.col-input {
font-size: 28rpx;
color: #333333;
width: 100rpx;
padding-bottom: 8rpx;
border-bottom: 1rpx solid #E5E5E5;
flex:1;
}
}
}
}
/* 单选 - checkbox方框样式 */
.checkbox-group {
display: flex;
align-items: center;
gap: 48rpx;
.checkbox-item {
display: flex;
align-items: center;
margin-right:80rpx;
.checkbox-box {
width: 36rpx;
height: 36rpx;
border-radius: 6rpx;
border: 2rpx solid #DDDDDD;
margin-right: 12rpx;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
&.active {
background-color: #FF7B54;
border-color: #FF7B54;
.check-mark {
color: #FFFFFF;
font-size: 24rpx;
line-height: 1;
}
}
}
.checkbox-text {
font-size: 28rpx;
color: #666666;
}
}
}
/* 区块标题 */
.form-section-title {
padding: 32rpx 32rpx 20rpx;
text {
font-size: 28rpx;
color: #333333;
font-weight: 500;
}
}
/* 上传区域 */
.upload-area {
background-color: #FFFFFF;
padding: 32rpx;
.upload-btn {
width: 180rpx;
height: 180rpx;
border: 2rpx dashed #DDDDDD;
border-radius: 16rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&:active {
border-color: #FF7B54;
background-color: rgba(255, 123, 84, 0.02);
}
.upload-icon-wrapper {
margin-bottom: 12rpx;
.upload-folder-icon {
font-size: 56rpx;
opacity: 0.4;
}
}
.upload-text {
font-size: 24rpx;
color: #999999;
}
}
}
/* 底部按钮 */
.bottom-btn-wrapper {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 24rpx 38rpx;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
background-color: #F5F5F5;
.submit-btn {
width: 100%;
height: 96rpx;
background: linear-gradient(135deg, #FF8A65 0%, #FF6B35 100%);
border-radius: 48rpx;
border: none;
font-size: 32rpx;
font-weight: 500;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 24rpx rgba(255, 107, 53, 0.3);
&::after {
border: none;
}
&:active {
opacity: 0.9;
transform: scale(0.98);
}
}
}
</style>