智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1178 lines
30 KiB

<template>
<view class="personnel-form-container">
<!-- 自定义导航栏 -->
<view class="custom-nav">
<view class="nav-left" @click="goBack">
<text class="iconfont icon-arrow-left"></text>
</view>
<view class="nav-title">新员工信息填写</view>
<view class="nav-right"></view>
</view>
<!-- 进度条 -->
<view class="progress-container">
<view class="progress-bar">
<view class="progress-step" :class="currentStep >= 1 ? 'active' : ''">
<text class="step-number">1</text>
<text class="step-text">基本信息</text>
</view>
<view class="progress-line" :class="currentStep >= 2 ? 'active' : ''"></view>
<view class="progress-step" :class="currentStep >= 2 ? 'active' : ''">
<text class="step-number">2</text>
<text class="step-text">详细信息</text>
</view>
<view class="progress-line" :class="currentStep >= 3 ? 'active' : ''"></view>
<view class="progress-step" :class="currentStep >= 3 ? 'active' : ''">
<text class="step-number">3</text>
<text class="step-text">确认提交</text>
</view>
</view>
</view>
<!-- 表单内容 -->
<view class="form-content">
<!-- 第一步基本信息 -->
<view v-if="currentStep === 1" class="step-content">
<view class="section-title">基本信息</view>
<!-- 头像上传 -->
<view class="form-item">
<view class="label">头像</view>
<view class="avatar-upload" @click="chooseAvatar">
<image v-if="formData.head_img" :src="formData.head_img" class="avatar-preview"></image>
<view v-else class="avatar-placeholder">
<text class="iconfont icon-camera"></text>
<text class="placeholder-text">点击上传头像</text>
</view>
</view>
</view>
<!-- 姓名 -->
<view class="form-item required">
<view class="label">姓名</view>
<input class="form-input" v-model="formData.name" placeholder="请输入姓名" />
</view>
<!-- 性别 -->
<view class="form-item required">
<view class="label">性别</view>
<view class="radio-group">
<label class="radio-item" @click="formData.gender = 1">
<view class="radio" :class="formData.gender === 1 ? 'checked' : ''"></view>
<text>男</text>
</label>
<label class="radio-item" @click="formData.gender = 0">
<view class="radio" :class="formData.gender === 0 ? 'checked' : ''"></view>
<text>女</text>
</label>
</view>
</view>
<!-- 生日 -->
<view class="form-item">
<view class="label">出生日期</view>
<picker mode="date" :value="formData.birthday" @change="onBirthdayChange">
<view class="picker-input">
{{formData.birthday || '请选择出生日期'}}
</view>
</picker>
</view>
<!-- 手机号 -->
<view class="form-item required">
<view class="label">手机号码</view>
<input class="form-input" v-model="formData.phone" placeholder="请输入手机号码" type="number" />
</view>
<!-- 邮箱 -->
<view class="form-item">
<view class="label">邮箱</view>
<input class="form-input" v-model="formData.email" placeholder="请输入邮箱地址" />
</view>
<!-- 微信号 -->
<view class="form-item">
<view class="label">微信号</view>
<input class="form-input" v-model="formData.wx" placeholder="请输入微信号" />
</view>
<!-- 职位类型 -->
<view class="form-item required">
<view class="label">职位类型</view>
<picker :range="roleTypeOptions" range-key="role_name" @change="onRoleTypeChange">
<view class="picker-input">
{{getRoleTypeName(formData.account_type) || '请选择职位类型'}}
</view>
</picker>
</view>
<!-- 入职时间 -->
<view class="form-item">
<view class="label">入职时间</view>
<picker mode="date" :value="formData.join_time" @change="onJoinTimeChange">
<view class="picker-input">
{{formData.join_time || '请选择入职时间'}}
</view>
</picker>
</view>
</view>
<!-- 第二步:详细信息 -->
<view v-if="currentStep === 2" class="step-content">
<view class="section-title">详细信息</view>
<!-- 民族 -->
<view class="form-item">
<view class="label">民族</view>
<input class="form-input" v-model="detailData.ethnicity" placeholder="请输入民族" />
</view>
<!-- 年龄 -->
<view class="form-item">
<view class="label">年龄</view>
<input class="form-input" v-model.number="detailData.age" placeholder="请输入年龄" type="number" />
</view>
<!-- 政治面貌 -->
<view class="form-item">
<view class="label">政治面貌</view>
<picker :range="politicsOptions" @change="onPoliticsChange">
<view class="picker-input">
{{detailData.politics || '请选择政治面貌'}}
</view>
</picker>
</view>
<!-- 毕业院校 -->
<view class="form-item">
<view class="label">毕业院校</view>
<input class="form-input" v-model="detailData.university" placeholder="请输入毕业院校" />
</view>
<!-- 学历 -->
<view class="form-item">
<view class="label">学历</view>
<picker :range="educationOptions" @change="onEducationChange">
<view class="picker-input">
{{detailData.education || '请选择学历'}}
</view>
</picker>
</view>
<!-- 专业 -->
<view class="form-item">
<view class="label">专业</view>
<input class="form-input" v-model="detailData.major" placeholder="请输入专业" />
</view>
<!-- 毕业日期 -->
<view class="form-item">
<view class="label">毕业日期</view>
<picker mode="date" :value="detailData.graduation_date" @change="onGraduationDateChange">
<view class="picker-input">
{{detailData.graduation_date || '请选择毕业日期'}}
</view>
</picker>
</view>
<!-- 籍贯 -->
<view class="form-item">
<view class="label">籍贯</view>
<input class="form-input" v-model="detailData.native_place" placeholder="请输入籍贯" />
</view>
<!-- 户口所在地 -->
<view class="form-item">
<view class="label">户口所在地</view>
<input class="form-input" v-model="detailData.household_place" placeholder="请输入户口所在地" />
</view>
<!-- 户口性质 -->
<view class="form-item">
<view class="label">户口性质</view>
<picker :range="householdTypeOptions" @change="onHouseholdTypeChange">
<view class="picker-input">
{{detailData.household_type || '请选择户口性质'}}
</view>
</picker>
</view>
<!-- 户籍地址 -->
<view class="form-item">
<view class="label">户籍地址</view>
<textarea class="form-textarea" v-model="detailData.household_address" placeholder="请输入户籍地址"></textarea>
</view>
<!-- 现居地址 -->
<view class="form-item">
<view class="label">现居地址</view>
<textarea class="form-textarea" v-model="detailData.current_address" placeholder="请输入现居地址"></textarea>
</view>
<!-- 紧急联系人 -->
<view class="form-item">
<view class="label">紧急联系人</view>
<input class="form-input" v-model="detailData.emergency_contact" placeholder="请输入紧急联系人姓名" />
</view>
<!-- 紧急联系电话 -->
<view class="form-item">
<view class="label">紧急联系电话</view>
<input class="form-input" v-model="detailData.emergency_phone" placeholder="请输入紧急联系电话" type="number" />
</view>
<!-- 婚姻状况 -->
<view class="form-item">
<view class="label">婚姻状况</view>
<picker :range="maritalStatusOptions" @change="onMaritalStatusChange">
<view class="picker-input">
{{detailData.marital_status || '请选择婚姻状况'}}
</view>
</picker>
</view>
<!-- 银行卡号 -->
<view class="form-item">
<view class="label">银行卡号</view>
<input class="form-input" v-model="detailData.bank_card" placeholder="请输入银行卡号" type="number" />
</view>
<!-- 开户银行 -->
<view class="form-item">
<view class="label">开户银行</view>
<input class="form-input" v-model="detailData.bank_name" placeholder="请输入开户银行" />
</view>
<!-- 备注 -->
<view class="form-item">
<view class="label">备注</view>
<textarea class="form-textarea" v-model="detailData.remark" placeholder="请输入备注信息"></textarea>
</view>
</view>
<!-- 第三步:确认信息 -->
<view v-if="currentStep === 3" class="step-content">
<view class="section-title">确认信息</view>
<!-- 审批流程提示 -->
<view class="approval-section">
<view class="section-title">审批流程</view>
<view class="approval-info">
<view class="info-item">
<text class="info-label">审批流程:</text>
<text class="info-value">{{currentApprovalConfigName}}</text>
</view>
<view class="info-note">
<text>提交后将进入审批流程,请等待审批完成</text>
</view>
</view>
</view>
<view class="confirm-info">
<view class="info-section">
<view class="info-title">基本信息</view>
<view class="info-item">
<text class="info-label">姓名:</text>
<text class="info-value">{{formData.name}}</text>
</view>
<view class="info-item">
<text class="info-label">性别:</text>
<text class="info-value">{{formData.gender === 1 ? '男' : '女'}}</text>
</view>
<view class="info-item">
<text class="info-label">手机:</text>
<text class="info-value">{{formData.phone}}</text>
</view>
<view class="info-item">
<text class="info-label">职位:</text>
<text class="info-value">{{getRoleTypeName(formData.account_type)}}</text>
</view>
</view>
<view class="info-section">
<view class="info-title">详细信息</view>
<view class="info-item" v-if="detailData.education">
<text class="info-label">学历:</text>
<text class="info-value">{{detailData.education}}</text>
</view>
<view class="info-item" v-if="detailData.university">
<text class="info-label">毕业院校:</text>
<text class="info-value">{{detailData.university}}</text>
</view>
<view class="info-item" v-if="detailData.emergency_contact">
<text class="info-label">紧急联系人:</text>
<text class="info-value">{{detailData.emergency_contact}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="footer-buttons">
<button v-if="currentStep > 1" class="btn btn-secondary" @click="prevStep">上一步</button>
<button v-if="currentStep < 3" class="btn btn-primary" @click="nextStep">下一步</button>
<button v-if="currentStep === 3" class="btn btn-primary" @click="submitForm" :loading="submitting">提交</button>
</view>
<!-- 加载提示 -->
<uni-load-more v-if="submitting" status="loading" content-text="正在提交..."></uni-load-more>
</view>
</template>
<script>
import apiRoute from '@/common/axios.js'
export default {
data() {
return {
currentStep: 1,
submitting: false,
// 基本信息
formData: {
name: '',
head_img: '',
gender: null,
birthday: '',
phone: '',
email: '',
wx: '',
account_type: '',
join_time: ''
},
// 详细信息
detailData: {
ethnicity: '',
age: null,
politics: '',
university: '',
education: '',
major: '',
graduation_date: '',
native_place: '',
household_place: '',
household_type: '',
household_address: '',
current_address: '',
emergency_contact: '',
emergency_phone: '',
marital_status: '',
bank_card: '',
bank_name: '',
remark: ''
},
// 审批流程相关
approvalData: {
useApproval: true, // 默认启用审批流程
selectedConfig: null,
selectedIndex: 0
},
approvalConfigs: [],
// 选项数据
politicsOptions: ['群众', '共青团员', '中共党员', '民主党派', '无党派人士'],
educationOptions: ['高中', '中专', '大专', '本科', '硕士', '博士'],
householdTypeOptions: ['城镇', '农村'],
maritalStatusOptions: ['未婚', '已婚', '离异', '丧偶'],
// 职位类型选项
roleTypeOptions: []
}
},
computed: {
// 当前审批配置名称
currentApprovalConfigName() {
if (this.approvalData.selectedConfig && this.approvalData.selectedConfig.config_name) {
return this.approvalData.selectedConfig.config_name
}
return '新入职申请'
},
// 是否显示审批配置加载失败
shouldShowApprovalError() {
return this.currentStep === 3 && this.approvalData.useApproval &&
!this.approvalData.selectedConfig && this.approvalConfigs.length === 0
}
},
onLoad() {
// 设置当前日期为默认入职时间
const today = new Date()
const year = today.getFullYear()
const month = String(today.getMonth() + 1).padStart(2, '0')
const day = String(today.getDate()).padStart(2, '0')
this.formData.join_time = `${year}-${month}-${day}`
// 加载审批配置
this.loadApprovalConfigs()
// 加载职位类型
this.loadRoleTypes()
},
methods: {
// 返回上一页
goBack() {
uni.navigateBack()
},
// 选择头像
chooseAvatar() {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
this.uploadAvatar(tempFilePath)
}
})
},
// 上传头像
async uploadAvatar(filePath) {
uni.showLoading({ title: '上传中...' })
try {
// 使用封装的上传方法
const response = await apiRoute.uploadFile({
url: 'uploadImage', // 使用员工端图片上传接口
filePath: filePath,
name: 'file'
})
if (response.data.code === 1) {
this.formData.head_img = response.data.data.url
uni.showToast({
title: '头像上传成功',
icon: 'success'
})
} else {
uni.showToast({
title: response.data.msg || '上传失败',
icon: 'none'
})
}
} catch (error) {
console.error('头像上传失败:', error)
uni.showToast({
title: '网络错误,请稍后重试',
icon: 'none'
})
} finally {
uni.hideLoading()
}
},
// 日期选择事件
onBirthdayChange(e) {
this.formData.birthday = e.detail.value
// 自动计算年龄
this.calculateAge()
},
onJoinTimeChange(e) {
this.formData.join_time = e.detail.value
},
onGraduationDateChange(e) {
this.detailData.graduation_date = e.detail.value
},
// 下拉选择事件
onPoliticsChange(e) {
this.detailData.politics = this.politicsOptions[e.detail.value]
},
onEducationChange(e) {
this.detailData.education = this.educationOptions[e.detail.value]
},
onHouseholdTypeChange(e) {
this.detailData.household_type = this.householdTypeOptions[e.detail.value]
},
onMaritalStatusChange(e) {
this.detailData.marital_status = this.maritalStatusOptions[e.detail.value]
},
// 职位类型选择事件
onRoleTypeChange(e) {
const index = e.detail.value
const selectedRole = this.roleTypeOptions[index]
if (selectedRole) {
this.formData.account_type = selectedRole.role_key
}
},
// 计算年龄
calculateAge() {
if (this.formData.birthday) {
const birthDate = new Date(this.formData.birthday)
const today = new Date()
let age = today.getFullYear() - birthDate.getFullYear()
const monthDiff = today.getMonth() - birthDate.getMonth()
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
age--
}
this.detailData.age = age
}
},
// 步骤控制
nextStep() {
if (this.validateCurrentStep()) {
this.currentStep++
}
},
prevStep() {
this.currentStep--
},
// 验证当前步骤
validateCurrentStep() {
if (this.currentStep === 1) {
if (!this.formData.name) {
uni.showToast({ title: '请输入姓名', icon: 'none' })
return false
}
if (this.formData.gender === null) {
uni.showToast({ title: '请选择性别', icon: 'none' })
return false
}
if (!this.formData.phone) {
uni.showToast({ title: '请输入手机号码', icon: 'none' })
return false
}
if (!/^1[3-9]\d{9}$/.test(this.formData.phone)) {
uni.showToast({ title: '请输入正确的手机号码', icon: 'none' })
return false
}
if (!this.formData.account_type) {
uni.showToast({ title: '请选择职位类型', icon: 'none' })
return false
}
}
return true
},
// 加载审批配置
async loadApprovalConfigs() {
try {
const response = await apiRoute.get('personnel/approval-configs', {
business_type: 'personnel_add'
})
if (response.code === 1) {
this.approvalConfigs = response.data || []
// 自动选择第一个可用的审批配置
if (this.approvalConfigs.length > 0) {
this.approvalData.selectedConfig = this.approvalConfigs[0]
this.approvalData.selectedIndex = 0
}
console.log('审批配置加载成功:', this.approvalConfigs)
} else {
console.error('审批配置加载失败:', response.msg)
// 如果加载失败,设置默认配置以避免阻塞提交
this.approvalData.selectedConfig = {
id: 0,
config_name: '新入职申请',
description: '新入职申请',
business_type: 'personnel_add'
}
}
} catch (error) {
console.error('加载审批配置失败:', error)
// 网络错误时也设置默认配置
this.approvalData.selectedConfig = {
id: 0,
config_name: '新入职申请',
description: '新入职申请',
business_type: 'personnel_add'
}
}
},
// 审批配置选择变化
onApprovalConfigChange(e) {
const index = e.detail.value
this.approvalData.selectedIndex = index
this.approvalData.selectedConfig = this.approvalConfigs[index]
},
// 获取职位类型名称
getRoleTypeName(roleKey) {
if (!roleKey) return ''
const role = this.roleTypeOptions.find(item => item.role_key === roleKey)
return role ? role.role_name : roleKey
},
// 加载职位类型数据
async loadRoleTypes() {
try {
const response = await apiRoute.get('personnel/role-types')
if (response.code === 1 && response.data) {
this.roleTypeOptions = response.data
console.log('职位类型加载成功:', this.roleTypeOptions)
} else {
console.error('职位类型加载失败:', response.msg)
// 如果加载失败,使用默认选项
this.roleTypeOptions = [
{ role_id: 1, role_name: '教练主管', role_key: 'teacher_manager' },
{ role_id: 2, role_name: '普通市场', role_key: 'market' },
{ role_id: 3, role_name: '班主任', role_key: 'teacher' }
]
}
} catch (error) {
console.error('加载职位类型失败:', error)
// 网络错误时使用默认选项
this.roleTypeOptions = [
{ role_id: 1, role_name: '教练主管', role_key: 'teacher_manager' },
{ role_id: 2, role_name: '普通市场', role_key: 'market' },
{ role_id: 3, role_name: '班主任', role_key: 'teacher' }
]
}
},
// 提交表单
async submitForm() {
if (!this.validateCurrentStep()) {
return
}
console.log('开始提交表单...')
console.log('当前审批配置:', this.approvalData.selectedConfig)
// 确保有审批配置(如果配置还没加载完,等待一下或使用默认值)
if (this.approvalData.useApproval && !this.approvalData.selectedConfig) {
console.log('审批配置未加载,尝试重新加载...')
await this.loadApprovalConfigs()
// 如果还是没有配置,使用默认配置继续提交
if (!this.approvalData.selectedConfig) {
this.approvalData.selectedConfig = {
id: 0,
config_name: '新入职申请',
description: '新入职申请',
business_type: 'personnel_add'
}
console.log('使用默认审批配置:', this.approvalData.selectedConfig)
}
}
this.submitting = true
try {
// 处理字段值:空字符串转为null或空字符串,避免数据库错误
const processField = (value, allowEmpty = true) => {
if (value === null || value === undefined) {
return null
}
if (typeof value === 'string') {
const trimmed = value.trim()
return trimmed === '' ? (allowEmpty ? '' : null) : trimmed
}
return value
}
// 处理日期字段:空字符串必须转为null
const processDateField = (dateValue) => {
return processField(dateValue, false) // 日期字段不允许空字符串
}
// 处理数字字段:空值转为null
const processNumberField = (numberValue) => {
if (numberValue === null || numberValue === undefined || numberValue === '') {
return null
}
return numberValue
}
const submitData = {
// 基本信息(必填字段保持原值)
name: this.formData.name,
gender: this.formData.gender,
phone: this.formData.phone,
account_type: this.formData.account_type,
// 基本信息(非必填字段)
head_img: processField(this.formData.head_img),
birthday: processDateField(this.formData.birthday),
email: processField(this.formData.email),
wx: processField(this.formData.wx),
join_time: processDateField(this.formData.join_time),
// 详细信息(全部非必填)
ethnicity: processField(this.detailData.ethnicity),
age: processNumberField(this.detailData.age),
politics: processField(this.detailData.politics),
university: processField(this.detailData.university),
education: processField(this.detailData.education),
major: processField(this.detailData.major),
graduation_date: processDateField(this.detailData.graduation_date),
native_place: processField(this.detailData.native_place),
household_place: processField(this.detailData.household_place),
household_type: processField(this.detailData.household_type),
household_address: processField(this.detailData.household_address),
current_address: processField(this.detailData.current_address),
emergency_contact: processField(this.detailData.emergency_contact),
emergency_phone: processField(this.detailData.emergency_phone),
marital_status: processField(this.detailData.marital_status),
bank_card: processField(this.detailData.bank_card),
bank_name: processField(this.detailData.bank_name),
remark: processField(this.detailData.remark),
// 处理审批配置
use_approval: this.approvalData.useApproval,
approval_config_id: this.approvalData.selectedConfig ? this.approvalData.selectedConfig.id : 0
}
console.log('提交数据:', submitData)
const response = await apiRoute.post('personnel/add', submitData)
console.log('提交响应:', response)
console.log('响应数据结构:', response.data || response)
console.log('响应码:', response.code, '类型:', typeof response.code)
if (response.code === 1) {
console.log('提交成功:', response.msg)
uni.showToast({
title: '入职申请已提交,等待审批',
icon: 'success',
duration: 2000
})
setTimeout(() => {
uni.navigateBack()
}, 2000)
} else {
console.error('提交失败:', response.msg)
uni.showToast({
title: response.msg || '提交失败',
icon: 'none'
})
}
} catch (error) {
console.error('提交员工信息失败:', error)
// 提供更详细的错误信息
let errorMsg = '网络错误,请稍后重试'
if (error.response) {
errorMsg = error.response.msg || `服务器错误(${error.response.status})`
} else if (error.message) {
errorMsg = error.message
}
uni.showToast({
title: errorMsg,
icon: 'none',
duration: 3000
})
} finally {
this.submitting = false
}
}
}
}
</script>
<style lang="scss" scoped>
.personnel-form-container {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 120rpx;
}
/* 自定义导航栏 */
.custom-nav {
display: flex;
align-items: center;
justify-content: space-between;
height: 88rpx;
padding: 0 32rpx;
background-color: #fff;
border-bottom: 1rpx solid #e5e5e5;
position: sticky;
top: 0;
z-index: 100;
.nav-left {
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
.iconfont {
font-size: 36rpx;
color: #333;
}
}
.nav-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
}
.nav-right {
width: 80rpx;
}
}
/* 进度条 */
.progress-container {
background-color: #fff;
padding: 40rpx 32rpx;
margin-bottom: 20rpx;
}
.progress-bar {
display: flex;
align-items: center;
justify-content: space-between;
}
.progress-step {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
.step-number {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background-color: #e5e5e5;
color: #999;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
font-weight: 600;
margin-bottom: 12rpx;
}
.step-text {
font-size: 24rpx;
color: #999;
}
&.active {
.step-number {
background-color: #007ACC;
color: #fff;
}
.step-text {
color: #007ACC;
}
}
}
.progress-line {
flex: 1;
height: 4rpx;
background-color: #e5e5e5;
margin: 0 20rpx;
margin-top: -30rpx;
&.active {
background-color: #007ACC;
}
}
/* 表单内容 */
.form-content {
background-color: #fff;
margin: 0 20rpx 20rpx;
border-radius: 16rpx;
padding: 32rpx;
}
.section-title {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin-bottom: 40rpx;
border-left: 8rpx solid #007ACC;
padding-left: 20rpx;
}
.form-item {
margin-bottom: 40rpx;
&.required .label::before {
content: '*';
color: #ff4d4f;
margin-right: 8rpx;
}
.label {
font-size: 28rpx;
color: #333;
margin-bottom: 16rpx;
font-weight: 500;
}
.form-input,
.picker-input {
width: 100%;
height: 88rpx;
border: 2rpx solid #e5e5e5;
border-radius: 12rpx;
padding: 0 24rpx;
font-size: 28rpx;
color: #333;
background-color: #fff;
box-sizing: border-box;
display: flex;
align-items: center;
&:focus {
border-color: #007ACC;
}
}
.form-textarea {
width: 100%;
min-height: 120rpx;
border: 2rpx solid #e5e5e5;
border-radius: 12rpx;
padding: 20rpx 24rpx;
font-size: 28rpx;
color: #333;
background-color: #fff;
box-sizing: border-box;
resize: none;
&:focus {
border-color: #007ACC;
}
}
.picker-input {
color: #999;
cursor: pointer;
}
}
/* 头像上传 */
.avatar-upload {
width: 120rpx;
height: 120rpx;
border: 2rpx solid #e5e5e5;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
cursor: pointer;
.avatar-preview {
width: 100%;
height: 100%;
border-radius: 50%;
}
.avatar-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #999;
.iconfont {
font-size: 32rpx;
margin-bottom: 8rpx;
}
.placeholder-text {
font-size: 20rpx;
}
}
}
/* 单选按钮组 */
.radio-group {
display: flex;
gap: 60rpx;
}
.radio-item {
display: flex;
align-items: center;
cursor: pointer;
.radio {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #e5e5e5;
border-radius: 50%;
margin-right: 16rpx;
position: relative;
&.checked {
border-color: #007ACC;
&::after {
content: '';
width: 16rpx;
height: 16rpx;
background-color: #007ACC;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
text {
font-size: 28rpx;
color: #333;
}
}
/* 审批流程部分 */
.approval-section {
background-color: #fff;
margin: 24rpx 32rpx;
padding: 32rpx;
border-radius: 16rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 24rpx;
border-left: 6rpx solid #007ACC;
padding-left: 16rpx;
}
.approval-info {
.info-item {
display: flex;
align-items: center;
margin-bottom: 16rpx;
.info-label {
font-size: 28rpx;
color: #666;
margin-right: 16rpx;
}
.info-value {
font-size: 28rpx;
color: #007ACC;
font-weight: 500;
}
}
.info-note {
padding: 16rpx;
background-color: #f8f9fa;
border-radius: 8rpx;
border-left: 4rpx solid #007ACC;
text {
font-size: 24rpx;
color: #666;
line-height: 1.5;
}
}
}
}
/* 确认信息 */
.confirm-info {
.info-section {
margin-bottom: 40rpx;
.info-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 24rpx;
border-left: 6rpx solid #007ACC;
padding-left: 16rpx;
}
.info-item {
display: flex;
margin-bottom: 16rpx;
.info-label {
font-size: 28rpx;
color: #666;
width: 120rpx;
flex-shrink: 0;
}
.info-value {
font-size: 28rpx;
color: #333;
flex: 1;
}
}
}
}
/* 底部按钮 */
.footer-buttons {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
padding: 24rpx 32rpx 24rpx;
border-top: 1rpx solid #e5e5e5;
display: flex;
gap: 24rpx;
z-index: 100;
.btn {
flex: 1;
height: 88rpx;
border-radius: 12rpx;
font-size: 32rpx;
font-weight: 600;
border: none;
display: flex;
align-items: center;
justify-content: center;
&.btn-primary {
background-color: #007ACC;
color: #fff;
&:active {
background-color: #0056b3;
}
}
&.btn-secondary {
background-color: #f5f5f5;
color: #666;
&:active {
background-color: #e5e5e5;
}
}
}
}
/* 步骤内容动画 */
.step-content {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20rpx);
}
to {
opacity: 1;
transform: translateX(0);
}
}
</style>