netliva/symfony-fast-search-table

Symfony 快速搜索表库

v1.1.0 2024-02-24 09:43 UTC

This package is auto-updated.

Last update: 2024-09-24 06:37:50 UTC


README

Symfony 用于缓存过滤的表格列表结构。

该系统不是直接从数据库中批量提取数据来进行列表显示,而是为了实现更快的列表显示,将数据保存在缓存文件中,并通过页面内查询以最快速度进行列表显示。

安装

composer require netliva/symfony-fast-search-table

激活 Bundle

然后,在您的项目 "app/AppKernel.php" 文件中,通过将包添加到已注册包列表中来激活它

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Netliva\SymfonyFastSearchBundle\NetlivaSymfonyFastSearchBundle(),
        );

        // ...
    }

    // ...
}

页面路径定义

为了在页面上加载表格数据,需要执行以下路径定义。

NetlivaFastTableBundle:
  resource: "@NetlivaSymfonyFastSearchBundle/Controller/"
  type: annotation
  prefix: /fasttable
  • prefix: 您可以输入一个用于前缀的路径值。

配置设置

配置您将创建的表格的创建方式和方式。

# Symfony >= 4.0. Create a dedicated netliva_config.yaml in config/packages with:
# Symfony >= 3.3. Add in your app/config/config.yml:

# Netliva Fast Search
netliva_symfony_fast_search:
  cache_path: %kernel.cache_dir%/../shared/fastsearch
  default_limit_per_page: 15
  default_input_class: 'form-control'
  entities: ~
  • cache_path: 定义前缓存文件在哪里创建。
  • default_limit_per_page: 定义表格中每次显示多少条记录。
  • default_input_class: 定义搜索表单元素的默认 CSS 类。
  • entities: 配置将被缓存的、表格的结构。

依赖关系

快速表格需要一些 JavaScript 依赖项才能运行。如果您的系统中没有 Vue 和 Axios,请将相关链接添加到您的网站主题中;

<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

使用

假设我们有一个名为 User 的实体。并且我们假设在这个表格中,我们保存了名字 (name)、姓氏 (surname)、出生日期 (birthday) 和创建日期 (createAt) 的数据。根据这些表格数据,我们可以进行以下配置。

配置

首先,我们需要在配置文件中定义要缓存的资料。定义在 entities 标识符下。每个表格都在其下定义。您可以用您想要的任何值作为键值。我们将使用这个值在创建列表时使用。

netliva_symfony_fast_search:
  # ...
  entities:
    user_table:
      class: App\DefaultBundle\Entity\Users # Haangi entitiy için veriler önbelleğe alınacak 
      limit_per_page: 15 # Her seferinde yüklenecek veri, tanılanmazsa default_input_class geçerli olur.
      default_sort_field: createAt # varsayılan sıralama hangi field için yapılacak
      default_sorting_direction: desc # varsayılşan sıralama yönü  
      where: # Önbelleğe alınacak ve listelenecek verileri kısıtlamak için. Bu kısıtlamalar sonrası kısıtlanan veriler hiç önbelleğe alınmaz.
        - { field: createAt, expr: gte, value: -2 years, valueType: date } # son 2 yıla ait verileri önbelleğe alır
      fields: # ön belleğe alınacak verilerin listesi 
        # entitiy'deki field isimleri key olarak eklenerek liste oluşturulur.
        catId: { title: 'Kategori Idsi', field: 'category.id' }  # ilişkili entity'de id field'ını cache'e dahil ediyoruz
        name: { title: 'Adı' }  
        surname: { title: 'Soyadı' }  
        birthday: { title: 'Doğum Tarihi' } # tüm tarihler ISO 8601 tarih formati ile önbelleğe kaydedilir (2004-02-12T15:19:21+00:00 gibi)
        createAt: { title: 'Oluşturma Tarihi' }
        age: { title: 'Yaşı' } # entitiy'de olmayan veriyi ön belleğe kaydetmek için maniplasyon kullnacağız.
        # ... 
      filters: # Listeleme tablosu üzerindeki filtreleme alanının oluşturulması
        category: { type: 'hidden', fields: [catId], exp: eq, decrease_from_total_count: true } # kategory id'sine göre filtreleme yapıyoruz, filtrelenen öğeler toplam sayıdan düşülecek.
        search_box: { type: 'text', title: 'Ara', fields: [name, surname] }
        create_range: { type: 'date_range', title: 'Oluşturma', fields: [createAt] }

      cache_clear: # ilişkili başka entitiy üzerinden bir veri bu tablo için cachlenmiş ise, o entitiyde değişiklik yapıldığında bağlı bu tablodaki veririnin cache'inin temizlenmesi için yapılan tanımlama  
        Crm\DefaultBundle\Entity\OtherEntity: { reverse_fields: [ user ] } # reverse_fields ile diğer tablodan user tablosuna hangi field tanımıyla ulaşıldığı bilgisi tanımlanır. Böylece diğer tablodaki bir veri değiştirildiğinde, bağlantılı user tablolarının cache'i de düzenlenir
        Crm\DefaultBundle\Entity\AnotherEntity: { clear_all: true } # clear_all true olursa; AnotherEntity'de değişiklik yapıldığında user_table için tüm cachelenen veri silinir.

    other_table: # listelenencek diğer tablolar için tanılama yapılmaya devam edilir.
      # ...  

列表显示

{% import _self as funcs %}

{% set tableColumns = [
    {'title': 'Adı', 'releated_field': 'name'},
    {'title': 'Soyadı', 'releated_field': 'surname'},
    {'title': 'Yaşı', 'releated_field': 'age'},
    {'title': 'Oluşturma', 'releated_field': 'createAt'},
    {'title': 'İşlemler'},
] %}

<div id="bina_bilgileri_table">
    {{ get_fast_search_table('all_bids', {
        'table_class'                    : 'table table-striped table-hover table-bordered font-size-12',
        'record_variable_name'           : 'user_data',
        'table_tbody_cells_vue_template' : funcs.tBodyCells(),
        'table_columns' : tableColumns,
        'vue_variables' : {
            vueVarName: twigVarName,
        },
        'filter_values' : {
           category: category.id,
        }
    }) }}
</div>

{% macro tBodyCells() %}
	<td>[[ user_data.name ]]</td>
	<td>[[ user_data.surname ]]</td>
	<td>[[ user_data.age ]] Yaşında</td>
	<td>[[ user_data.createAtText ]]</td>
	<td>
        <a class="btn btn-xs btn-info"
           target="_blank"
           :href="'{{ path('users_show', { 'id': '__ID__' }) }}'.replace('__ID__', user_data.id)" 
        >
            Görüntüle
        </a>
	</td>
{% endmacro %}

table_tbody_cells_vue_template : 变量需要在其中发送一个 vue 模板。为此,我们使用 twig 宏。为了避免 twig 的括号与 vue 的括号混淆;我们需要将 vue 的括号用 [[ ]] 形式的角括号表示。

filter_values : 在这里确定创建的筛选器的默认值。隐藏筛选器的值也在这里发送。

record_variable_name : 定义您将使用哪个变量名来在 vue 模板内获取每个可显示的记录。

vue_variables : 您可以发送要在 vue 模板内使用的 twig 变量。

js_variables : 您可以发送要在 vue 模板内使用的 JavaScript 变量。

js_methods : 您可以发送要在 vue 模板内使用的 JavaScript 函数。

//...
'js_methods' : {
	moment: '(date) => window.moment(date)',
}
//...

components 您可以发送要在 vue 模板内导入的组件。

//...
'js_methods' : {
	'ComponentAdi': asset('vue_components/component_dosyasi.js'),
}
//...

数据处理

在将数据存入缓存之前和列表显示操作之前,您可以使用两个 event listener。您可以像以下示例中那样定义这些监听器;

services:
  #...
  user_fasttable_subscriber:
    class: App\DefaultBundle\EventListener\FastTableSubscriber
    tags:
      - { name: kernel.event_subscriber }
<?php
namespace App\DefaultBundle\EventListener\FastTableSubscriber;

use App\DefaultBundle\Entity\Users;
use Netliva\SymfonyFastSearchBundle\Events\BeforeViewEvent;
use Netliva\SymfonyFastSearchBundle\Events\NetlivaFastSearchEvents;
use Netliva\SymfonyFastSearchBundle\Events\PrepareRecordEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class FastTableSubscriber implements EventSubscriberInterface
{

	public static function getSubscribedEvents ()
	{
		return [
            NetlivaFastSearchEvents::PREPARE_RECORD => 'prepareRecord',
            NetlivaFastSearchEvents::BEFORE_VIEW => 'beforeView',
		];
	}

	public function prepareRecord (PrepareRecordEvent $event)
	{
        $entity    = $event->getEntity(); // kaydedilecek ilgili entity
        $fKey      = $event->getFKey(); // kaydedilecek field ley
        $entityKey = $event->getEntityKey(); // kayıt yapılacak tablo tanımı
        $value     = $event->getValue(); // kaydedilecek veri

        switch ($entityKey)
        {
            case 'user_table': // hangi tablo tanımlaması için işlem yapılacağının seçilmesi
                if ($entity instanceof Users) // gelen verinin bu tabloaya ait entitiy'e mi ait olduğunun kontrolü
                {
                    switch ($fKey)
                    {
                        case 'age' :
                            $value = $entity->getBirthday() ? $entity->getBirthday()->diff(new DateTime())->y : '---';
                            break;
                    }
                }
            break;
        }

        // değiştirilen veriyi kaydediyoruz
        $event->setValue($value);
	}


    public function beforeView (BeforeViewEvent $event)
    {
        // gerektiğinde filtre verileri gibi post edilen verileri alabilirsiniz
        $postedData = $event->getRequests();
        
        // listelenecek verileri döndürüyoruz
        foreach ($event->getRecords() as $key => $record)
        {
            switch ($event->getEntityKey())
            {
                // düzenleme yapacağımız tabloyu belirliyoruz
                case 'user_table':
                    // gelen oluşturma tarihi verisini, okunabilir tarih formatına çevirerek yeni bir değişken ile vue template'e gönderiyoruz
                    $record['createAtText'] = $record['createAt']?(new \DateTime($record['createAt']))->format('d.m.Y H:i'):null;
                    $event->updateRecord($key, $record);
                    break;
            }
        }
    }
}