added controller for QR photo upload and inserted route for it. added functional for multiple photo upload.
This commit is contained in:
parent
8978980901
commit
7ad20993d9
@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Userarea;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class UploadPhotosMobileController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$iddatadb = $request->query('iddatadb');
|
||||||
|
|
||||||
|
if (empty($iddatadb)) {
|
||||||
|
return response('ID riga non fornito', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the upload form
|
||||||
|
return view('userarea.upload_photos_mobile', [
|
||||||
|
'iddatadb' => $iddatadb
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function upload(Request $request)
|
||||||
|
{
|
||||||
|
// Validation
|
||||||
|
$request->validate([
|
||||||
|
'photo' => 'required|file|mimes:jpeg,png,gif,heic,heif|max:5120', // 5MB
|
||||||
|
'iddatadb' => 'required|integer'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$iddatadb = $request->input('iddatadb');
|
||||||
|
$photo = $request->file('photo');
|
||||||
|
$iduserlogin = auth()->id(); // assuming Laravel authentication
|
||||||
|
|
||||||
|
// Check if user exists
|
||||||
|
$userExists = DB::table('auth_users')->where('id', $iduserlogin)->exists();
|
||||||
|
if (!$userExists) {
|
||||||
|
return response()->json(['success' => false, 'message' => 'Utente non valido']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload folder
|
||||||
|
$uploadDir = public_path('photostrf');
|
||||||
|
if (!is_dir($uploadDir)) {
|
||||||
|
mkdir($uploadDir, 0755, true);
|
||||||
|
}
|
||||||
|
if (!is_writable($uploadDir)) {
|
||||||
|
return response()->json(['success' => false, 'message' => 'La cartella photostrf non è scrivibile']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// New filename
|
||||||
|
$timestamp = now()->format('YmdHis');
|
||||||
|
$originalName = pathinfo($photo->getClientOriginalName(), PATHINFO_FILENAME);
|
||||||
|
$extension = strtolower($photo->getClientOriginalExtension());
|
||||||
|
|
||||||
|
$newFileName = "{$iddatadb}-{$timestamp}-{$originalName}.{$extension}";
|
||||||
|
$destination = $uploadDir . '/' . $newFileName;
|
||||||
|
|
||||||
|
// Move uploaded file
|
||||||
|
$photo->move($uploadDir, $newFileName);
|
||||||
|
|
||||||
|
// Save DB record
|
||||||
|
DB::table('datadb_photos')->insert([
|
||||||
|
'iddatadb' => $iddatadb,
|
||||||
|
'file_path' => $newFileName,
|
||||||
|
'file_name' => $newFileName,
|
||||||
|
'uploaded_by' => $iduserlogin
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json(['success' => true, 'message' => 'Foto caricata con successo']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,13 +14,18 @@ if (!$iddatadb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("SELECT file_path FROM datadb_photos WHERE iddatadb = :iddatadb LIMIT 1");
|
// Adjust the query to select all photo paths for the given iddatadb
|
||||||
|
$stmt = $pdo->prepare("SELECT file_path FROM datadb_photos WHERE iddatadb = :iddatadb");
|
||||||
$stmt->execute([':iddatadb' => $iddatadb]);
|
$stmt->execute([':iddatadb' => $iddatadb]);
|
||||||
$photo = $stmt->fetch(PDO::FETCH_ASSOC);
|
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if ($photo && $photo['file_path']) {
|
if ($photos && count($photos) > 0) {
|
||||||
$fullPath = '../photostrf/' . $photo['file_path']; // Assumi che le foto siano nella cartella photostrf
|
// Prepare an array of full file paths
|
||||||
echo json_encode(['success' => true, 'file_path' => $fullPath]);
|
$photoPaths = array_map(function($photo) {
|
||||||
|
return '../photostrf/' . $photo['file_path']; // Assuming the photos are stored in the "photostrf" folder
|
||||||
|
}, $photos);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'photos' => $photoPaths]); // Return an array of photo paths
|
||||||
} else {
|
} else {
|
||||||
echo json_encode(['success' => false, 'message' => 'Nessuna foto trovata']);
|
echo json_encode(['success' => false, 'message' => 'Nessuna foto trovata']);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,29 +13,32 @@
|
|||||||
<ul id="partsList" class="list-group"></ul>
|
<ul id="partsList" class="list-group"></ul>
|
||||||
<table class="table table-striped table-sm mt-3" id="partsTable">
|
<table class="table table-striped table-sm mt-3" id="partsTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Num. Parte</th>
|
<th>Num. Parte</th>
|
||||||
<th>Descrizione Parte</th>
|
<th>Descrizione Parte</th>
|
||||||
<th>Azioni</th>
|
<th>Azioni</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="partsTableBody">
|
<tbody id="partsTableBody">
|
||||||
<tr data-part-id="new">
|
<tr data-part-id="new">
|
||||||
<td><input type="number" class="form-control form-control-sm part-number" value="1" style="width: 80px;"></td>
|
<td><input type="number" class="form-control form-control-sm part-number" value="1" style="width: 80px;"></td>
|
||||||
<td><input type="text" class="form-control form-control-sm part-description" placeholder="Inserisci descrizione" style="width: 100%;"></td>
|
<td><input type="text" class="form-control form-control-sm part-description" placeholder="Inserisci descrizione" style="width: 100%;"></td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="btn btn-success btn-sm add-row" style="padding: 0.1rem 0.3rem; font-size: 0.8rem;"><i class="fas fa-plus fa-xs"></i></button>
|
<button type="button" class="btn btn-success btn-sm add-row" style="padding: 0.1rem 0.3rem; font-size: 0.8rem;"><i class="fas fa-plus fa-xs"></i></button>
|
||||||
<button type="button" class="btn btn-primary btn-sm add-mix-row" style="padding: 0.1rem 0.3rem; font-size: 0.8rem;">M</button>
|
<button type="button" class="btn btn-primary btn-sm add-mix-row" style="padding: 0.1rem 0.3rem; font-size: 0.8rem;">M</button>
|
||||||
<button type="button" class="btn btn-danger btn-sm remove-row" style="padding: 0.1rem 0.3rem; font-size: 0.8rem; display: none;"><i class="fas fa-trash fa-xs"></i></button>
|
<button type="button" class="btn btn-danger btn-sm remove-row" style="padding: 0.1rem 0.3rem; font-size: 0.8rem; display: none;"><i class="fas fa-trash fa-xs"></i></button>
|
||||||
<span class="save-status text-success" style="display: none; margin-left: 5px;"><i class="fas fa-check fa-xs"></i></span>
|
<span class="save-status text-success" style="display: none; margin-left: 5px;"><i class="fas fa-check fa-xs"></i></span>
|
||||||
<span class="save-loading text-warning" style="display: none; margin-left: 5px;"><i class="fas fa-spinner fa-spin fa-xs"></i></span>
|
<span class="save-loading text-warning" style="display: none; margin-left: 5px;"><i class="fas fa-spinner fa-spin fa-xs"></i></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h6>Foto del Campione</h6>
|
<h6>Foto del Campione</h6>
|
||||||
|
<div id="photoSelectorContainer" style="display: none;">
|
||||||
|
<!-- Dropdown or buttons for photo selection will appear here -->
|
||||||
|
</div>
|
||||||
<div style="position: relative; width: 100%; min-height: 400px;">
|
<div style="position: relative; width: 100%; min-height: 400px;">
|
||||||
<img id="samplePhoto" src="" alt="Foto del campione" style="max-width: 100%; max-height: 100%; object-fit: contain; position: absolute; top: 0; left: 0;">
|
<img id="samplePhoto" src="" alt="Foto del campione" style="max-width: 100%; max-height: 100%; object-fit: contain; position: absolute; top: 0; left: 0;">
|
||||||
<canvas id="photoCanvas" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></canvas>
|
<canvas id="photoCanvas" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></canvas>
|
||||||
@ -142,4 +145,4 @@
|
|||||||
padding: 0.1rem 0.3rem;
|
padding: 0.1rem 0.3rem;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -61,35 +61,19 @@ $(document).ready(function () {
|
|||||||
method: "GET",
|
method: "GET",
|
||||||
data: { iddatadb: iddatadb },
|
data: { iddatadb: iddatadb },
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
if (response.success && response.file_path) {
|
if (response.success) {
|
||||||
const img = $("#samplePhoto");
|
if (response.photos && response.photos.length > 1) {
|
||||||
img.attr("src", response.file_path);
|
// Multiple photos available, create a selector
|
||||||
img.on("load", function () {
|
showPhotoSelector(response.photos);
|
||||||
const container = img.parent();
|
} else if (response.photos && response.photos.length === 1) {
|
||||||
const canvas = document.getElementById("photoCanvas");
|
// Only one photo, load it directly
|
||||||
const containerWidth = container.width();
|
loadSinglePhoto(response.photos[0]);
|
||||||
const containerHeight = container.height();
|
} else {
|
||||||
const scaleX = containerWidth / img[0].naturalWidth;
|
$("#samplePhoto").attr("src", "");
|
||||||
const scaleY = containerHeight / img[0].naturalHeight;
|
alert("Nessuna foto trovata per questo TRF.");
|
||||||
const scale = Math.min(scaleX, scaleY);
|
}
|
||||||
canvas.width = img[0].naturalWidth * scale;
|
|
||||||
canvas.height = img[0].naturalHeight * scale;
|
|
||||||
canvas.style.width = `${containerWidth}px`;
|
|
||||||
canvas.style.height = `${containerHeight}px`;
|
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
ctx.drawImage(
|
|
||||||
img.get(0),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
canvas.width,
|
|
||||||
canvas.height,
|
|
||||||
);
|
|
||||||
updateMarkers();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
$("#samplePhoto").attr("src", "");
|
alert(response.message || "Errore nel caricamento della foto.");
|
||||||
alert("Nessuna foto trovata per questo TRF.");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function (xhr, status, error) {
|
error: function (xhr, status, error) {
|
||||||
@ -98,6 +82,52 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showPhotoSelector(photos) {
|
||||||
|
const selectorContainer = $("#photoSelectorContainer"); // A div to hold the photo selector
|
||||||
|
selectorContainer.empty(); // Clear any previous options
|
||||||
|
|
||||||
|
// Create a dropdown or buttons to select a photo
|
||||||
|
const selector = $('<select id="photoSelector"></select>');
|
||||||
|
photos.forEach((photo, index) => {
|
||||||
|
const option = $('<option></option>').val(photo).text(`Photo ${index + 1}`);
|
||||||
|
selector.append(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
selector.on("change", function () {
|
||||||
|
const selectedPhoto = $(this).val();
|
||||||
|
loadSinglePhoto(selectedPhoto);
|
||||||
|
});
|
||||||
|
|
||||||
|
selectorContainer.append(selector);
|
||||||
|
selectorContainer.show(); // Make sure the selector is visible
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSinglePhoto(photoPath) {
|
||||||
|
const img = $("#samplePhoto");
|
||||||
|
img.attr("src", photoPath);
|
||||||
|
|
||||||
|
img.on("load", function () {
|
||||||
|
const container = img.parent();
|
||||||
|
const canvas = document.getElementById("photoCanvas");
|
||||||
|
const containerWidth = container.width();
|
||||||
|
const containerHeight = container.height();
|
||||||
|
const scaleX = containerWidth / img[0].naturalWidth;
|
||||||
|
const scaleY = containerHeight / img[0].naturalHeight;
|
||||||
|
const scale = Math.min(scaleX, scaleY);
|
||||||
|
|
||||||
|
canvas.width = img[0].naturalWidth * scale;
|
||||||
|
canvas.height = img[0].naturalHeight * scale;
|
||||||
|
canvas.style.width = `${containerWidth}px`;
|
||||||
|
canvas.style.height = `${containerHeight}px`;
|
||||||
|
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.drawImage(img.get(0), 0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
updateMarkers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function addNewRow(nextPartNumber, isMix = false) {
|
function addNewRow(nextPartNumber, isMix = false) {
|
||||||
const description = isMix ? "Mix" : "";
|
const description = isMix ? "Mix" : "";
|
||||||
const newRow = `
|
const newRow = `
|
||||||
|
|||||||
@ -44,7 +44,7 @@ $photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
$photoBasePath = '../photostrf/';
|
$photoBasePath = '../photostrf/';
|
||||||
|
|
||||||
// Genera l'URL per il QR code
|
// Genera l'URL per il QR code
|
||||||
$baseUrl = "http://localhost/trf_certest/public/userarea/"; // Sostituisci con il tuo dominio
|
$baseUrl = "http://localhost:8000/userarea/"; // Sostituisci con il tuo dominio
|
||||||
$uploadUrl = $baseUrl . "upload_photos_mobile.php?iddatadb=" . $iddatadb;
|
$uploadUrl = $baseUrl . "upload_photos_mobile.php?iddatadb=" . $iddatadb;
|
||||||
|
|
||||||
// Genera il QR code con endroid/qr-code 6.0.6
|
// Genera il QR code con endroid/qr-code 6.0.6
|
||||||
@ -224,4 +224,4 @@ $result->saveToFile($qrCodeFile);
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -142,4 +142,4 @@ $sampleCode = $row['sample_code'] ?? 'Non disponibile';
|
|||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
<script src="{{ url(mix('assets/js/vendor.js')) }}"></script>
|
<script src="{{ url(mix('assets/js/vendor.js')) }}"></script>
|
||||||
<script src="{{ url('assets/js/as/app.js') }}"></script>
|
<script src="{{ url('assets/js/as/app.js') }}"></script>
|
||||||
|
<script src="{{ url('assets/js/alpinejs.js') }}"></script>
|
||||||
@yield('scripts')
|
@yield('scripts')
|
||||||
|
|
||||||
@hook('app:scripts')
|
@hook('app:scripts')
|
||||||
|
|||||||
@ -188,3 +188,11 @@ Route::group(['prefix' => 'install'], function () {
|
|||||||
Route::get('complete', 'InstallController@complete')->name('install.complete');
|
Route::get('complete', 'InstallController@complete')->name('install.complete');
|
||||||
Route::get('error', 'InstallController@error')->name('install.error');
|
Route::get('error', 'InstallController@error')->name('install.error');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
use App\Vanguard\Http\Controllers\Userarea\UploadPhotosMobileController;
|
||||||
|
|
||||||
|
Route::get('/userarea/upload-photos-mobile', [UploadPhotosMobileController::class, 'index'])
|
||||||
|
->name('userarea.upload-photos-mobile.index');
|
||||||
|
|
||||||
|
Route::post('/userarea/upload-photos-mobile', [UploadPhotosMobileController::class, 'upload'])
|
||||||
|
->name('userarea.upload-photos-mobile.upload');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user