新增報修介面設計

This commit is contained in:
jasonchenwork 2025-05-09 16:49:13 +08:00
parent f98c3ed9f0
commit c6248935e7
12 changed files with 383 additions and 4 deletions

View File

@ -8,7 +8,7 @@ plugins {
android {
namespace = "com.example.communityapp"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
ndkVersion = "27.0.12077973"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11

View File

@ -42,4 +42,7 @@
<data android:mimeType="text/plain"/>
</intent>
</queries>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'reapair.dart';
class HomeContentPage extends StatelessWidget {
const HomeContentPage({super.key});
@ -79,7 +80,14 @@ class HomeContentPage extends StatelessWidget {
) {
return GestureDetector(
onTap: () {
// TODO:
switch (title) {
case "報修":
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const RepairPage()),
);
default:
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'login_page.dart';
import 'edit_profile.dart';
import 'feedback.dart';
import 'reapair.dart';
class PersonalPage extends StatelessWidget {
const PersonalPage({super.key});
@ -196,6 +197,10 @@ class PersonalPage extends StatelessWidget {
}),
_buildMenuItem('報修申請', 'repair.png', () {
// TODO:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const RepairPage()),
);
}),
_buildMenuItem('包裹通知', 'package.png', () {
// TODO:

187
lib/reapair.dart Normal file
View File

@ -0,0 +1,187 @@
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class RepairPage extends StatefulWidget {
const RepairPage({super.key});
@override
State<RepairPage> createState() => _RepairPageState();
}
class _RepairPageState extends State<RepairPage> {
final _formKey = GlobalKey<FormState>();
String? _repairType;
final _locationController = TextEditingController();
final _descriptionController = TextEditingController();
XFile? _photo;
final List<Map<String, String>> _repairRecords = [
{
"date": "2025/04/20",
"type": "水管漏水",
"location": "A棟 2F",
"status": "處理中",
},
{
"date": "2025/04/18",
"type": "網路異常",
"location": "C棟 5F",
"status": "已完成",
},
{
"date": "2025/04/15",
"type": "電力問題",
"location": "B棟 6F",
"status": "待處理",
},
];
Future<void> _pickImage() async {
final picker = ImagePicker();
final picked = await picker.pickImage(source: ImageSource.gallery);
if (picked != null) {
setState(() {
_photo = picked;
});
}
}
void _submitForm() {
if (_formKey.currentState!.validate() && _repairType != null) {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('報修已提交!')));
//
}
}
@override
void dispose() {
_locationController.dispose();
_descriptionController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('水電網路報修'),
backgroundColor: const Color(0xFF9eaf9f),
foregroundColor: Colors.white,
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
const Text('🛠️ 填寫報修單', style: TextStyle(fontSize: 16)),
const SizedBox(height: 12),
Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'報修類別',
style: TextStyle(fontWeight: FontWeight.bold),
),
DropdownButtonFormField<String>(
value: _repairType,
items: const [
DropdownMenuItem(value: '電力問題', child: Text('電力問題')),
DropdownMenuItem(value: '水管漏水', child: Text('水管漏水')),
DropdownMenuItem(value: '網路異常', child: Text('網路異常')),
DropdownMenuItem(value: '其他', child: Text('其他')),
],
hint: const Text('請選擇'),
onChanged: (value) {
setState(() {
_repairType = value;
});
},
validator: (value) => value == null ? '請選擇報修類別' : null,
),
const SizedBox(height: 12),
const Text(
'地點/房號',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextFormField(
controller: _locationController,
decoration: const InputDecoration(hintText: 'B棟 3F'),
validator:
(value) =>
value == null || value.isEmpty ? '請輸入地點' : null,
),
const SizedBox(height: 12),
const Text(
'問題描述',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextFormField(
controller: _descriptionController,
maxLines: 3,
decoration: const InputDecoration(
hintText: '請簡要描述問題...',
border: OutlineInputBorder(),
),
validator:
(value) =>
value == null || value.isEmpty ? '請輸入問題描述' : null,
),
const SizedBox(height: 12),
const Text(
'照片上傳(選填)',
style: TextStyle(fontWeight: FontWeight.bold),
),
Row(
children: [
ElevatedButton(
onPressed: _pickImage,
child: const Text(
'選擇照片',
style: TextStyle(color: Colors.purple),
),
),
const SizedBox(width: 8),
if (_photo != null)
Text('已選擇圖片', style: TextStyle(color: Colors.green)),
],
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _submitForm,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
minimumSize: const Size.fromHeight(48),
),
child: const Text(
'送出報修',
style: TextStyle(color: Colors.white),
),
),
],
),
),
const SizedBox(height: 24),
const Text('📋 已申報紀錄', style: TextStyle(fontSize: 16)),
const SizedBox(height: 12),
..._repairRecords.map(
(record) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${record["date"]} - ${record["type"]}',
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text('地點:${record["location"]}|狀態:${record["status"]}'),
],
),
),
),
],
),
);
}
}

View File

@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
}

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@ -5,6 +5,8 @@
import FlutterMacOS
import Foundation
import file_selector_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
}

View File

@ -41,6 +41,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.19.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
url: "https://pub.dev"
source: hosted
version: "0.3.4+2"
cupertino_icons:
dependency: "direct main"
description:
@ -57,6 +65,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.2"
file_selector_linux:
dependency: transitive
description:
name: file_selector_linux
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: "271ab9986df0c135d45c3cdb6bd0faa5db6f4976d3e4b437cf7d0f258d941bfc"
url: "https://pub.dev"
source: hosted
version: "0.9.4+2"
file_selector_platform_interface:
dependency: transitive
description:
name: file_selector_platform_interface
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
url: "https://pub.dev"
source: hosted
version: "2.6.2"
file_selector_windows:
dependency: transitive
description:
name: file_selector_windows
sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
url: "https://pub.dev"
source: hosted
version: "0.9.3+4"
flutter:
dependency: "direct main"
description: flutter
@ -70,11 +110,104 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e
url: "https://pub.dev"
source: hosted
version: "2.0.28"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
http:
dependency: transitive
description:
name: http
sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
url: "https://pub.dev"
source: hosted
version: "4.1.2"
image_picker:
dependency: "direct main"
description:
name: image_picker
sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: "317a5d961cec5b34e777b9252393f2afbd23084aa6e60fcf601dcf6341b9ebeb"
url: "https://pub.dev"
source: hosted
version: "0.8.12+23"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83"
url: "https://pub.dev"
source: hosted
version: "3.0.6"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100"
url: "https://pub.dev"
source: hosted
version: "0.8.12+2"
image_picker_linux:
dependency: transitive
description:
name: image_picker_linux
sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9"
url: "https://pub.dev"
source: hosted
version: "0.2.1+2"
image_picker_macos:
dependency: transitive
description:
name: image_picker_macos
sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1"
url: "https://pub.dev"
source: hosted
version: "0.2.1+2"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0"
url: "https://pub.dev"
source: hosted
version: "2.10.1"
image_picker_windows:
dependency: transitive
description:
name: image_picker_windows
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
leak_tracker:
dependency: transitive
description:
@ -131,6 +264,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.16.0"
mime:
dependency: transitive
description:
name: mime
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
path:
dependency: transitive
description:
@ -139,6 +280,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
sky_engine:
dependency: transitive
description: flutter
@ -192,6 +341,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.4"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
version: "1.4.0"
vector_math:
dependency: transitive
description:
@ -208,6 +365,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "14.3.1"
web:
dependency: transitive
description:
name: web
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
sdks:
dart: ">=3.7.2 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
flutter: ">=3.27.0"

View File

@ -30,7 +30,7 @@ environment:
dependencies:
flutter:
sdk: flutter
image_picker: ^1.0.4
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8

View File

@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h"
#include <file_selector_windows/file_selector_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
}

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST