移到新目錄(gogs) 並優化 login 及上傳圖片機制
This commit is contained in:
@@ -39,11 +39,11 @@ class ExpenseApiService {
|
||||
// 使用 GenericApiService 內定義的 BASE_IP
|
||||
var request = http.MultipartRequest(
|
||||
'POST',
|
||||
Uri.parse("$BASE_IP/upload/EIS_demo/images")
|
||||
Uri.parse("${GenericApiService.BASE_IP}/upload/EIS_demo/images")
|
||||
);
|
||||
|
||||
// 取得本地檔案名稱
|
||||
String picFileName = "$BASE_IP/upload/EIS_demo/images/" + file.path.split('/').last;
|
||||
String picFileName = "${GenericApiService.BASE_IP}/upload/EIS_demo/images/" + file.path.split('/').last;
|
||||
|
||||
// [修正] index.js 的 multer 配置要求 key 必須是 'file'
|
||||
request.files.add(await http.MultipartFile.fromPath('file', file.path));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import './expense_model.dart';
|
||||
import '../services/generic_api_service.dart';
|
||||
|
||||
class ExpenseDetail extends StatelessWidget {
|
||||
final ExpenseApply expense;
|
||||
@@ -170,17 +171,32 @@ class ExpenseDetail extends StatelessWidget {
|
||||
height: 250,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
// [新增] 加載中的轉圈圈
|
||||
loadingBuilder: (context, child, loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return Container(
|
||||
height: 250,
|
||||
color: Colors.grey.shade100,
|
||||
child: const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
},
|
||||
// 處理圖片加載失敗
|
||||
errorBuilder: (context, error, stackTrace) => Container(
|
||||
height: 200,
|
||||
child: const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.broken_image, color: Colors.grey, size: 40),
|
||||
Text('無法載入單據圖片', style: TextStyle(color: Colors.grey)),
|
||||
],
|
||||
),
|
||||
),
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
print("圖片載入失敗,試圖存取的網址為: ${expense.fullPicUrl}");
|
||||
return Container(
|
||||
height: 200,
|
||||
color: Colors.grey.shade100,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.broken_image, color: Colors.red, size: 40),
|
||||
const SizedBox(height: 8),
|
||||
Text('無法載入圖片', style: TextStyle(color: Colors.grey.shade600)),
|
||||
Text(expense.picPath ?? "無檔名", style: const TextStyle(fontSize: 10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
// 在 expense_model.dart 中修改
|
||||
import '../auth_manager.dart';
|
||||
import '../services/generic_api_service.dart';
|
||||
|
||||
// --- 新增類別模型 ---
|
||||
class ExpenseClass {
|
||||
@@ -30,6 +33,31 @@ class ExpenseApply {
|
||||
final String? creatorId;
|
||||
final DateTime? createDateTime;
|
||||
|
||||
// [修改] 動態取得完整網址的 Getter
|
||||
String get fullPicUrl {
|
||||
if (picPath == null || picPath!.trim().isEmpty) return "";
|
||||
|
||||
// 1. 先去除前後空白,避免不可見字元的干擾
|
||||
String path = picPath!.trim();
|
||||
|
||||
// 2. 判斷是否已經是完整網址 (http/https)
|
||||
if (path.startsWith('http://') || path.startsWith('https://')) {
|
||||
return path;
|
||||
}
|
||||
|
||||
// 3. 【關鍵修正】檢查 path 開頭是否有斜線,如果有,把它去掉
|
||||
// 避免與前面的 "/images/" 組成 "//" 導致解析異常
|
||||
if (path.startsWith('/')) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
|
||||
// 4. 取得目前登入的公司別
|
||||
final String db = AuthManager().currentCompany ?? "demo";
|
||||
|
||||
// 5. 組合最終網址
|
||||
return "${GenericApiService.BASE_IP}/upload/eis_$db/images/$path";
|
||||
}
|
||||
|
||||
ExpenseApply({
|
||||
this.applyId,
|
||||
required this.applyDate,
|
||||
@@ -59,5 +87,5 @@ class ExpenseApply {
|
||||
}
|
||||
|
||||
// 輔助屬性:取得完整圖片路徑 (假設後端基礎 URL)
|
||||
String get fullPicUrl => "https://api.gex.com.tw:8033/uploads/$picPath";
|
||||
// String get fullPicUrl => "https://api.gex.com.tw:8033/uploads/$picPath";
|
||||
}
|
||||
Reference in New Issue
Block a user