fix data display

This commit is contained in:
misya 2025-05-29 09:23:13 +08:00
parent 755acb1a84
commit 9bd5774e08
2 changed files with 172 additions and 142 deletions

View File

@ -11,6 +11,7 @@ using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using MySqlConnector;
using Org.BouncyCastle.Asn1.Cms;
namespace PSTW_CentralSystem.Areas.MMS.Controllers
{
@ -18,25 +19,40 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
{
// From tbl_marine_tarball
public int Id { get; set; }
public string StationID { get; set; }
public string Longitude { get; set; }
public string Latitude { get; set; }
public required string StationID { get; set; }
public required string Longitude { get; set; }
public required string Latitude { get; set; }
public DateTime DateSample { get; set; }
public TimeSpan TimeSample { get; set; }
public string ClassifyID { get; set; }
public string OptionalName1 { get; set; }
public string OptionalName2 { get; set; }
public string OptionalName3 { get; set; }
public string OptionalName4 { get; set; }
public string FirstSampler { get; set; }
public required string ClassifyID { get; set; }
public string? OptionalName1 { get; set; }
public string? OptionalName2 { get; set; }
public string? OptionalName3 { get; set; }
public string? OptionalName4 { get; set; }
public required string FirstSampler { get; set; }
// From joined tables
public string LocationName { get; set; } // From tbl_marine_station
public string StateName { get; set; } // From tbl_state
public string FullName { get; set; } // From tbl_user
public string LevelName { get; set; } // From tbl_level
public required string LocationName { get; set; } // From tbl_marine_station
public required string StateName { get; set; } // From tbl_state
public required string FullName { get; set; } // From tbl_user
public required string LevelName { get; set; } // From tbl_level
}
public class TarBallGroupViewModel
{
public List<int> Id { get; set; } = new List<int>();
public required string StationID { get; set; }
public required string Date { get; set; }
public required int TimeSampleCount { get; set; }
public required string LatestTime {get; set; }
public List<TarBallTimeSample> TimeSamples { get; set; } = new List<TarBallTimeSample>();
}
public class TarBallTimeSample
{
public required int Id { get; set; }
public string Time { get; set; }
}
[Area("MMS")]
public class MarineController : Controller
{
@ -55,28 +71,37 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
return View();
}
public IActionResult TarBallForm()//Queries the database and returns a view with tarball data
public class StationDateGroup
{
public required string StationID { get; set; }
public DateTime DateSample { get; set; }
public List<TarballPdfDto> TimeSamples { get; set; } = new List<TarballPdfDto>();
}
public IActionResult TarBallForm()
{
try
{
var marineTarballs = _context.MarineTarballs //ERRORRRRRRR======================================
var marineTarballs = _context.MarineTarballs
.Select(t => new
{
t.Id,
Date = t.DateSample.ToString("yyyy/MM/dd"),
Station = t.StationID
station = t.StationID,
date = t.DateSample.ToString("yyyy/MM/dd"),
time = t.TimeSample.ToString(@"hh\:mm\:ss"),
fullDate = t.DateSample, // Keep DateTime for sorting
t.TimeSample
})
.AsEnumerable()
.OrderByDescending(t => t.fullDate)
.ThenByDescending(t => t.TimeSample)
.ToList();
Console.WriteLine($"Marine Tarballs Count: {marineTarballs.Count}");
return View(marineTarballs);
}
catch (Exception ex)
{
// Show the real error in the browser (for debugging only)
return Content($"Error: {ex.Message}<br/>{ex.StackTrace}", "text/html");
}
}
[HttpGet] // Explicitly mark as a GET endpoint
@ -222,7 +247,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
}
}
public async Task<IActionResult> GenerateReport(int id)//calls GeneratePdfResponse to generate a PDF for inline viewing
public async Task<IActionResult> GenerateReport(int id)
{
return await GeneratePdfResponse(id, true);
}
@ -239,7 +264,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
{
// Add timeout for safety
var task = Task.Run(() => GeneratePdfResponse(id, false));
if (task.Wait(TimeSpan.FromSeconds(30))) // 30 second timeout
if (task.Wait(TimeSpan.FromSeconds(30))) // 30-second timeout
{
return task.Result;
}
@ -254,63 +279,55 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
private async Task<IActionResult> GeneratePdfResponse(int id, bool forceDownload)
{
Console.WriteLine($"Requested ID in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {id}");
// Temporary network connection test
try
{
Console.WriteLine("Testing network connection...");
_networkAccessService.ConnectToNetworkPath();
Console.WriteLine("Network connected successfully!");
_networkAccessService.DisconnectFromNetworkShare();
}
catch (Exception ex)
{
Console.WriteLine($"NETWORK ERROR: {ex.Message}");
return StatusCode(500, $"Cannot access network: {ex.Message}");
}
try
{
// Connect to the network path
_networkAccessService.ConnectToNetworkPath();
// ===== 1. NEW SQL QUERY APPROACH =====
var record = await _context.MarineTarballs.FirstOrDefaultAsync(t => t.Id == id);
if (record == null)
return NotFound($"No record found for Id: {id}");
// Retrieve all entries for the same StationID and DateSample
var query = @"
SELECT
marine.*,
station.LocationName,
state.StateName,
user.FullName,level.LevelName
user.FullName,
level.LevelName
FROM tbl_marine_tarball marine
JOIN tbl_marine_station station ON marine.StationID = station.StationID
JOIN tbl_state state ON station.StateID = state.StateID
JOIN tbl_user user ON marine.FirstSampler = user.FullName -- Corrected column name
JOIN tbl_user user ON marine.FirstSampler = user.FullName
JOIN tbl_level level ON user.LevelID = level.LevelID
WHERE marine.Id = @id";
WHERE marine.Id=@id";
var tarball = await _context.Database
var tarballEntries = await _context.Database
.SqlQueryRaw<TarballPdfDto>(query, new MySqlParameter("@id", id))
.FirstOrDefaultAsync();
.ToListAsync();
if (tarball == null)
return NotFound("Record not found");
if (!tarballEntries.Any())
return NotFound($"No records found for Id: {id}");
//Prepare boolean values for PDF
var pdfList = new List<IActionResult>();
// Iterate over each unique TimeSample within the same DateSample
foreach (var timeGroup in tarballEntries.GroupBy(t => t.TimeSample))
{
var tarball = timeGroup.First(); // Use first entry per time sample
// Classification logic remains unchanged
bool tarBallYes = tarball.ClassifyID != "NO";
bool tarBallNo = tarball.ClassifyID == "NO";
bool isSand = tarball.ClassifyID == "SD";
bool isNonSandy = tarball.ClassifyID == "NS";
bool isCoquina = tarball.ClassifyID == "CO";
// ===== 2. Get Images from path =====
var sampleDateString = tarball.DateSample.ToString("yyyyMMdd");
//var sampleTimeString = tarball.TimeSample.ToString("hhmmss");
var sampleTimePrefix = ((int)tarball.TimeSample.TotalHours).ToString("D2") +
tarball.TimeSample.Minutes.ToString("D2");
// Construct image paths ensuring correct naming format
var stationFolder = Path.Combine(PhotoBasePath, tarball.StationID);
var sampleDateString = tarball.DateSample.ToString("yyyyMMdd");
var sampleTimeString = tarball.TimeSample.ToString(@"hhmmss");
//Image collection
var stationImages = new Dictionary<string, string>();
if (Directory.Exists(stationFolder))
@ -321,7 +338,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
{ "RIGHTSIDECOASTALVIEW", null },
{ "DRAWINGVERTICALLINES", null },
{ "DRAWINGHORIZONTALLINES", null },
{ "OPTIONAL01", null }, // Will remain null if not found
{ "OPTIONAL01", null },
{ "OPTIONAL02", null },
{ "OPTIONAL03", null },
{ "OPTIONAL04", null }
@ -332,7 +349,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
var fileName = Path.GetFileNameWithoutExtension(imagePath);
foreach (var type in imageTypes.Keys.ToList())
{
if (fileName.EndsWith(type, StringComparison.OrdinalIgnoreCase))
if (fileName.StartsWith($"{tarball.StationID}_{sampleDateString}_{sampleTimeString}") &&
fileName.Contains(type, StringComparison.OrdinalIgnoreCase))
{
imageTypes[type] = imagePath;
break;
@ -341,7 +359,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
}
stationImages = imageTypes;
}
//Mandatory images
// Validate mandatory images exist
var mandatoryImages = new List<string>
{
"LEFTSIDECOASTALVIEW",
@ -350,16 +369,16 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
"DRAWINGHORIZONTALLINES"
};
foreach(var mandatoryType in mandatoryImages)
foreach (var mandatoryType in mandatoryImages)
{
if(!stationImages.ContainsKey(mandatoryType))
if (!stationImages.ContainsKey(mandatoryType) || stationImages[mandatoryType] == null)
{
return StatusCode(400, $"Missing mandatory image: {mandatoryType}");
return StatusCode(400, $"Missing mandatory image: {mandatoryType} for {tarball.StationID} on {tarball.DateSample}");
}
}
// ===== 3. GENERATE PDF (ADAPTED FOR NEW DTO) =====
var pdf = new TarBallPDF(
// Generate PDF using existing classification and sorting logic
var pdfDocument = new TarBallPDF(
tarball.StateName,
tarball.StationID,
tarball.LocationName,
@ -390,23 +409,26 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
tarball.LevelName
).GeneratePdf();
return forceDownload
? File(pdf, "application/pdf", $"{tarball.StationID}_{tarball.DateSample:yyyyMMdd}_{tarball.TimeSample:hhmmss}.pdf")
: File(pdf, "application/pdf");
string pdfFileName = $"{tarball.StationID}_{tarball.DateSample:yyyyMMdd}_{tarball.TimeSample:hhmmss}.pdf";
pdfList.Add(
forceDownload
? File(pdfDocument, "application/pdf", pdfFileName)
: File(pdfDocument, "application/pdf")
);
}
return pdfList.Count == 1 ? pdfList.First() : Ok(pdfList);
}
catch (Exception ex)
{
var errorMessage = ex.InnerException != null
? $"{ex.Message} (Inner: {ex.InnerException.Message})"
: ex.Message;
return Content($"PDF generation failed: {errorMessage}<br/>{ex.StackTrace}", "text/html");
return StatusCode(500, $"Error: {ex.Message}");
}
finally
{
_networkAccessService.DisconnectFromNetworkShare();
}
}
private bool IsImageValid(string imagePath)
{
try

View File

@ -102,15 +102,21 @@
return []; // Return an empty array if no data is available
}
// Extract all years from the data
const allYears = this.dataFromServer.map(data => new Date(data.date).getFullYear());
// Extract all years from the data (handling both FormattedDate and date)
const allYears = this.dataFromServer.map(data => {
const dateStr = data.Date || data.date; // Handle both cases
return new Date(dateStr).getFullYear();
});
// Find the minimum and maximum years
const minYear = Math.min(...allYears);
const maxYear = Math.max(...allYears);
// Generate a range of years from minYear to maxYear
return Array.from({ length: maxYear - minYear + 1 }, (_, i) => (minYear + i).toString());
return Array.from(
{ length: maxYear - minYear + 1 },
(_, i) => (minYear + i).toString()
);
},
sortedFilteredData() {
// If no filters are applied, return all data sorted by descending date
@ -154,11 +160,11 @@
"data": null,
"render": (data, type, row, meta) => meta.row + 1 // Dynamically generate "No."
},
{ "data": "date", "render": (data) => new Date(data).toLocaleDateString('en-GB') },
{ "data": "date"},
{ "data": "station" },
{
"data": null,
"render": () => `
"render": (data) => `
<button class="btn btn-success">Approve</button>
<button class="btn btn-danger">Reject</button>
`
@ -166,8 +172,10 @@
{
"data": null,
"render": (data) => `
<a href="/MMS/Marine/ViewPDF?id=${data.id}" class="btn btn-primary" target="_blank">View PDF</a>
<a href="/MMS/Marine/GenerateReport?id=${data.id}" class="btn btn-primary">Download PDF</a>
<a href="/MMS/Marine/ViewPDF?stationId=${data.Id}"
class="btn btn-primary" target="_blank">View PDF</a>
<a href="/MMS/Marine/GenerateReport?stationId=${data.Id}"
class="btn btn-primary">Download PDF</a>
`
}
],