gcx/frontend/admin-app/lib/features/onboarding/presentation/pages/onboarding_page.dart

384 lines
13 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import '../../../../app/theme/app_colors.dart';
import '../../../../app/router.dart';
/// 发行方入驻审核流程
///
/// 步骤:企业信息 → 资质上传 → 联系人 → 提交审核 → 审核结果
/// 零保证金入驻:审核通过后给予初始低额度
enum OnboardingStep { companyInfo, documents, contactPerson, review, approved, rejected }
class OnboardingPage extends StatefulWidget {
const OnboardingPage({super.key});
@override
State<OnboardingPage> createState() => _OnboardingPageState();
}
class _OnboardingPageState extends State<OnboardingPage> {
OnboardingStep _currentStep = OnboardingStep.companyInfo;
final _companyNameController = TextEditingController();
final _licenseController = TextEditingController();
final _contactController = TextEditingController();
final _contactPhoneController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('企业入驻')),
body: Column(
children: [
// Step Indicator
_buildStepIndicator(),
const Divider(height: 1),
// Step Content
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: _buildStepContent(),
),
),
// Bottom Actions
Padding(
padding: const EdgeInsets.all(24),
child: Row(
children: [
if (_currentStep.index > 0 && _currentStep.index < 3)
Expanded(
child: OutlinedButton(
onPressed: _goBack,
child: const Text('上一步'),
),
),
if (_currentStep.index > 0 && _currentStep.index < 3) const SizedBox(width: 12),
Expanded(
child: ElevatedButton(
onPressed: _goNext,
child: Text(_currentStep.index < 2 ? '下一步' : '提交审核'),
),
),
],
),
),
],
),
);
}
Widget _buildStepIndicator() {
final steps = ['企业信息', '资质上传', '联系人', '审核中'];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Row(
children: List.generate(steps.length, (i) {
final isActive = i <= _currentStep.index && _currentStep.index < 4;
final isComplete = i < _currentStep.index;
return Expanded(
child: Row(
children: [
Container(
width: 28,
height: 28,
decoration: BoxDecoration(
color: isComplete
? AppColors.success
: isActive
? AppColors.primary
: AppColors.gray200,
shape: BoxShape.circle,
),
child: Center(
child: isComplete
? const Icon(Icons.check, color: Colors.white, size: 16)
: Text(
'${i + 1}',
style: TextStyle(
color: isActive ? Colors.white : AppColors.textTertiary,
fontSize: 13,
fontWeight: FontWeight.w600,
),
),
),
),
const SizedBox(width: 6),
Expanded(
child: Text(
steps[i],
style: TextStyle(
fontSize: 12,
color: isActive ? AppColors.textPrimary : AppColors.textTertiary,
fontWeight: isActive ? FontWeight.w600 : FontWeight.w400,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}),
),
);
}
Widget _buildStepContent() {
switch (_currentStep) {
case OnboardingStep.companyInfo:
return _buildCompanyInfoStep();
case OnboardingStep.documents:
return _buildDocumentsStep();
case OnboardingStep.contactPerson:
return _buildContactStep();
case OnboardingStep.review:
return _buildReviewStep();
case OnboardingStep.approved:
return _buildApprovedStep();
case OnboardingStep.rejected:
return _buildRejectedStep();
}
}
Widget _buildCompanyInfoStep() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('企业基本信息', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
const SizedBox(height: 8),
const Text('请填写真实的企业信息,用于入驻审核', style: TextStyle(color: AppColors.textSecondary)),
const SizedBox(height: 24),
TextField(
controller: _companyNameController,
decoration: const InputDecoration(labelText: '企业名称', hintText: '请输入企业全称'),
),
const SizedBox(height: 16),
TextField(
controller: _licenseController,
decoration: const InputDecoration(labelText: '统一社会信用代码', hintText: '请输入18位信用代码'),
),
const SizedBox(height: 16),
DropdownButtonFormField<String>(
decoration: const InputDecoration(labelText: '企业类型'),
items: const [
DropdownMenuItem(value: 'restaurant', child: Text('餐饮企业')),
DropdownMenuItem(value: 'retail', child: Text('零售企业')),
DropdownMenuItem(value: 'entertainment', child: Text('娱乐/文旅')),
DropdownMenuItem(value: 'other', child: Text('其他')),
],
onChanged: (_) {
// TODO: Update selected company type
},
),
const SizedBox(height: 16),
TextField(
decoration: const InputDecoration(labelText: '企业地址', hintText: '请输入企业注册地址'),
),
// AI合规助手
const SizedBox(height: 24),
Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: AppColors.primarySurface,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.primary.withValues(alpha: 0.15)),
),
child: const Row(
children: [
Icon(Icons.auto_awesome_rounded, color: AppColors.primary, size: 20),
SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('AI 合规助手', style: TextStyle(fontSize: 13, color: AppColors.primary, fontWeight: FontWeight.w600)),
SizedBox(height: 2),
Text('填写信息后AI将自动检查合规要求', style: TextStyle(fontSize: 12, color: AppColors.textSecondary)),
],
),
),
],
),
),
],
);
}
Widget _buildDocumentsStep() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('资质文件上传', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
const SizedBox(height: 8),
const Text('请上传清晰的企业资质文件', style: TextStyle(color: AppColors.textSecondary)),
const SizedBox(height: 24),
_buildUploadArea('营业执照', Icons.business_rounded, true),
const SizedBox(height: 16),
_buildUploadArea('法人身份证(正反面)', Icons.badge_rounded, true),
const SizedBox(height: 16),
_buildUploadArea('行业资质证书(可选)', Icons.verified_rounded, false),
],
);
}
Widget _buildUploadArea(String title, IconData icon, bool required) {
return Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
border: Border.all(color: AppColors.border, style: BorderStyle.solid),
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Icon(icon, size: 40, color: AppColors.textTertiary),
const SizedBox(height: 8),
Text(
title,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
),
if (required)
const Text('*必填', style: TextStyle(fontSize: 11, color: AppColors.error)),
const SizedBox(height: 8),
OutlinedButton.icon(
onPressed: () {
// TODO: Open file picker for document upload
},
icon: const Icon(Icons.upload_rounded, size: 18),
label: const Text('点击上传'),
),
],
),
);
}
Widget _buildContactStep() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('联系人信息', style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
const SizedBox(height: 24),
TextField(
controller: _contactController,
decoration: const InputDecoration(labelText: '联系人姓名'),
),
const SizedBox(height: 16),
TextField(
controller: _contactPhoneController,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(labelText: '联系人手机号'),
),
const SizedBox(height: 16),
TextField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(labelText: '企业邮箱'),
),
const SizedBox(height: 16),
TextField(
decoration: const InputDecoration(labelText: '职位/角色'),
),
],
);
}
Widget _buildReviewStep() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 40),
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: AppColors.warningLight,
shape: BoxShape.circle,
),
child: const Icon(Icons.hourglass_bottom_rounded, color: AppColors.warning, size: 40),
),
const SizedBox(height: 24),
const Text('审核中', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700)),
const SizedBox(height: 8),
const Text('您的入驻申请已提交预计1-3个工作日内完成审核', style: TextStyle(color: AppColors.textSecondary)),
const SizedBox(height: 32),
OutlinedButton(
onPressed: () => Navigator.pop(context),
child: const Text('返回登录'),
),
],
),
);
}
Widget _buildApprovedStep() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 40),
Container(
width: 80,
height: 80,
decoration: const BoxDecoration(
color: AppColors.successLight,
shape: BoxShape.circle,
),
child: const Icon(Icons.check_circle_rounded, color: AppColors.success, size: 40),
),
const SizedBox(height: 24),
const Text('审核通过', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700)),
const SizedBox(height: 8),
const Text('恭喜!您已获得白银级初始额度', style: TextStyle(color: AppColors.textSecondary)),
const SizedBox(height: 32),
ElevatedButton(
onPressed: () => Navigator.pushReplacementNamed(context, AppRouter.main),
child: const Text('进入控制台'),
),
],
),
);
}
Widget _buildRejectedStep() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 40),
Container(
width: 80,
height: 80,
decoration: const BoxDecoration(
color: AppColors.errorLight,
shape: BoxShape.circle,
),
child: const Icon(Icons.cancel_rounded, color: AppColors.error, size: 40),
),
const SizedBox(height: 24),
const Text('审核未通过', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700)),
const SizedBox(height: 8),
const Text('原因:资质文件不清晰,请重新上传', style: TextStyle(color: AppColors.textSecondary)),
const SizedBox(height: 32),
ElevatedButton(
onPressed: () => setState(() => _currentStep = OnboardingStep.documents),
child: const Text('重新提交'),
),
],
),
);
}
void _goBack() {
if (_currentStep.index > 0) {
setState(() => _currentStep = OnboardingStep.values[_currentStep.index - 1]);
}
}
void _goNext() {
if (_currentStep.index < 2) {
setState(() => _currentStep = OnboardingStep.values[_currentStep.index + 1]);
} else if (_currentStep == OnboardingStep.contactPerson) {
setState(() => _currentStep = OnboardingStep.review);
}
}
}