ikinci temizlik tamamlandı
This commit is contained in:
@@ -0,0 +1,649 @@
|
||||
# DevQMS Developer Get Started Guide
|
||||
|
||||
## Table of Contents
|
||||
1. [Project Overview](#project-overview)
|
||||
2. [Architecture Overview](#architecture-overview)
|
||||
3. [Core Components](#core-components)
|
||||
4. [Module System](#module-system)
|
||||
5. [DevExtreme Integration](#devextreme-integration)
|
||||
6. [Admin-AJAX System](#admin-ajax-system)
|
||||
7. [Save Trigger System](#save-trigger-system)
|
||||
8. [Batch Excel Operations](#batch-excel-operations)
|
||||
9. [Development Workflow](#development-workflow)
|
||||
10. [Common Patterns](#common-patterns)
|
||||
11. [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Project Overview
|
||||
|
||||
DevQMS is a Quality Management System (QMS) built on Laravel framework with advanced features including:
|
||||
|
||||
- **Modular Architecture**: Each module (WeldLog, TestPackage, etc.) has its own Model, Controller, and View
|
||||
- **DevExtreme Integration**: Advanced UI components for data grids, forms, and charts
|
||||
- **Dynamic Form System**: Forms are generated dynamically based on database schema
|
||||
- **Excel Import/Export**: Batch operations for data management
|
||||
- **Role-based Access Control**: User permission system with different levels
|
||||
- **Real-time Data Processing**: Save triggers for automatic data synchronization
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
app/
|
||||
├── Http/Controllers/
|
||||
│ ├── AdminController.php # Main CRUD controller
|
||||
│ ├── AdminAjaxController.php # AJAX request handler
|
||||
│ └── SaveTrigger/ # Automatic data processing
|
||||
├── DevExtreme/ # DevExtreme integration classes
|
||||
├── Models/ # Eloquent models
|
||||
└── Functions/ # Helper functions
|
||||
|
||||
resources/views/
|
||||
├── admin/ # Admin panel views
|
||||
│ └── type/ # Module views
|
||||
├── admin-ajax/ # AJAX response views
|
||||
├── components/ # Reusable components
|
||||
│ ├── blocks/ # Module blocks
|
||||
│ └── table/ # DataGrid components
|
||||
└── guide/ # Documentation
|
||||
|
||||
routes/
|
||||
└── web.php # Route definitions
|
||||
```
|
||||
|
||||
### Core Technologies
|
||||
|
||||
- **Backend**: Laravel 8+ with PHP 8+
|
||||
- **Frontend**: DevExtreme DataGrid, jQuery, Bootstrap
|
||||
- **Database**: MySQL with InnoDB
|
||||
- **File Storage**: Laravel Storage with local/cloud options
|
||||
- **Excel Processing**: Maatwebsite Excel package
|
||||
|
||||
## Core Components
|
||||
|
||||
### 1. AdminController.php
|
||||
|
||||
The central controller handling all CRUD operations for modules. Key methods:
|
||||
|
||||
```php
|
||||
// Read operations
|
||||
public function tableToJson(Request $request, string $tableName)
|
||||
public function getDetail(Request $request, string $tableName, string $columnName, string $value)
|
||||
|
||||
// Write operations
|
||||
public function insertJson(Request $request, string $tableName)
|
||||
public function saveJson(Request $request, string $tableName)
|
||||
public function removeJson(Request $request, string $tableName)
|
||||
|
||||
// Excel operations
|
||||
public function importExcel(Request $request, string $tableName)
|
||||
public function exportExcel(Request $request, string $tableName, string $fileName)
|
||||
```
|
||||
|
||||
**Important**: All modules use this centralized controller - no need to create individual controllers for basic CRUD operations.
|
||||
|
||||
### 2. AdminAjaxController.php
|
||||
|
||||
Handles AJAX requests through view-based routing:
|
||||
|
||||
```php
|
||||
public function index(Request $request, string $var) {
|
||||
$url = "admin-ajax.$var";
|
||||
return view($url, array("request" => $request));
|
||||
}
|
||||
```
|
||||
|
||||
AJAX views are located in `resources/views/admin-ajax/` and follow the naming pattern `{action}.blade.php`.
|
||||
|
||||
### 3. DevExtreme Integration
|
||||
|
||||
#### DbSet.php
|
||||
Custom query builder for DevExtreme DataGrid:
|
||||
|
||||
```php
|
||||
$dbSet = new DbSet($mySQL, 'table_name');
|
||||
$result = $dbSet->Select(['id', 'name'])
|
||||
->Filter(['status' => 'active'])
|
||||
->OrderBy('name')
|
||||
->SkipTake(0, 10)
|
||||
->AsArray();
|
||||
```
|
||||
|
||||
#### Utils.php
|
||||
Helper functions for data processing and SQL escaping.
|
||||
|
||||
## Module System
|
||||
|
||||
### Creating a New Module
|
||||
|
||||
1. **Create Model and Migration**:
|
||||
```php
|
||||
// app/Models/NewModule.php
|
||||
class NewModule extends Model {
|
||||
protected $table = 'new_modules';
|
||||
protected $primaryKey = 'id';
|
||||
public $timestamps = true;
|
||||
}
|
||||
```
|
||||
|
||||
2. **Create View Template**:
|
||||
```php
|
||||
// resources/views/admin/type/new-module.blade.php
|
||||
<?php
|
||||
use App\Models\NewModule;
|
||||
|
||||
$title = "New Module";
|
||||
$tableName = "new_modules";
|
||||
$listDatas = NewModule::orderBy("id","DESC")->paginate(setting('row_count'));
|
||||
|
||||
$blockGroup = [
|
||||
'General Info' => [
|
||||
'name',
|
||||
'description',
|
||||
],
|
||||
'Details' => [
|
||||
'status',
|
||||
'created_at',
|
||||
],
|
||||
];
|
||||
|
||||
$relationDatas = [
|
||||
'status' => [
|
||||
'type' => 'select',
|
||||
'datas' => [
|
||||
'active' => 'Active',
|
||||
'inactive' => 'Inactive'
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$firstUploadFolder = 'NewModule/';
|
||||
$firstUploadTitle = 'Upload Files';
|
||||
?>
|
||||
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
@include("admin.type.document.upload")
|
||||
@include("components.blocks.module-block")
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
3. **Add to Types Table**:
|
||||
Register the module in the admin panel's Types section with:
|
||||
- Title: "New Module"
|
||||
- Slug: "new-module"
|
||||
- Fields: "name,description,status,created_at"
|
||||
|
||||
### Module Template Structure
|
||||
|
||||
#### sablon4.blade.php
|
||||
Base template for modules with these key variables:
|
||||
|
||||
```php
|
||||
$title = "Module Title"; // Page title
|
||||
$tableName = "table_name"; // Database table name
|
||||
$listDatas = Model::paginate(50); // Data source
|
||||
$blockGroup = []; // Field grouping
|
||||
$relationDatas = []; // Field type definitions
|
||||
$firstUploadFolder = 'ModuleName/'; // File upload folder
|
||||
$firstUploadTitle = 'Upload Title'; // Upload section title
|
||||
```
|
||||
|
||||
#### module-block.blade.php
|
||||
Handles the DataGrid integration and includes:
|
||||
- Column selection
|
||||
- Excel import/export
|
||||
- DataGrid component
|
||||
- Field type mapping
|
||||
|
||||
## DevExtreme Integration
|
||||
|
||||
### DataGrid Configuration
|
||||
|
||||
The DataGrid is configured in `resources/views/components/table/datagrid.blade.php` with:
|
||||
|
||||
```javascript
|
||||
var dataGrid = $("#dataGrid").dxDataGrid({
|
||||
dataSource: dataSource,
|
||||
keyExpr: "{{$tableName}}",
|
||||
allowColumnResizing: true,
|
||||
allowColumnReordering: true,
|
||||
showBorders: true,
|
||||
filterRow: {
|
||||
visible: true
|
||||
},
|
||||
searchPanel: {
|
||||
visible: true
|
||||
},
|
||||
paging: {
|
||||
pageSize: 20
|
||||
},
|
||||
pager: {
|
||||
showPageSizeSelector: true,
|
||||
allowedPageSizes: [10, 20, 50, 100]
|
||||
},
|
||||
editing: {
|
||||
mode: "popup",
|
||||
allowUpdating: true,
|
||||
allowAdding: true,
|
||||
allowDeleting: true
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Field Types
|
||||
|
||||
Supported field types in `relationDatas`:
|
||||
|
||||
```php
|
||||
$relationDatas = [
|
||||
'text_field' => ['type' => 'text'],
|
||||
'date_field' => ['type' => 'date'],
|
||||
'number_field' => ['type' => 'number'],
|
||||
'select_field' => [
|
||||
'type' => 'select',
|
||||
'datas' => ['option1' => 'Label 1', 'option2' => 'Label 2']
|
||||
],
|
||||
'link_field' => [
|
||||
'type' => 'link-search',
|
||||
'html' => '<i class="fa fa-link"></i>'
|
||||
],
|
||||
'decimal_field' => ['type' => 'decimal'],
|
||||
'checkbox_field' => ['type' => 'checkbox']
|
||||
];
|
||||
```
|
||||
|
||||
### Custom Validation
|
||||
|
||||
Add custom validation in `components/table/datagrid/validation-callback/{module}/{field}.blade.php`:
|
||||
|
||||
```javascript
|
||||
function validationCallback_fieldName(e) {
|
||||
// Custom validation logic
|
||||
if (e.value && e.value.length < 3) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
## Admin-AJAX System
|
||||
|
||||
### Creating AJAX Endpoints
|
||||
|
||||
1. **Create AJAX View**:
|
||||
```php
|
||||
// resources/views/admin-ajax/custom-action.blade.php
|
||||
@php
|
||||
$data = db('table_name')->where('condition', $request->input('value'))->get();
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'data' => $data
|
||||
]);
|
||||
@endphp
|
||||
```
|
||||
|
||||
2. **Call from JavaScript**:
|
||||
```javascript
|
||||
$.ajax({
|
||||
url: '/admin-ajax/custom-action',
|
||||
type: 'POST',
|
||||
data: {
|
||||
value: 'search_value',
|
||||
_token: csrf_token
|
||||
},
|
||||
success: function(response) {
|
||||
// Handle response
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Common AJAX Patterns
|
||||
|
||||
#### Batch Operations
|
||||
```php
|
||||
// admin-ajax/batch-operation.blade.php
|
||||
@php
|
||||
$ids = $request->input('ids', []);
|
||||
$operation = $request->input('operation');
|
||||
|
||||
foreach($ids as $id) {
|
||||
db('table_name')->where('id', $id)->update(['status' => $operation]);
|
||||
}
|
||||
|
||||
echo json_encode(['status' => 'success', 'processed' => count($ids)]);
|
||||
@endphp
|
||||
```
|
||||
|
||||
#### Data Export
|
||||
```php
|
||||
// admin-ajax/export-data.blade.php
|
||||
@php
|
||||
$query = $request->input('query');
|
||||
$data = DB::select($query);
|
||||
|
||||
$filename = 'export_' . date('Y-m-d_H-i-s') . '.xlsx';
|
||||
Excel::store(new ExportExcel($data), $filename);
|
||||
|
||||
echo json_encode(['status' => 'success', 'file' => $filename]);
|
||||
@endphp
|
||||
```
|
||||
|
||||
## Save Trigger System
|
||||
|
||||
### Overview
|
||||
|
||||
Save triggers automatically process data changes and maintain data consistency across related tables.
|
||||
|
||||
### Trigger Structure
|
||||
|
||||
```php
|
||||
// app/Http/Controllers/SaveTrigger/{table_name}.php
|
||||
<?php
|
||||
use App\Models\RelatedModel;
|
||||
|
||||
$id = $request['key'];
|
||||
$data = db($tableName)->where("id", $id)->first();
|
||||
|
||||
// Detect changed fields
|
||||
$changedFields = [];
|
||||
foreach ($data as $key => $value) {
|
||||
if (isset($beforeData->$key) && $beforeData->$key != $value) {
|
||||
$changedFields[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute related updates
|
||||
if (in_array('status', $changedFields)) {
|
||||
// Update related records
|
||||
RelatedModel::where('parent_id', $id)
|
||||
->update(['status' => $data->status]);
|
||||
}
|
||||
```
|
||||
|
||||
### Common Trigger Patterns
|
||||
|
||||
#### Status Synchronization
|
||||
```php
|
||||
// Update related records when status changes
|
||||
if (in_array('status', $changedFields)) {
|
||||
$newStatus = $data->status;
|
||||
|
||||
// Update child records
|
||||
db('child_table')->where('parent_id', $id)
|
||||
->update(['status' => $newStatus]);
|
||||
|
||||
// Update summary tables
|
||||
$summary = db('summary_table')->where('parent_id', $id)->first();
|
||||
if ($summary) {
|
||||
$summary->update(['last_status' => $newStatus]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Calculated Fields
|
||||
```php
|
||||
// Recalculate totals when related fields change
|
||||
if (array_intersect(['quantity', 'unit_price'], $changedFields)) {
|
||||
$total = $data->quantity * $data->unit_price;
|
||||
|
||||
db($tableName)->where('id', $id)
|
||||
->update(['total' => $total]);
|
||||
}
|
||||
```
|
||||
|
||||
#### Cross-Table Updates
|
||||
```php
|
||||
// Update related tables when key fields change
|
||||
if (in_array('project_id', $changedFields)) {
|
||||
$newProjectId = $data->project_id;
|
||||
|
||||
// Update all related records
|
||||
db('related_table')->where('parent_id', $id)
|
||||
->update(['project_id' => $newProjectId]);
|
||||
}
|
||||
```
|
||||
|
||||
## Batch Excel Operations
|
||||
|
||||
### Import Process
|
||||
|
||||
1. **File Upload**: Users upload Excel files through the interface
|
||||
2. **Validation**: System validates data format and required fields
|
||||
3. **Processing**: Data is processed in batches to handle large files
|
||||
4. **Save Triggers**: Each row triggers the appropriate save triggers
|
||||
5. **Progress Tracking**: Real-time progress updates via AJAX
|
||||
|
||||
### Export Process
|
||||
|
||||
1. **Query Building**: Dynamic SQL query based on filters
|
||||
2. **Data Retrieval**: Fetch data with pagination for large datasets
|
||||
3. **Formatting**: Apply formatting and styling
|
||||
4. **File Generation**: Create Excel file with multiple sheets if needed
|
||||
5. **Download**: Provide download link to user
|
||||
|
||||
### Implementation Example
|
||||
|
||||
```php
|
||||
// Batch Excel Import
|
||||
public function importExcel(Request $request, string $tableName) {
|
||||
$file = $request->file('file');
|
||||
$import = new ImportExcel($tableName);
|
||||
|
||||
Excel::import($import, $file);
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'imported' => $import->getRowCount()
|
||||
]);
|
||||
}
|
||||
|
||||
// Batch Excel Export
|
||||
public function exportExcel(Request $request, string $tableName, string $fileName = "") {
|
||||
$query = $request->input('query');
|
||||
$data = DB::select($query);
|
||||
|
||||
$fileName = $fileName ?: $tableName . '_' . date('Y-m-d_H-i-s');
|
||||
|
||||
return Excel::download(new ExportExcel($data), $fileName . '.xlsx');
|
||||
}
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### 1. Environment Setup
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone [repository-url]
|
||||
cd dev
|
||||
|
||||
# Install dependencies
|
||||
composer install
|
||||
npm install
|
||||
|
||||
# Configure environment
|
||||
cp .env.example .env
|
||||
php artisan key:generate
|
||||
|
||||
# Run migrations
|
||||
php artisan migrate
|
||||
|
||||
# Start development server
|
||||
php artisan serve
|
||||
```
|
||||
|
||||
### 2. Creating New Features
|
||||
|
||||
1. **Database Changes**:
|
||||
```bash
|
||||
php artisan make:migration create_new_table
|
||||
php artisan migrate
|
||||
```
|
||||
|
||||
2. **Model Creation**:
|
||||
```bash
|
||||
php artisan make:model NewModel
|
||||
```
|
||||
|
||||
3. **View Template**:
|
||||
- Copy `sablon4.blade.php` as base
|
||||
- Customize variables and field groups
|
||||
- Add to Types table
|
||||
|
||||
4. **Save Triggers** (if needed):
|
||||
- Create trigger file in `SaveTrigger/`
|
||||
- Define change detection logic
|
||||
- Implement cross-table updates
|
||||
|
||||
### 3. Testing
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
php artisan test
|
||||
|
||||
# Test specific module
|
||||
php artisan test --filter=NewModuleTest
|
||||
```
|
||||
|
||||
### 4. Deployment
|
||||
|
||||
```bash
|
||||
# Production deployment
|
||||
composer install --optimize-autoloader --no-dev
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### 1. Dynamic Field Handling
|
||||
|
||||
```php
|
||||
// Get field types from database
|
||||
$fieldTypes = [];
|
||||
foreach($columns as $column) {
|
||||
$fieldTypes[$column] = table_column_type($tableName, $column);
|
||||
}
|
||||
|
||||
// Apply custom field types
|
||||
$relationDatas = [
|
||||
'status' => ['type' => 'select', 'datas' => $statusOptions],
|
||||
'date_field' => ['type' => 'date'],
|
||||
];
|
||||
```
|
||||
|
||||
### 2. Permission Checking
|
||||
|
||||
```php
|
||||
// Check user permissions
|
||||
if (!isAuth($tableName, 'write')) {
|
||||
return response()->json(['error' => 'Permission denied'], 403);
|
||||
}
|
||||
|
||||
// Role-based access
|
||||
if (!isAdmin()) {
|
||||
// Limited access logic
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Data Validation
|
||||
|
||||
```php
|
||||
// Custom validation in save triggers
|
||||
$requiredFields = ['name', 'email', 'status'];
|
||||
foreach($requiredFields as $field) {
|
||||
if (empty($data->$field)) {
|
||||
throw new Exception("Field $field is required");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Error Handling
|
||||
|
||||
```php
|
||||
try {
|
||||
// Database operation
|
||||
DB::transaction(function() use ($data) {
|
||||
// Complex operations
|
||||
});
|
||||
} catch (Exception $e) {
|
||||
Log::error('Operation failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'data' => $data
|
||||
]);
|
||||
|
||||
return response()->json(['error' => 'Operation failed'], 500);
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **DataGrid Not Loading**:
|
||||
- Check browser console for JavaScript errors
|
||||
- Verify AJAX endpoint returns valid JSON
|
||||
- Check network tab for failed requests
|
||||
|
||||
2. **Save Triggers Not Working**:
|
||||
- Verify trigger file exists in `SaveTrigger/`
|
||||
- Check database permissions
|
||||
- Review error logs
|
||||
|
||||
3. **Excel Import Failures**:
|
||||
- Validate Excel file format
|
||||
- Check column mappings
|
||||
- Verify required fields are present
|
||||
|
||||
4. **Permission Errors**:
|
||||
- Check user level in database
|
||||
- Verify module permissions
|
||||
- Review middleware configuration
|
||||
|
||||
### Debug Tools
|
||||
|
||||
1. **Laravel Telescope** (if enabled):
|
||||
```
|
||||
/telescope
|
||||
```
|
||||
|
||||
2. **Database Logging**:
|
||||
```php
|
||||
DB::enableQueryLog();
|
||||
// ... operations
|
||||
dd(DB::getQueryLog());
|
||||
```
|
||||
|
||||
3. **DevExtreme Debug**:
|
||||
```javascript
|
||||
// Enable DevExtreme debug mode
|
||||
DevExpress.config({ debug: true });
|
||||
```
|
||||
|
||||
### Performance Optimization
|
||||
|
||||
1. **Database Indexing**:
|
||||
```sql
|
||||
CREATE INDEX idx_table_column ON table_name(column_name);
|
||||
```
|
||||
|
||||
2. **Query Optimization**:
|
||||
```php
|
||||
// Use eager loading for relationships
|
||||
$data = Model::with('relation')->get();
|
||||
```
|
||||
|
||||
3. **Caching**:
|
||||
```php
|
||||
// Cache frequently accessed data
|
||||
$data = Cache::remember('key', 3600, function() {
|
||||
return Model::all();
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
This guide provides a comprehensive overview of the DevQMS system. For specific module documentation, refer to the individual guide files in the `guide/` directory. Always test changes in a development environment before deploying to production.
|
||||
Reference in New Issue
Block a user