Commit c54231c5 by Vladislav

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

1 parent f60a7639
...@@ -4,10 +4,12 @@ namespace App\Http\Controllers; ...@@ -4,10 +4,12 @@ namespace App\Http\Controllers;
use App\Models\Campaigns; use App\Models\Campaigns;
use App\Models\Dictionary; use App\Models\Dictionary;
use App\Models\Pivots\DictionaryCampaign;
use App\Models\Tokens; use App\Models\Tokens;
use App\Service\API\API; use App\Service\API\API;
use App\Service\Requests\APIRequest; use App\Service\Requests\APIRequest;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect; use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Request;
use Inertia\Inertia; use Inertia\Inertia;
...@@ -51,7 +53,7 @@ class TokensController extends Controller ...@@ -51,7 +53,7 @@ class TokensController extends Controller
), ),
'cities' => ( 'cities' => (
!$token->isMain() !$token->isMain()
? $token->cities ? $token->load('cities.campaigns')->cities
: [] : []
), ),
], ],
...@@ -153,9 +155,37 @@ class TokensController extends Controller ...@@ -153,9 +155,37 @@ class TokensController extends Controller
return Redirect::back(); return Redirect::back();
} }
$token->cities()->save($city); $token_main = Tokens::with('campaigns')->where('type', Tokens::MAIN)->first();
return Redirect::route('token.edit', $token->getKey())->with('success', 'City added.'); 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) public function updatedCity(Tokens $token, Dictionary $city)
...@@ -164,8 +194,7 @@ class TokensController extends Controller ...@@ -164,8 +194,7 @@ class TokensController extends Controller
return Redirect::back(); return Redirect::back();
} }
$city = $token->cities()->where($city->getKeyName(), $city->getKey()) $city = $token->cities()->find($city->getKey());
->first();
if (!$city) { if (!$city) {
return Redirect::back(); return Redirect::back();
...@@ -178,15 +207,21 @@ class TokensController extends Controller ...@@ -178,15 +207,21 @@ class TokensController extends Controller
return Redirect::route('token.edit', $token->getKey())->with('success', 'City updated.'); 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()) { if ($token->isMain()) {
return Redirect::back(); 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.'); return Redirect::route('token.edit', $token->getKey())->with('success', 'Campaign updated.');
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Models\Pivots\DictionaryCampaign;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
...@@ -37,11 +38,39 @@ class Campaigns extends Model ...@@ -37,11 +38,39 @@ class Campaigns extends Model
'groups_loaded_at' => 'datetime', '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() public function vars()
{ {
return $this->hasMany(CampaignVar::class, 'campaign_id'); 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) public function scopeForUpdated($query)
{ {
$query->whereNotNull('updated'); $query->whereNotNull('updated');
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Models\Pivots\DictionaryCampaign;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
class Dictionary extends Model class Dictionary extends Model
...@@ -21,6 +22,14 @@ class Dictionary extends Model ...@@ -21,6 +22,14 @@ class Dictionary extends Model
return $this->belongsTo(Tokens::class, 'token_id'); 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) public function scopeDefaultOrderBy(Builder $query)
{ {
return $query->orderBy('name'); 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 @@ ...@@ -26,55 +26,61 @@
<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"></th> <th class="px-6 pt-6 pb-4"></th>
</tr> </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"> <tr :key="city.id" class="hover:bg-gray-100 focus-within:bg-gray-100">
<td colspan="2" class="border-t"> <td colspan="2" class="border-t">
{{ city.name }} <div class="px-6 py-4">
</td> {{ city.name }}
<td class="border-t"> </div>
<input :checked="city.update" </td>
@change="cityUpdated(city.id, !city.update)" <td class="border-t">
type="checkbox" <div class="px-6 py-4">
> <input :checked="city.update"
</td> @change="cityUpdated(city.id, !city.update)"
<td> type="checkbox"
<button class="px-4 flex items-center" >
tabindex="-1" </div>
@click="cityDelete(city.id)" </td>
> <td class="border-t w-px">
<icon name="trash" class="block w-6 h-6 fill-gray-400" /> <div class="px-6 py-4">
</button> <button class="px-4 flex items-center"
</td> tabindex="-1"
</tr> @click="cityDelete(city.id)"
<tr> >
<icon name="trash" class="block w-6 h-6 fill-gray-400"/>
</button>
</div>
</td>
</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">Кампания</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> <th></th>
</tr> </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"></td>
<td class="border-t"> <td class="border-t">
<span class="px-6 py-4 flex items-center focus:text-indigo-500"> <span class="px-6 py-4 flex items-center focus:text-indigo-500">
<inertia-link class="hover:text-indigo-500 focus:text-indigo-500" <inertia-link class="hover:text-indigo-500 focus:text-indigo-500"
:href="route('token.campaign.vars', [token.id, campaign.id])" :href="route('token.campaign.vars', [token.id, campaign.id])"
> >
{{ campaign.name }} {{ campaign.pivot.name }}
</inertia-link> </inertia-link>
</span> </span>
</td> </td>
<td class="border-t"> <td class="border-t text-center">
<input :checked="false" <input :checked="campaign.pivot.updated !== '0'"
@change="campaignUpdated(campaign.id, false)" @change="campaignUpdated(city.id, campaign.id, !(campaign.pivot.updated !== '0'))"
type="checkbox" type="checkbox"
> >
</td> </td>
<td> <td class="border-t">
<inertia-link class="px-4 flex items-center" <inertia-link class="px-4 flex items-center"
tabindex="-1" tabindex="-1"
:href="route('token.campaign.vars', [token.id, campaign.id])" :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> </inertia-link>
</td> </td>
</tr> </tr>
...@@ -89,39 +95,38 @@ ...@@ -89,39 +95,38 @@
<script> <script>
import SelectInput from "../../Shared/SelectInput"; import SelectInput from "../../Shared/SelectInput";
import Icon from "../../Shared/Icon"; import Icon from "../../Shared/Icon";
export default {
components: {Icon, SelectInput},
props: {
cities: Array,
token: Object,
main_token_campaigns: Array,
},
data() {
return {
city: false
}
},
watch: {
},
mounted() {
}, export default {
methods: { components: {Icon, SelectInput},
cityAdd() { props: {
this.$emit('add', this.city) cities: Array,
token: Object,
main_token_campaigns: Array,
}, },
cityDelete(id) { data() {
this.$emit('delete', id) return {
city: false
}
}, },
cityUpdated(id, updated) { watch: {},
this.$emit('updated', id, updated) mounted() {
},
campaignUpdated(id, updated) {
this.$emit('campaignUpdated', id, updated)
}, },
methods: {
cityAdd() {
this.$emit('add', this.city)
},
cityDelete(id) {
this.$emit('delete', id)
},
cityUpdated(id, updated) {
this.$emit('updated', id, updated)
},
campaignUpdated(city_id, campaign_id, updated) {
this.$emit('campaignUpdated', city_id, campaign_id, updated)
},
}
} }
}
</script> </script>
...@@ -109,8 +109,8 @@ export default { ...@@ -109,8 +109,8 @@ export default {
updated: updated ? 1 : 0, updated: updated ? 1 : 0,
}) })
}, },
campaignUpdated(id, updated) { campaignUpdated(city_id, campaign_id, updated) {
this.$inertia.post(this.route('token.city.campaign.updated', [this.token.id, id]), { this.$inertia.post(this.route('token.city.campaign.updated', [this.token.id, city_id, campaign_id]), {
updated: updated ? 1 : 0, updated: updated ? 1 : 0,
}) })
}, },
......
...@@ -190,7 +190,7 @@ Route::post('token/city/store/{token}/{city}', [TokensController::class, 'storeC ...@@ -190,7 +190,7 @@ Route::post('token/city/store/{token}/{city}', [TokensController::class, 'storeC
Route::post('token/city/updated/{token}/{city}', [TokensController::class, 'updatedCity']) Route::post('token/city/updated/{token}/{city}', [TokensController::class, 'updatedCity'])
->name('token.city.updated') ->name('token.city.updated')
->middleware('auth'); ->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') ->name('token.city.campaign.updated')
->middleware('auth'); ->middleware('auth');
Route::delete('token/city/{token}/{city}', [TokensController::class, 'destroyCity']) 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!