Commit c54231c5 by Vladislav

#19461 Страница настройки целевых аккаунтов.

1 parent f60a7639
......@@ -4,10 +4,12 @@ namespace App\Http\Controllers;
use App\Models\Campaigns;
use App\Models\Dictionary;
use App\Models\Pivots\DictionaryCampaign;
use App\Models\Tokens;
use App\Service\API\API;
use App\Service\Requests\APIRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request;
use Inertia\Inertia;
......@@ -51,7 +53,7 @@ class TokensController extends Controller
),
'cities' => (
!$token->isMain()
? $token->cities
? $token->load('cities.campaigns')->cities
: []
),
],
......@@ -153,9 +155,37 @@ class TokensController extends Controller
return Redirect::back();
}
$token_main = Tokens::with('campaigns')->where('type', Tokens::MAIN)->first();
if (!$token_main) {
return Redirect::back();
}
DB::beginTransaction();
try {
$token->cities()->save($city);
if ($token_main->campaigns->count()) {
$city->campaigns()->syncWithoutDetaching(
$token_main->campaigns->keyBy($token_main->campaigns->first()->getKeyName())->transform(function (Campaigns $campaign) {
return DictionaryCampaign::copyPropertyInCampaign($campaign);
})->all()
);
}
$token_main->campaigns->each(function (Campaigns $campaign) use ($city) {
});
DB::commit();
return Redirect::route('token.edit', $token->getKey())->with('success', 'City added.');
} catch (\Exception $e) {
DB::rollBack();
return Redirect::back()->withErrors($e->getMessage());
}
}
public function updatedCity(Tokens $token, Dictionary $city)
......@@ -164,8 +194,7 @@ class TokensController extends Controller
return Redirect::back();
}
$city = $token->cities()->where($city->getKeyName(), $city->getKey())
->first();
$city = $token->cities()->find($city->getKey());
if (!$city) {
return Redirect::back();
......@@ -178,15 +207,21 @@ class TokensController extends Controller
return Redirect::route('token.edit', $token->getKey())->with('success', 'City updated.');
}
public function updatedCampaign(Tokens $token, Dictionary $city)
public function updatedCityCampaign(Tokens $token, Dictionary $city, $campaign_id)
{
if ($token->isMain()) {
return Redirect::back();
}
$updated = !!request('updated');
$campaign = $city->campaigns()->find($campaign_id);
//
if (!$campaign) {
return Redirect::back();
}
$campaign->pivot->update([
'updated' => !!request('updated'),
]);
return Redirect::route('token.edit', $token->getKey())->with('success', 'Campaign updated.');
}
......
......@@ -2,6 +2,7 @@
namespace App\Models;
use App\Models\Pivots\DictionaryCampaign;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
......@@ -37,11 +38,39 @@ class Campaigns extends Model
'groups_loaded_at' => 'datetime',
];
public static function boot()
{
parent::boot();
static::creating(function(Campaigns $campaign_new)
{
Dictionary::whereNotNull('token_id')->each(function (Dictionary $dictionary) use ($campaign_new) {
$campaign_new->dictionaries()->syncWithoutDetaching([
$dictionary->getKey() => DictionaryCampaign::copyPropertyInCampaign($campaign_new),
]);
});
});
static::deleting(function(Campaigns $campaign_delete)
{
$campaign_delete->dictionaries()->sync([]);
$campaign_delete->vars()->delete();
});
}
public function vars()
{
return $this->hasMany(CampaignVar::class, 'campaign_id');
}
public function dictionaries()
{
return $this->belongsToMany(Dictionary::class, 'dictionary_campaigns', 'campaign_id', 'dictionary_id')
->using(DictionaryCampaign::class)
->withPivot(DictionaryCampaign::getWithPivot())
->withTimestamps();
}
public function scopeForUpdated($query)
{
$query->whereNotNull('updated');
......
......@@ -2,6 +2,7 @@
namespace App\Models;
use App\Models\Pivots\DictionaryCampaign;
use Illuminate\Database\Eloquent\Builder;
class Dictionary extends Model
......@@ -21,6 +22,14 @@ class Dictionary extends Model
return $this->belongsTo(Tokens::class, 'token_id');
}
public function campaigns()
{
return $this->belongsToMany(Campaigns::class, 'dictionary_campaigns', 'dictionary_id', 'campaign_id')
->using(DictionaryCampaign::class)
->withPivot(DictionaryCampaign::getWithPivot())
->withTimestamps();
}
public function scopeDefaultOrderBy(Builder $query)
{
return $query->orderBy('name');
......
<?php
namespace App\Models\Pivots;
use App\Models\Campaigns;
use App\Models\Dictionary;
use Illuminate\Database\Eloquent\Relations\Pivot;
class DictionaryCampaign extends Pivot
{
protected $fillable = [
'campaign_id',
'dictionary_id',
'name',
'negative_keywords',
'excluded_sites',
'updated',
];
static public function getWithPivot()
{
return [
'name',
'negative_keywords',
'excluded_sites',
'updated',
];
}
static public function copyPropertyInCampaign(Campaigns $campaign)
{
return collect(self::getWithPivot())
->filter(fn($property_name) => $property_name !== 'updated')
->transform(function ($property_name) use ($campaign) {
return [
$property_name => $campaign->{$property_name}
];
})->flatMap(fn($val) => $val)->all();
}
protected $cast = [
'campaign_id' => 'int',
'dictionary_id' => 'int',
'updated' => 'boolean',
];
public function dictionary()
{
return $this->belongsTo(Dictionary::class, 'dictionary_id');
}
public function campaign()
{
return $this->belongsTo(Campaigns::class, 'campaign_id');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDictionaryCampaignsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('dictionary_campaigns', function (Blueprint $table) {
$table->id();
$table->bigInteger('campaign_id')->unsigned();
$table->bigInteger('dictionary_id')->unsigned();
$table->string('name', 255)->nullable();
$table->text('negative_keywords')->nullable();
$table->text('excluded_sites')->nullable();
$table->boolean('updated')->default(0);
$table->timestamps();
$table->foreign('campaign_id')->references('id')->on('campaigns');
$table->foreign('dictionary_id')->references('id')->on('dictionaries');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('dictionary_campaigns');
}
}
......@@ -26,55 +26,61 @@
<th class="px-6 pt-6 pb-4">Обновлять?</th>
<th class="px-6 pt-6 pb-4"></th>
</tr>
<template v-for="city in token.cities" >
<template v-for="city in token.cities">
<tr :key="city.id" class="hover:bg-gray-100 focus-within:bg-gray-100">
<td colspan="2" class="border-t">
<div class="px-6 py-4">
{{ city.name }}
</div>
</td>
<td class="border-t">
<div class="px-6 py-4">
<input :checked="city.update"
@change="cityUpdated(city.id, !city.update)"
type="checkbox"
>
</div>
</td>
<td>
<td class="border-t w-px">
<div class="px-6 py-4">
<button class="px-4 flex items-center"
tabindex="-1"
@click="cityDelete(city.id)"
>
<icon name="trash" class="block w-6 h-6 fill-gray-400" />
<icon name="trash" class="block w-6 h-6 fill-gray-400"/>
</button>
</div>
</td>
</tr>
<tr>
<tr v-if="city.campaigns.length">
<th class="px-6 pt-6 pb-4"></th>
<th class="px-6 pt-6 pb-4">Кампания</th>
<th class="px-6 pt-6 pb-4" colspan="2">Синхронизировать?</th>
<th class="px-6 pt-6 pb-4">Синхронизировать?</th>
<th></th>
</tr>
<tr v-for="campaign in main_token_campaigns">
<tr v-if="city.campaigns.length" :key="campaign.id" v-for="campaign in city.campaigns">
<td class="border-t"></td>
<td class="border-t">
<span class="px-6 py-4 flex items-center focus:text-indigo-500">
<inertia-link class="hover:text-indigo-500 focus:text-indigo-500"
:href="route('token.campaign.vars', [token.id, campaign.id])"
>
{{ campaign.name }}
{{ campaign.pivot.name }}
</inertia-link>
</span>
</td>
<td class="border-t">
<input :checked="false"
@change="campaignUpdated(campaign.id, false)"
<td class="border-t text-center">
<input :checked="campaign.pivot.updated !== '0'"
@change="campaignUpdated(city.id, campaign.id, !(campaign.pivot.updated !== '0'))"
type="checkbox"
>
</td>
<td>
<td class="border-t">
<inertia-link class="px-4 flex items-center"
tabindex="-1"
:href="route('token.campaign.vars', [token.id, campaign.id])"
>
<icon name="book" class="block w-6 h-6 fill-gray-400" />
<icon name="book" class="block w-6 h-6 fill-gray-400"/>
</inertia-link>
</td>
</tr>
......@@ -89,9 +95,10 @@
<script>
import SelectInput from "../../Shared/SelectInput";
import Icon from "../../Shared/Icon";
export default {
import SelectInput from "../../Shared/SelectInput";
import Icon from "../../Shared/Icon";
export default {
components: {Icon, SelectInput},
props: {
cities: Array,
......@@ -103,9 +110,7 @@ export default {
city: false
}
},
watch: {
},
watch: {},
mounted() {
},
......@@ -119,9 +124,9 @@ export default {
cityUpdated(id, updated) {
this.$emit('updated', id, updated)
},
campaignUpdated(id, updated) {
this.$emit('campaignUpdated', id, updated)
campaignUpdated(city_id, campaign_id, updated) {
this.$emit('campaignUpdated', city_id, campaign_id, updated)
},
}
}
}
</script>
......@@ -109,8 +109,8 @@ export default {
updated: updated ? 1 : 0,
})
},
campaignUpdated(id, updated) {
this.$inertia.post(this.route('token.city.campaign.updated', [this.token.id, id]), {
campaignUpdated(city_id, campaign_id, updated) {
this.$inertia.post(this.route('token.city.campaign.updated', [this.token.id, city_id, campaign_id]), {
updated: updated ? 1 : 0,
})
},
......
......@@ -190,7 +190,7 @@ Route::post('token/city/store/{token}/{city}', [TokensController::class, 'storeC
Route::post('token/city/updated/{token}/{city}', [TokensController::class, 'updatedCity'])
->name('token.city.updated')
->middleware('auth');
Route::post('token/city/campaign/updated/{token}/{city}', [TokensController::class, 'updatedCampaign'])
Route::post('token/city/campaign/updated/{token}/{city}/{campaign}', [TokensController::class, 'updatedCityCampaign'])
->name('token.city.campaign.updated')
->middleware('auth');
Route::delete('token/city/{token}/{city}', [TokensController::class, 'destroyCity'])
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!