generated from liutk/owl-admin-base
admin 店员管理
parent
1a377349e9
commit
9305112e84
|
|
@ -51,6 +51,14 @@ class EmployeeController extends AdminController
|
|||
->api('post:'.admin_url('hr/employees/${id}/leave'))
|
||||
->visible(Admin::user()->can('admin.hr.employees.leave'))
|
||||
->visibleOn('${employee_status == '.EmployeeStatus::Online->value.'}'),
|
||||
amisMake()->AjaxAction()
|
||||
->label(__('employee.reback'))
|
||||
->level('link')
|
||||
->icon('fa fa-sign-out')
|
||||
->confirmText(__('employee.leave_confirm'))
|
||||
->api('post:'.admin_url('hr/employees/${id}/leave'))
|
||||
->visible(Admin::user()->can('admin.hr.employees.leave'))
|
||||
->visibleOn('${employee_status == '.EmployeeStatus::Offline->value.'}'),
|
||||
]),
|
||||
]);
|
||||
|
||||
|
|
@ -108,11 +116,23 @@ class EmployeeController extends AdminController
|
|||
public function leave($id, Request $request)
|
||||
{
|
||||
$user = Employee::findOrFail($id);
|
||||
$user->update([
|
||||
'leave_at' => $request->input('leave_at', now()),
|
||||
'employee_status' => EmployeeStatus::Offline,
|
||||
]);
|
||||
if ($user->employee_status == EmployeeStatus::Online) {
|
||||
$user->update([
|
||||
'leave_at' => $request->input('leave_at', now()),
|
||||
'employee_status' => EmployeeStatus::Offline,
|
||||
]);
|
||||
} else {
|
||||
$user->update([
|
||||
'leave_at' => null,
|
||||
'employee_status' => EmployeeStatus::Online,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->response()->success(null, '操作成功');
|
||||
}
|
||||
|
||||
public function shareList()
|
||||
{
|
||||
return $this->service->listQuery()->get(['id', 'name', 'phone']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use Slowlyo\OwlAdmin\Renderers\Form;
|
|||
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||
|
||||
/**
|
||||
* 休息日管理
|
||||
* 休息管理
|
||||
*/
|
||||
class RestController extends AdminController
|
||||
{
|
||||
|
|
@ -46,7 +46,7 @@ class RestController extends AdminController
|
|||
{
|
||||
return $this->baseForm()->title('')->body([
|
||||
amisMake()->SelectControl()->name('employees')->label(__('employee_sign.employee_id'))
|
||||
->source(admin_url('hr/employees?_action=getData&_all=1&employee_status='.EmployeeStatus::Online->value))
|
||||
->source(admin_url('api/employees?_all=1&employee_status='.EmployeeStatus::Online->value))
|
||||
->labelField('name')
|
||||
->valueField('id')
|
||||
->searchable()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Hr;
|
||||
|
||||
use App\Admin\Controllers\AdminController;
|
||||
use App\Admin\Services\EmployeeSignService;
|
||||
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||
|
||||
/**
|
||||
* 考勤打卡
|
||||
*/
|
||||
class SignController extends AdminController
|
||||
{
|
||||
protected string $serviceName = EmployeeSignService::class;
|
||||
|
||||
public function list(): Page
|
||||
{
|
||||
$crud = $this->baseCRUD()
|
||||
->tableLayout('fixed')
|
||||
->headerToolbar([
|
||||
...$this->baseHeaderToolBar(),
|
||||
])
|
||||
->bulkActions([])
|
||||
->filter($this->baseFilter()->body([
|
||||
amis()->GroupControl()->mode('horizontal')->body([
|
||||
amisMake()->SelectControl()->source(admin_url('api/stores?_all=1'))->labelField('title')->valueField('id')->searchable()->name('store_id')->label(__('employee_sign.store_id'))->columnRatio(3)->clearable(),
|
||||
amisMake()->TextControl()->name('employee_name')->label(__('employee_sign.employee_id'))->placeholder(__('employee.name').'/'.__('employee.phone'))->columnRatio(3)->clearable(),
|
||||
amisMake()->DateRangeControl()->name('date_range')->label(__('employee_sign.date'))->columnRatio(3)->clearable(),
|
||||
]),
|
||||
]))
|
||||
->columns([
|
||||
amisMake()->TableColumn()->name('store.name')->label(__('employee_sign.store_id')),
|
||||
amisMake()->TableColumn()->name('employee.name')->label(__('employee.name')),
|
||||
amisMake()->TableColumn()->name('sign_type')->label(__('employee_sign.sign_type')),
|
||||
amisMake()->TableColumn()->name('first_time')->label(__('employee_sign.first_time')),
|
||||
amisMake()->TableColumn()->name('last_time')->label(__('employee_sign.last_time')),
|
||||
amisMake()->TableColumn()->name('sign_status')->label(__('employee_sign.sign_status')),
|
||||
$this->rowActions([
|
||||
$this->rowShowButton(),
|
||||
]),
|
||||
]);
|
||||
|
||||
return $this->baseList($crud);
|
||||
}
|
||||
|
||||
public function detail(): Form
|
||||
{
|
||||
return $this->baseDetail()->title('')->body(amisMake()->Property()->items([
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ class DeviceController extends AdminController
|
|||
->filter($this->baseFilter()->body([
|
||||
amis()->GroupControl()->mode('horizontal')->body([
|
||||
amisMake()->SelectControl()->name('store_id')->label(__('store_device.store_id'))
|
||||
->source(admin_url('store/stores?_action=getData&_all=1'))
|
||||
->source(admin_url('api/stores?_all=1'))
|
||||
->labelField('title')
|
||||
->valueField('id')
|
||||
->columnRatio(3)
|
||||
|
|
@ -55,7 +55,7 @@ class DeviceController extends AdminController
|
|||
{
|
||||
return $this->baseForm()->title('')->body([
|
||||
amisMake()->SelectControl()->name('store_id')->label(__('store_device.store_id'))
|
||||
->source(admin_url('store/stores?_action=getData&_all=1'))
|
||||
->source(admin_url('api/stores?_all=1'))
|
||||
->labelField('title')
|
||||
->valueField('id')
|
||||
->required(),
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class EmployeeController extends AdminController
|
|||
->filter($this->baseFilter()->body([
|
||||
amis()->GroupControl()->mode('horizontal')->body([
|
||||
amisMake()->SelectControl()->name('store_id')->label(__('employee.store_id'))
|
||||
->source(admin_url('store/stores?_action=getData&_all=1'))
|
||||
->source(admin_url('api/stores?_all=1'))
|
||||
->labelField('title')
|
||||
->valueField('id')
|
||||
->columnRatio(3)
|
||||
|
|
@ -38,8 +38,8 @@ class EmployeeController extends AdminController
|
|||
->columns([
|
||||
amisMake()->TableColumn()->name('id')->label(__('employee.id')),
|
||||
amisMake()->TableColumn()->name('store.title')->label(__('employee.store_id')),
|
||||
amisMake()->TableColumn()->name('employee.name')->label(__('store.employees')),
|
||||
amisMake()->TableColumn()->name('employee.phone')->label(__('employee.phone')),
|
||||
amisMake()->TableColumn()->name('name')->label(__('store.employees')),
|
||||
amisMake()->TableColumn()->name('phone')->label(__('employee.phone')),
|
||||
$this->rowActions([
|
||||
// $this->rowEditButton(true)->visible(Admin::user()->can('admin.store.employees.update')),
|
||||
$this->rowDeleteButton()->visible(Admin::user()->can('admin.store.employees.delete')),
|
||||
|
|
@ -53,14 +53,18 @@ class EmployeeController extends AdminController
|
|||
{
|
||||
return $this->baseForm()->title('')->body([
|
||||
amisMake()->SelectControl()->name('store_id')->label(__('employee.store_id'))
|
||||
->source(admin_url('store/stores?_action=getData&_all=1'))
|
||||
->source(admin_url('api/stores?_all=1'))
|
||||
->labelField('title')
|
||||
->valueField('id')
|
||||
->required(),
|
||||
amisMake()->SelectControl()->name('employee_id')->label(__('store.employees'))
|
||||
->source(admin_url('hr/employees?_action=getData&_all=1'))
|
||||
->source(admin_url('api/employees?_all=1&store_id=0&master_store_id=0&enable=1'))
|
||||
->labelField('name')
|
||||
->valueField('id')
|
||||
->multiple()
|
||||
->joinValues(false)
|
||||
->extractValue()
|
||||
->searchable()
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class StoreController extends AdminController
|
|||
return $this->baseForm()->title('')->body([
|
||||
amisMake()->TextControl()->name('title')->label(__('store.title'))->required(),
|
||||
amisMake()->SelectControl()->name('master_id')->label(__('store.master_id'))
|
||||
->source(admin_url('hr/employees?_action=getData&_all=1&employee_status='.EmployeeStatus::Online->value))
|
||||
->source(admin_url('api/employees?_all=1&employee_status='.EmployeeStatus::Online->value))
|
||||
->labelField('name')
|
||||
->valueField('id')
|
||||
->searchable()
|
||||
|
|
|
|||
|
|
@ -22,8 +22,23 @@ class EmployeeFilter extends ModelFilter
|
|||
$this->whereLike('phone', $key);
|
||||
}
|
||||
|
||||
public function store($key)
|
||||
{
|
||||
$this->where('store_id', $key);
|
||||
}
|
||||
|
||||
public function masterStore($key)
|
||||
{
|
||||
$this->where('master_store_id', $key);
|
||||
}
|
||||
|
||||
public function employeeStatus($key)
|
||||
{
|
||||
$this->whereIn('employee_status', is_array($key) ? $key : explode(',', $key));
|
||||
}
|
||||
|
||||
public function enable($key)
|
||||
{
|
||||
$this->query->enable();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace App\Admin\Filters;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use EloquentFilter\ModelFilter;
|
||||
|
||||
class StoreEmployeeFilter extends ModelFilter
|
||||
class EmployeeSignFilter extends ModelFilter
|
||||
{
|
||||
protected $drop_id = false;
|
||||
|
||||
|
|
@ -27,4 +28,12 @@ class StoreEmployeeFilter extends ModelFilter
|
|||
{
|
||||
$this->where('store_id', $key);
|
||||
}
|
||||
|
||||
public function dateRange($dates)
|
||||
{
|
||||
$dates = explode(',', $dates);
|
||||
$start = Carbon::createFromTimestamp(data_get($dates, 0, time()))->startOfDay();
|
||||
$end = Carbon::createFromTimestamp(data_get($dates, 1, time()))->endOfDay();
|
||||
$this->whereBetween('date', [$start, $end]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Services;
|
||||
|
||||
use App\Admin\Filters\EmployeeSignFilter;
|
||||
use App\Models\EmployeeSign;
|
||||
|
||||
class EmployeeSignService extends BaseService
|
||||
{
|
||||
protected array $withRelationships = ['employee', 'store'];
|
||||
|
||||
protected string $modelName = EmployeeSign::class;
|
||||
|
||||
protected string $modelFilterName = EmployeeSignFilter::class;
|
||||
}
|
||||
|
|
@ -2,35 +2,79 @@
|
|||
|
||||
namespace App\Admin\Services;
|
||||
|
||||
use App\Admin\Filters\StoreEmployeeFilter;
|
||||
use App\Models\StoreEmployee;
|
||||
use App\Admin\Filters\EmployeeFilter;
|
||||
use App\Models\Employee;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreEmployeeService extends BaseService
|
||||
{
|
||||
protected array $withRelationships = ['store', 'employee'];
|
||||
protected array $withRelationships = ['store'];
|
||||
|
||||
protected string $modelName = StoreEmployee::class;
|
||||
protected string $modelName = Employee::class;
|
||||
|
||||
protected string $modelFilterName = StoreEmployeeFilter::class;
|
||||
protected string $modelFilterName = EmployeeFilter::class;
|
||||
|
||||
public function listQuery()
|
||||
{
|
||||
$model = $this->getModel();
|
||||
$filter = $this->getModelFilter();
|
||||
|
||||
$query = $this->query()->where('store_id', '>', 0);
|
||||
if ($this->withRelationships) {
|
||||
$query->with($this->withRelationships);
|
||||
}
|
||||
|
||||
if ($filter) {
|
||||
$query->filter(request()->input(), $filter);
|
||||
}
|
||||
|
||||
if ($this->modelSortAble) {
|
||||
$query->sort();
|
||||
}
|
||||
|
||||
$this->sortable($query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function store($data): bool
|
||||
{
|
||||
$storeId = $data['store_id'];
|
||||
$employees = Employee::whereIn('id', $data['employee_id'])->get();
|
||||
foreach ($employees as $employee) {
|
||||
if ($employee->store_id > 0 && $employee->store_id != $storeId) {
|
||||
$this->setError($employee->name . ' 已经有门店了');
|
||||
return false;
|
||||
}
|
||||
if ($employee->master_store_id > 0) {
|
||||
$this->setError($employee->name . ' 已经是店长了');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Employee::whereIn('id', $data['employee_id'])->update(['store_id' => $storeId]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete(string $ids): mixed
|
||||
{
|
||||
$id = explode(',', $ids);
|
||||
Employee::whereIn('id', $id)->update(['store_id' => 0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validate($data, $model = null)
|
||||
{
|
||||
$createRules = [
|
||||
'employee_id' => ['required'],
|
||||
'store_id' => ['required'],
|
||||
'employee_id' => ['required', Rule::unique('store_employees', 'employee_id')],
|
||||
];
|
||||
$updateRules = [
|
||||
'employee_id' => [Rule::unique('store_employees', 'employee_id')->ignore($model, 'employee_id')],
|
||||
];
|
||||
$validator = Validator::make($data, $model ? $updateRules : $createRules, [
|
||||
'employee_id.unique' => '已经是店员了',
|
||||
]);
|
||||
$validator = Validator::make($data, $model ? $updateRules : $createRules);
|
||||
if ($validator->fails()) {
|
||||
return $validator->errors()->first();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Admin\Services;
|
||||
|
||||
use App\Admin\Filters\StoreFilter;
|
||||
use App\Enums\StoreRole;
|
||||
use App\Models\Employee;
|
||||
use App\Models\Store;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -18,72 +17,6 @@ class StoreService extends BaseService
|
|||
|
||||
protected string $modelFilterName = StoreFilter::class;
|
||||
|
||||
public function store($data): bool
|
||||
{
|
||||
$data = $this->resloveData($data);
|
||||
|
||||
$validate = $this->validate($data);
|
||||
if ($validate !== true) {
|
||||
$this->setError($validate);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$model = $this->modelName::create($data);
|
||||
|
||||
// 设置店长
|
||||
$model->employees()->attach([$data['master_id'] => ['role' => StoreRole::Master]]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function update($primaryKey, $data): bool
|
||||
{
|
||||
$model = $this->query()->whereKey($primaryKey)->firstOrFail();
|
||||
$data = $this->resloveData($data, $model);
|
||||
$validate = $this->validate($data, $model);
|
||||
if ($validate !== true) {
|
||||
$this->setError($validate);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 修改店长
|
||||
if (isset($data['master_id']) && $data['master_id'] != $model->master_id) {
|
||||
$model->employees()->detach($model->master_id);
|
||||
$model->employees()->attach([$data['master_id'] => ['role' => StoreRole::Master]]);
|
||||
}
|
||||
|
||||
return $model->update($data);
|
||||
}
|
||||
|
||||
// 添加员工
|
||||
public function attachEmployee(Store $store, array $employeeIds)
|
||||
{
|
||||
$data = [];
|
||||
$employees = Employee::whereIn('id', $employeeIds)->get();
|
||||
// 每个员工只能有一个门店
|
||||
foreach ($employees as $employee) {
|
||||
if (DB::table('store_employees')->where('employee_id', $employee->id)->exists()) {
|
||||
$this->setError($employee->name.' 已经是店员');
|
||||
|
||||
return false;
|
||||
}
|
||||
$data[$employee->id] = ['role' => StoreRole::Employee];
|
||||
}
|
||||
$store->employees()->attach($data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 移除员工
|
||||
public function destroyEmployee(Store $store, array $employeeIds)
|
||||
{
|
||||
$store->employees()->detach($employeeIds);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function resloveData($data, $model = null)
|
||||
{
|
||||
if (isset($data['location'])) {
|
||||
|
|
@ -92,6 +25,11 @@ class StoreService extends BaseService
|
|||
$data['address'] = data_get($data['location'], 'address');
|
||||
}
|
||||
|
||||
// 绑定店长
|
||||
if (isset($data['master_id'])) {
|
||||
Employee::where('id', $data['master_id'])->update(['master_store_id' => $model->id]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
|
@ -122,8 +60,8 @@ class StoreService extends BaseService
|
|||
|
||||
public function preDelete(array $ids)
|
||||
{
|
||||
// 删除店员
|
||||
DB::table('store_employees')->whereIn('store_id', $ids)->delete();
|
||||
// 修改员工关联
|
||||
Employee::whereIn('store_id', $ids)->update(['store_id' => 0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use App\Admin\Controllers\BaseKeywordController;
|
|||
use App\Admin\Controllers\Finance\LedgerController;
|
||||
use App\Admin\Controllers\Hr\EmployeeController;
|
||||
use App\Admin\Controllers\Hr\RestController;
|
||||
use App\Admin\Controllers\Hr\SignController;
|
||||
use App\Admin\Controllers\Store\DeviceController;
|
||||
use App\Admin\Controllers\Store\EmployeeController as StoreEmployeeController;
|
||||
use App\Admin\Controllers\Store\StoreController;
|
||||
|
|
@ -66,7 +67,10 @@ Route::group([
|
|||
$router->post('employees/{id}/leave', [EmployeeController::class, 'leave'])->name('employees.leave');
|
||||
// 职位管理
|
||||
$router->resource('jobs', BaseKeywordController::class);
|
||||
$router->resource('rests', RestController::class);
|
||||
// 休息管理
|
||||
$router->resource('rests', RestController::class)->only(['index', 'create', 'store', 'destroy']);
|
||||
// 打卡情况
|
||||
$router->resource('signs', SignController::class)->only(['index', 'show']);
|
||||
});
|
||||
|
||||
/*
|
||||
|
|
@ -135,6 +139,7 @@ Route::group([
|
|||
'prefix' => 'api',
|
||||
], function (Router $router) {
|
||||
$router->get('stores', [StoreController::class, 'shareList']);
|
||||
$router->get('employees', [EmployeeController::class, 'shareList']);
|
||||
$router->get('keywords/tree-list', [KeywordController::class, 'getTreeList'])->name('api.keywords.tree-list');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
/**
|
||||
* 店员身份
|
||||
*/
|
||||
enum StoreRole: int
|
||||
{
|
||||
case Master = 1;
|
||||
case Employee = 2;
|
||||
|
||||
public static function map()
|
||||
{
|
||||
return [
|
||||
self::Master->value => '店长',
|
||||
self::Employee->value => '店员',
|
||||
];
|
||||
}
|
||||
|
||||
public static function options()
|
||||
{
|
||||
$list = [];
|
||||
foreach (self::map() as $key => $value) {
|
||||
array_push($list, ['label' => $value, 'value' => $key]);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function text()
|
||||
{
|
||||
return data_get(self::map(), $this->value);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ class Employee extends Model
|
|||
|
||||
const JOB_KEY = 'job';
|
||||
|
||||
protected $fillable = ['name', 'phone', 'prize_images', 'skill_images', 'employee_status', 'admin_user_id', 'leave_at', 'join_at', 'remarks'];
|
||||
protected $fillable = ['store_id', 'master_store_id', 'name', 'phone', 'prize_images', 'skill_images', 'employee_status', 'admin_user_id', 'leave_at', 'join_at', 'remarks'];
|
||||
|
||||
protected $casts = [
|
||||
'employee_status' => EmployeeStatus::class,
|
||||
|
|
@ -53,11 +53,16 @@ class Employee extends Model
|
|||
return $this->belongsTo(AdminUser::class, 'admin_user_id');
|
||||
}
|
||||
|
||||
// 关联的门店
|
||||
public function stores()
|
||||
// 关联的门店(店员)
|
||||
public function store()
|
||||
{
|
||||
// role(1: 店长, 2: 店员)
|
||||
return $this->belongsToMany(Store::class, 'store_employees', 'employee_id', 'store_id')->withPivot(['role']);
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
// 管理的门店(店长)
|
||||
public function masterStore()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'master_store_id');
|
||||
}
|
||||
|
||||
public function scopeEnable($q)
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ use App\Enums\SignStatus;
|
|||
use App\Enums\SignType;
|
||||
use App\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use EloquentFilter\Filterable;
|
||||
|
||||
/**
|
||||
* 员工-打卡情况
|
||||
*/
|
||||
class EmployeeSign extends Model
|
||||
{
|
||||
use HasDateTimeFormatter;
|
||||
use HasDateTimeFormatter, Filterable;
|
||||
|
||||
protected $table = 'employee_sign_dates';
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,14 @@ use App\Traits\HasDateTimeFormatter;
|
|||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
/**
|
||||
* 门店
|
||||
*/
|
||||
class Store extends Model
|
||||
{
|
||||
use Filterable, HasDateTimeFormatter;
|
||||
use Filterable, HasDateTimeFormatter, HasFactory;
|
||||
|
||||
protected $fillable = ['title', 'master_id', 'category_id', 'business_id', 'level_id', 'region', 'lon', 'lat', 'address', 'profit_ratio', 'profit_money', 'business_status'];
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ class Store extends Model
|
|||
public function employees()
|
||||
{
|
||||
// role(1: 店长, 2: 店员)
|
||||
return $this->belongsToMany(Employee::class, 'store_employees', 'store_id', 'employee_id')->using(StoreEmployee::class);
|
||||
return $this->hasMany(Employee::class, 'store_id');
|
||||
}
|
||||
|
||||
protected function businessStatusText(): Attribute
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
/**
|
||||
* 店员
|
||||
*/
|
||||
class StoreEmployee extends Pivot
|
||||
{
|
||||
use Filterable;
|
||||
|
||||
protected $table = 'store_employees';
|
||||
|
||||
public $incrementing = true;
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
public function employee()
|
||||
{
|
||||
return $this->belongsTo(Employee::class, 'employee_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ namespace Database\Factories;
|
|||
use App\Models\Employee;
|
||||
use App\Models\Keyword;
|
||||
use App\Models\Store;
|
||||
use App\Models\StoreEmployee;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
|
|
@ -22,10 +21,7 @@ class StoreFactory extends Factory
|
|||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
do {
|
||||
$master = Employee::inRandomOrder()->first();
|
||||
} while (StoreEmployee::where('employee_id', $master->id)->exists());
|
||||
|
||||
$master = Employee::where('store_id', 0)->inRandomOrder()->first();
|
||||
return [
|
||||
'title' => $this->faker->word(),
|
||||
'master_id' => $master->id,
|
||||
|
|
@ -38,4 +34,12 @@ class StoreFactory extends Factory
|
|||
'address' => '重庆市南川区东城街道办事处东环路三号',
|
||||
];
|
||||
}
|
||||
|
||||
public function configure(): static
|
||||
{
|
||||
return $this->afterMaking(function (Store $model) {
|
||||
})->afterCreating(function (Store $model) {
|
||||
Employee::where('id', $model->master_id)->update(['master_store_id' => $model->id]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ return new class extends Migration
|
|||
{
|
||||
Schema::create('employees', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('store_id')->default(0)->comment('所属门店, stores.id');
|
||||
$table->foreignId('master_store_id')->default(0)->comment('管理的门店, stores.id');
|
||||
$table->string('name')->comment('姓名');
|
||||
$table->string('phone')->comment('电话');
|
||||
$table->json('prize_images')->nullable()->comment('荣誉证书');
|
||||
|
|
|
|||
|
|
@ -28,14 +28,6 @@ return new class extends Migration
|
|||
$table->timestamps();
|
||||
$table->comment('门店');
|
||||
});
|
||||
|
||||
Schema::create('store_employees', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('store_id');
|
||||
$table->foreignId('employee_id');
|
||||
$table->unsignedInteger('role')->default(2)->comment('身份(1: 店长, 2: 店员)');
|
||||
$table->comment('门店-店员');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +36,5 @@ return new class extends Migration
|
|||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('stores');
|
||||
Schema::dropIfExists('store_employees');
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -114,8 +114,14 @@ class AdminPermissionSeeder extends Seeder
|
|||
'name' => '休息管理',
|
||||
'icon' => '',
|
||||
'uri' => '/hr/rests',
|
||||
'resource' => true,
|
||||
'resource' => ['list', 'create', 'delete'],
|
||||
],
|
||||
'signs' => [
|
||||
'name' => '考勤打卡',
|
||||
'icon' => '',
|
||||
'uri' => '/hr/signs',
|
||||
'resource' => ['list', 'view'],
|
||||
]
|
||||
],
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ class EmployeeSeeder extends Seeder
|
|||
DB::table('employee_jobs')->truncate();
|
||||
Employee::truncate();
|
||||
(new EmployeeFactory)->count(100)->create(['admin_user_id' => 1]);
|
||||
|
||||
DB::table('store_employees')->truncate();
|
||||
|
||||
Store::truncate();
|
||||
(new StoreFactory)->count(10)->create();
|
||||
Store::factory()->count(10)->create();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue