Задать вопрос
  • Как лучше всего хранить данные о группах в бд?

    Alixx
    @Alixx Автор вопроса
    Мне подошла такая схема:
    groups
        user_id: foreign key -> users.id
        manager_id: int
        user_id, manager_id: primary key
        is_deleted: boolean
        work_id: foreign key -> works.id, nullable
        worker_1_rarity: int, nullable
        worker_2_rarity: int nullable
        worker_3_rarity: int, nullable
    
    users_groups_sets
        id_user: foreign key -> users.id (primary key)
        managers_count: int // кол-во всех управляющих
        workers_1_count: int // кол-во всех рабочих 1 уровня производительности и т.д.
        workers_2_count: int
        workers_3_count: int
        workers_4_count: int
        workers_5_count: int

    Т.к. группа не может быть сформирована без управляющего, то id управляющего можно сделать идентификатором бригады. А в группе надо знать, какого уровня рабочие там собраны, вот и указываем (для 3х возможных мест рабочих) уровни рабочие, которые были сформированы в группу.
    Свободные группы - те, в которых work_id is null и хотя бы один из worker_X_rarity is not null.
    Работающие группы - где work_id is not null.
    Свободные управляющие - где все worker_X_rarity is null.

    В интерфейсе для формирования групп надо получать данные о всех группах, управляющих и рабочих. Поэтому тут два запроса всего - из groups и users_groups_sets получить все записи по id пользователя. На уровне приложения уже формируем все данные: о свободных и работающих группах, о свободных управляющих и рабочих.

    Удалять прямо из сформированной группы нельзя ни рабочих, ни управляющего.
    Когда рабочего добавляем юзеру, то добавляем 1 к workers_X_count, где X - это уровень производительности этого рабочего.
    Когда удаляем, то отнимаем 1 от нужного workers_X_count.
    С добавлением управляющего, также +1 и, если есть запись с is_deleted == true, то просто у неё ставим false, иначе создаём запись в groups.
    Когда удаляем, то также -1, а в groups у первой найденной записи, где все worker_X_rarity is null, ставим is_deleted в true.
    Ответ написан
  • Как правильно составить POST запрос?

    Alixx
    @Alixx
    $curl = curl_init();
    
    $data = array(
        "amount" => "15",
        "currency" => "USD",
        "order_id" => "1",
        "url_return" => "https://your.site/return",
        "url_callback" => "https://your.site/callback"
    );
    
    $headers = array(
        "merchant: 8b03432e-385b-4670-8d06-064591096795",
        "sign: fe99035f86fa436181717b302b95bacff1",
        "Content-Type: application/json"
    );
    
    $options = array(
        CURLOPT_URL => "https://api.cryptomus.com/v1/payment",
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => $headers
    );
    
    curl_setopt_array($curl, $options);
    $response = curl_exec($curl);
    curl_close($curl);
    Ответ написан
    Комментировать
  • Можно ли сделать логирование всех mysql запросов чтоб подневно создавались файлы логов?

    Alixx
    @Alixx
    Можно, я сделала следующим образом, может кому пригодится:
    class SqlLoggingServiceProvider extends ServiceProvider
    {
        public function boot()
        {
            if (config("database.connections." . env('DB_CONNECTION') . ".logging")) {
                DB::listen(function ($query) {
                    Log::channel('sql') // название канала, указанное в конфиге
                        ->info($query->sql, ['time' => $query->time, 'bindings' => $query->bindings]);
                });
            }
        }
        //..
    }

    В config/database.php в нужном подключении (у меня pgsql) надо добавить строки
    'connections' => [
        //...
        'pgsql' => [
            //..
            'logging' => true,
            'channel' => 'sql', // название канала
        ]
    ],

    В config/logging.php добавляем данные о канале sql
    'channels' => [
            //..
            'sql' => [
                'driver' => 'daily',
                'path' => storage_path('sql/laravel.log'),
                'level' => 'debug',
                'days' => 7,
            ],
    Ответ написан
    Комментировать
  • Как получить элемент имея element.style.(some-style)?

    Alixx
    @Alixx
    В данном случае никак, т.к. в someFuncton передаётся значение стиля. Чтобы в someFuncton получить элемент, нужно его передать в эту функцию:
    let element , element2;
    
            someFuncton(element.style.height, element);
            someFuncton(element.style.width, element)
    
            function someFuncton(value, element){
              /* теперь тут доступен элемент и у него можно менять разные стили */
            }

    А если по-нормальному, то тогда незачем в эту функцию значение стиля передавать, т.к. в функции сам элемент теперь доступен.

    Либо, как уже было сказано, используйте в функции поиск элемента по css селектору.
    Ответ написан
    Комментировать
  • Как при разных суммах корзины сделать разные подарки?

    Alixx
    @Alixx
    Я может не до конца поняла проблему (с woocommerce конкретно не работала), но в вашем коде просто не прописаны условия для суммы от 1500... Пропишите так:

    // условие: сумма от 1000 до 1499
            if ($woocommerce->cart->total >= $cart_total 
                && $woocommerce->cart->total <= 1499) {
                if (sizeof($woocommerce->cart->get_cart()) > 0) {
                    foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) {
                        $_product = $values['data'];
                        if ($_product->get_id() == $product_id)
                            $found = true;
                    }
                    if (!$found)
                        $woocommerce->cart->add_to_cart($product_id);
                } else {
                    $woocommerce->cart->add_to_cart($product_id);
                }
            } elseif ($woocommerce->cart->total >= 1500) { // условие: сумма от 1500
                /* ... */
            }
    Ответ написан
    1 комментарий
  • Какой ОКВЭД выбрать для браузерной игры?

    Alixx
    @Alixx Автор вопроса
    На основе подобных игр, надо искать в 62 разделе. Более уместный из этого списка, скорей всего, 62.01
    Ответ написан
    Комментировать
  • Как создавать таблицу через dom js?

    Alixx
    @Alixx
    Вы в tr() и td() каждый раз создаёте новую таблицу, а не строку/столбец.

    function tr(){
    texta.value += '<table><tbody>'; // Один раз создаёте таблицу
        for(let i = 0; i<table1.value;i++){
    	texta.value += '<tr>';
        td(); /* Вызов td() должен быть тут, внутри строки, и нигде больше */
      texta.value += '</tr>';
        
    //    texta.value += `<table><tbody><tr><td style = "width:${table4.value}px;height:${table3.value}px;border:${table5.value}px ${tableselect.value} ${colorselect.value}"</td></tr>`
        }
    }
    
    function td(){
        for(let i = 0; i<table2.value;i++){
        texta.value += '<td style = "width:${table4.value}px;height:${table3.value}px;border:${table5.value}px ${tableselect.value} ${colorselect.value}"</td>';
      
     //       texta.value +=  `<table><tbody><tr><td style = "width:${table4.value}px;height:${table3.value}px;border:${table5.value}px ${tableselect.value} ${colorselect.value}"</td></tr>`
    
        }
    }
    Ответ написан
    1 комментарий
  • Как составить условие к полю strong?

    Alixx
    @Alixx
    let gd = document.querySelector('#gd');
    let str = gd.innerText;
    let number_gd = parseInt(str.replace(/[^\d]/g, ''));
    
    if (number_gd > 10)
    	document.querySelector('#example').style.visibility = 'hidden';
    Ответ написан
  • Ошибка с Vue. Как запустить js-скрипты?

    Alixx
    @Alixx Автор вопроса
    <div id="app"> </div> был дочерним элементом body и содержал в себе уже весь остальном контент, в т.ч. мои js-скрипты.
    Я переместила все js-скрипты вне этого контейнера. И все скрипты заработали.
    Ответ написан
    1 комментарий
  • Как с помощью type="range" при каждом изменении value вызывать функцию с переменной = value?

    Alixx
    @Alixx
    <input id="my_input" type="range" value="0" max="100" min="0">
    var inp_value; // Здесь храните значение range
    // Ваша функция для действий со значением из range
    function my_function(value) {
       // что-то делаете с полученным значением
    }
    // Вешаете обработчик события mousemove на range
    document.querySelector("#my_input").addEventListener("mousemove", function() {
        inp_value  = this.value; // Сохраняете изменённое значение 
    });
    my_function(inp_value); // Собственно, вызываете ф-ю со значением range
    Ответ написан
    1 комментарий
  • Как php (в частности на Laravel) сайты осуществляют события при наступлении нужных даты/времени?

    Alixx
    @Alixx Автор вопроса
    Всем спасибо за ответы.) Всё получилось с планировщиком задач в ларе и винде. Может кому пригодится, опишу подробней:
    В бд создать таблицу с задачами (id, date_end с индексом - не позже этого времени нужно выполнить эту задачу, type - тип задачи, и пр.).
    В app/Console/Kernel.php создала artisan команду, вызывается ежеминутно
    ...
     protected $commands = [
            'App\Console\Commands\DateTasksUsers'
        ];
     protected function schedule(Schedule $schedule)
        {
            $schedule->command('date_tasks:users')->everyMinute();
        }
    ...

    В app/Console/Commands/DateTasksUsers.php - файл для команды. В ней проходим таблицу задач, ищем те, время которых уже подошло. Для каждой полученной задачи вызываем соответствующую функцию.
    ...
        protected $signature = 'date_tasks:users';
        ...  
        public function handle()
        {
            $tasks = TaskUser::where('date_end', '<=', time())
                ->get(); 
            if (!is_null($tasks)) {
                foreach($tasks as $task)
                {
                    if ($task->type == 1)
                        User::task_change($task); // там уже проверяем данные, обновляем данные в бд, уведомление кидаем 
                                        // юзеру и т.д. Там же в конце удаляем эту задачу.
                    elseif ($task->type == 2)
                        Item::task_upgrade($task);
                    // дальше так же добавлять новые типы задач и вызов соответствующих ф-й для них
                }
            }
        }

    Настроить планировщик винды (у меня 10ка) как в статье (там для xampp как раз показано), которую скинул Barmunk.
    Вот и все манипуляции)
    Смущает только то, что задачи выполняются последовательно, а надо бы запустить их все разом параллельно, т.е. в несколько процессов.
    Ответ написан
    Комментировать
  • Почему не работает символическая ссылка storage/app/public в Laravel?

    Alixx
    @Alixx Автор вопроса
    В общем, кому нужно, чтобы правильно работали ссылки на storage/app/public можно использовать вот такой вариант, взятый отсюда:

    Route::get('storage/{filename}', function ($filename)
    {
        $path = storage_path('app\public\\' . $filename);
    
        if (!File::exists($path)) {
            abort(404);
        }
    
        $file = File::get($path);
        $type = File::mimeType($path);
    
        $response = Response::make($file, 200);
        $response->header("Content-Type", $type);
    
        return $response;
    });
    Ответ написан