1
0
Fork 0

party_users

master
panliang 2023-12-01 16:35:28 +08:00
parent 5202921132
commit d6574cb1a7
31 changed files with 1010 additions and 39 deletions

View File

@ -29,7 +29,7 @@ class ArticleController extends AdminController
->columns([
amisMake()->TableColumn()->name('id')->label(__('article.id'))->sortable(true),
amisMake()->TableColumn()->name('title')->label(__('article.title')),
amisMake()->TableColumn()->name('category.name')->label(__('article.category_id'))->className('text-primary'),
amisMake()->TableColumn()->name('category.name')->label(__('article.category_id')),
amisMake()->Image()->name('cover')->label(__('article.cover'))->width(100),
amisMake()->TableColumn()->name('sort')->label(__('article.sort'))->align('center')->quickEdit(Components::make()->sortControl('sort', __('article.sort'))->saveImmediately(true)),
Components::make()->switchControl('table')->name('is_enable')->label(__('article.is_enable')),

View File

@ -0,0 +1,82 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Components;
use App\Admin\Services\PartyCateService;
use App\Models\PartyUser;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page;
/**
* 党支部管理
*/
class PartyCateController extends AdminController
{
protected string $serviceName = PartyCateService::class;
protected $userOptions;
public function list(): Page
{
$crud = $this->baseCRUD()
->filterTogglable(false)
->columnsTogglable(false)
->headerToolbar([
$this->createButton(true),
])
->filter($this->baseFilter()->actions([])->body([
amisMake()->TextControl()->name('name')->label(__('party_cate.name'))->size('md')->clearable(),
amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
amisMake()->TableColumn()->name('id')->label(__('party_cate.id')),
amisMake()->TableColumn()->name('name')->label(__('party_cate.name')),
amisMake()->TableColumn()->name('master.name')->label(__('party_cate.master_id')),
amisMake()->TableColumn()->name('plan.name')->label(__('party_cate.plan_id')),
amisMake()->TableColumn()->name('score')->label(__('party_cate.score')),
amisMake()->TableColumn()->name('remarks')->label(__('party_cate.remarks')),
$this->rowActions([
$this->rowShowButton(),
$this->rowEditButton(true),
$this->rowDeleteButton(),
]),
]);
return $this->baseList($crud);
}
public function form(): Form
{
return $this->baseForm()->title('')->body([
amisMake()->TextControl()->name('name')->label(__('party_cate.name'))->required(),
amisMake()->SelectControl()->name('master_id')->label(__('party_cate.master_id'))->options($this->getUserOptions()),
amisMake()->SelectControl()->name('plan_id')->label(__('party_cate.plan_id'))->options($this->getUserOptions()),
amisMake()->TextControl()->name('remarks')->label(__('party_cate.remarks')),
]);
}
public function detail(): Form
{
return $this->baseDetail()->title('')->body([
amisMake()->TextControl()->name('id')->label(__('party_cate.id'))->static(),
amisMake()->TextControl()->name('name')->label(__('party_cate.name'))->static(),
amisMake()->TextControl()->name('master.name')->label(__('party_cate.master_id'))->static(),
amisMake()->TextControl()->name('plan.name')->label(__('party_cate.plan_id'))->static(),
amisMake()->TextControl()->name('remarks')->label(__('party_cate.remarks'))->static(),
amisMake()->TextControl()->name('score')->label(__('party_cate.score'))->static(),
amisMake()->TextControl()->name('scores')->label(__('party_cate.scores'))->static()->staticSchema(amisMake()->Json()),
amisMake()->TextControl()->name('created_at')->label(__('party_cate.created_at'))->static(),
]);
}
public function getUserOptions()
{
if (!$this->userOptions) {
$this->userOptions = PartyUser::select(['id as value', 'name as label'])->get();
}
return $this->userOptions;
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Services\PartyUserService;
use App\Models\PartyCate;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page;
/**
* 党员管理
*/
class PartyUserController extends AdminController
{
protected string $serviceName = PartyUserService::class;
protected $cateOptions;
public function list(): Page
{
$crud = $this->baseCRUD()
->filterTogglable(false)
->columnsTogglable(false)
->headerToolbar([
$this->createButton(true),
])
->filter($this->baseFilter()->actions([])->body([
amisMake()->TextControl()->name('name')->label(__('party_user.name'))->size('md')->clearable(),
amisMake()->SelectControl()->name('cate_id')->label(__('party_user.cate_id'))->options($this->getCateOptions())->size('md')->clearable(),
amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
amisMake()->TableColumn()->name('id')->label(__('party_user.id')),
amisMake()->TableColumn()->name('name')->label(__('party_user.name')),
amisMake()->TableColumn()->type('avatar')->src('${avatar}')->name('avatar')->label(__('party_user.avatar')),
amisMake()->TableColumn()->name('cate.name')->label(__('party_user.cate_id')),
amisMake()->TableColumn()->name('score')->label(__('party_user.score')),
$this->rowActions([
$this->rowShowButton(),
$this->rowEditButton(true),
$this->rowDeleteButton(),
]),
]);
return $this->baseList($crud);
}
public function form($edit): Form
{
return $this->baseForm()->title('')->body([
amisMake()->SelectControl()->name('cate_id')->label(__('party_user.cate_id'))->options($this->getCateOptions()),
amisMake()->TextControl()->name('name')->label(__('party_user.name'))->required(),
amisMake()->ImageControl()->name('avatar')->label(__('party_user.avatar')),
amisMake()->TextControl()->name('username')->label(__('party_user.username'))->required(),
amisMake()->TextControl()->set('type', 'input-password')->name('password')->label(__('party_user.password'))->required(!$edit),
amisMake()->TextControl()->name('remarks')->label(__('party_cate.remarks')),
]);
}
public function detail(): Form
{
return $this->baseDetail()->title('')->body([
amisMake()->TextControl()->name('id')->label(__('party_user.id'))->static(),
amisMake()->TextControl()->name('username')->label(__('party_user.username'))->static(),
amisMake()->TextControl()->name('name')->label(__('party_user.name'))->static(),
amisMake()->TextControl()->name('avatar')->label(__('party_user.avatar'))->static()->staticSchema(amisMake()->Image()),
amisMake()->TextControl()->name('cate.name')->label(__('party_user.cate_id'))->static(),
amisMake()->TextControl()->name('score')->label(__('party_cate.score'))->static(),
amisMake()->TextControl()->name('scores')->label(__('party_cate.scores'))->static()->staticSchema(amisMake()->Json()),
amisMake()->TextControl()->name('remarks')->label(__('party_cate.remarks'))->static(),
amisMake()->TextControl()->name('created_at')->label(__('party_user.created_at'))->static(),
]);
}
public function getCateOptions()
{
if (!$this->cateOptions) {
$this->cateOptions = PartyCate::select(['id as value', 'name as label'])->get();
}
return $this->cateOptions;
}
}

View File

@ -0,0 +1,156 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Services\UserScoreService;
use App\Enums\CheckStatus;
use App\Exceptions\BaseException;
use App\Models\Keyword;
use App\Models\PartyUser;
use App\Models\UserScore;
use Illuminate\Http\Request;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page;
class UserScoreController extends AdminController
{
protected string $serviceName = UserScoreService::class;
protected $typeOptions;
protected $userOptions;
public function list(): Page
{
$crud = $this->baseCRUD()
->filterTogglable(false)
->columnsTogglable(false)
->headerToolbar([
$this->createButton(true),
])
->filter($this->baseFilter()->actions([])->body([
amisMake()->SelectControl()->name('type_id')->label(__('user_score.type_id'))->options($this->getTypeOptions())->clearable()->size('md'),
amisMake()->SelectControl()->name('user_id')->label(__('user_score.user_id'))->options($this->getUserOptions())->clearable()->size('md'),
amisMake()->TextControl()->name('title')->label(__('user_score.title'))->clearable()->size('md'),
amisMake()->SelectControl()->name('check_status')->label(__('user_score.check_status'))->options(CheckStatus::options())->clearable()->size('md'),
amisMake()->Component()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->columns([
amisMake()->TableColumn()->name('id')->label(__('user_score.id')),
amisMake()->TableColumn()->name('type_id')->label(__('user_score.type_id')),
amisMake()->TableColumn()->name('user.name')->label(__('user_score.user_id')),
amisMake()->TableColumn()->name('title')->label(__('user_score.title')),
amisMake()->TableColumn()->name('check_status_text')->label(__('user_score.check_status')),
amisMake()->TableColumn()->name('score')->label(__('user_score.score')),
amisMake()->TableColumn()->name('created_at')->label(__('user_score.created_at')),
$this->rowActions([
$this->rowShowButton(),
$this->rowEditButton(true),
$this->rowDeleteButton(),
]),
]);
return $this->baseList($crud);
}
public function form($edit): Form
{
return $this->baseForm()->title('')->body([
amisMake()->SelectControl()->name('type_id')->label(__('user_score.type_id'))->options($this->getTypeOptions())->required(),
amisMake()->SelectControl()->name('user_id')->label(__('user_score.user_id'))->options($this->getUserOptions())->required(),
amisMake()->TextControl()->name('title')->label(__('user_score.title'))->required(),
amisMake()->TextareaControl()->name('content')->label(__('user_score.content')),
amisMake()->ImageControl()->name('images')->label(__('user_score.images'))->multiple()->receiver(admin_url('upload_image') . '?full-url=1')->autoUpload(),
amisMake()->FileControl()->name('file')->label(__('user_score.file'))->autoUpload()
]);
}
public function show($id)
{
if ($this->actionOfGetData()) {
return $this->response()->success($this->service->getDetail($id));
}
$info = UserScore::findOrFail($id);
$detail = amisMake()
->Card()
->className('base-form')
->header(['title' => __('admin.detail')])
->body($this->detail())
->toolbar([
amisMake()->Button()
->visible($info->check_status != CheckStatus::Success)
->label('审核')
->level('danger')
->className('mr-1')
->actionType('dialog')
->dialog(amisMake()->Dialog()->title('审核')->body(amisMake()->Form()->api("/user-score/$id/check")->body([
amisMake()->RadiosControl()->name('check_status')->label(__('user_score.check_status'))->options([
CheckStatus::Success->value => CheckStatus::Success->text(),
CheckStatus::Fail->value => CheckStatus::Fail->text(),
])->value(CheckStatus::Success->value)->required(),
amisMake()->NumberControl()->name('score')->label(__('user_score.score')),
amisMake()->TextControl()->name('check_remarks')->label(__('user_score.check_remarks')),
])->onEvent([
'submitSucc' => [
'actions' => [
['actionType' => 'custom', 'script' => 'window.$owl.refreshAmisPage()',]
]
]
]))),
$this->backButton(),
]);
$page = $this->basePage()->body($detail);
return $this->response()->success($page);
}
public function detail(): Form
{
return $this->baseDetail()->title('')->body([
amisMake()->TextControl()->name('id')->label(__('user_score.id'))->static(),
amisMake()->TextControl()->name('type.name')->label(__('user_score.type_id'))->static(),
amisMake()->TextControl()->name('user.name')->label(__('user_score.user_id'))->static(),
amisMake()->TextControl()->name('title')->label(__('user_score.title'))->static(),
amisMake()->TextareaControl()->name('content')->label(__('user_score.content'))->static(),
amisMake()->TextControl()->name('images')->label(__('user_score.images'))->static()->staticSchema(amisMake()->Images()),
amisMake()->TextControl()->name('file')->label(__('user_score.file'))->static()->staticSchema(amisMake()->Link()->blank()),
amisMake()->TextControl()->name('check_status_text')->label(__('user_score.check_status'))->static(),
amisMake()->TextControl()->name('check_user.name')->label(__('user_score.check_user_id'))->static(),
amisMake()->TextControl()->name('check_remarks')->label(__('user_score.check_remarks'))->static(),
amisMake()->TextControl()->name('check_at')->label(__('user_score.check_at'))->static(),
amisMake()->TextControl()->name('score')->label(__('user_score.score'))->static(),
amisMake()->TextControl()->name('created_at')->label(__('user_score.created_at'))->static(),
]);
}
public function check($id, Request $request)
{
$info = UserScore::findOrFail($id);
try {
$this->service->check($info, $request->all());
return $this->response()->success();
} catch (BaseException $e) {
return $this->response()->fail($e->getMessage());
}
}
public function getTypeOptions()
{
if (!$this->typeOptions) {
$this->typeOptions = UserScore::getTypeList()->map(fn($item) => ['value' => $item->id, 'label' => $item->name]);
}
return $this->typeOptions;
}
public function getUserOptions()
{
if (!$this->userOptions) {
$this->userOptions = PartyUser::select(['id as value', 'name as label'])->get();
}
return $this->userOptions;
}
}

View File

@ -32,7 +32,7 @@ class ArticleService extends BaseService
return $query->sort();
}
public function resloveData($data)
public function resloveData($data, $model = null)
{
$cid = data_get($data, 'category_id');
if ($cid && $category = Keyword::find($cid)) {
@ -48,6 +48,7 @@ class ArticleService extends BaseService
public function validate($data, $model = null)
{
$createRules = [
'title' => 'required',
];
$updateRules = [
];

View File

@ -19,7 +19,7 @@ class BaseService extends AdminService
public function getTree()
{
$list = $this->query()->orderByDesc('sort')->get()->toArray();
$list = $this->query()->get()->toArray();
return array2tree($list);
}
@ -79,8 +79,8 @@ class BaseService extends AdminService
public function update($primaryKey, $data): bool
{
$data = $this->resloveData($data);
$model = $this->query()->whereKey($primaryKey)->firstOrFail();
$data = $this->resloveData($data, $model);
$validate = $this->validate($data, $model);
if ($validate !== true) {
$this->setError($validate);
@ -105,9 +105,10 @@ class BaseService extends AdminService
* 处理表单数据
*
* @param array $data
* @param Model $model : 添加, 非空: 修改
* @return array
*/
public function resloveData($data)
public function resloveData($data, $model = null)
{
return $data;
}
@ -121,6 +122,19 @@ class BaseService extends AdminService
*/
public function validate($data, $model = null)
{
// $createRules = [
// 'key' => ['required', Rule::unique('keywords', 'key')],
// 'name' => ['required'],
// ];
// $updateRules = [
// 'key' => [Rule::unique('keywords', 'key')->ignore($model->id)]
// ];
// $validator = Validator::make($data, $model ? $updateRules : $createRules, [
// 'key.unique' => ':input 已经存在'
// ]);
// if ($validator->fails()) {
// return $validator->errors()->first();
// }
return true;
}

View File

@ -56,7 +56,7 @@ class KeywordService extends BaseService
'name' => ['required'],
];
$updateRules = [
'key' => [Rule::unique('keywords', 'key')->ignore($model->id)]
'key' => [Rule::unique('keywords', 'key')->ignore($model?->id)]
];
$validator = Validator::make($data, $model ? $updateRules : $createRules, [
'key.unique' => ':input 已经存在'
@ -67,7 +67,7 @@ class KeywordService extends BaseService
return true;
}
public function resloveData($data)
public function resloveData($data, $model = null)
{
$parent_id = data_get($data, 'parent_id');
if (!is_null($parent_id)) {

View File

@ -0,0 +1,53 @@
<?php
namespace App\Admin\Services;
use App\ModelFilters\PartyCateFilter;
use App\Models\Keyword;
use App\Models\PartyCate;
use App\Models\PartyUser;
use App\Models\UserScore;
class PartyCateService extends BaseService
{
protected array $withRelationships = ['master', 'plan'];
protected string $modelName = PartyCate::class;
protected string $modelFilterName = PartyCateFilter::class;
public function preDelete(array $ids)
{
$userIds = PartyUser::whereIn('cate_id', $ids)->pluck('id');
// 删除支部下面的党员记录
PartyUser::whereIn('cate_id', $ids)->delete();
// 删除党员下面的审核记录
UserScore::whereIn('user_id', $userIds)->delete();
return true;
}
public function resloveData($data, $model = null)
{
if (!$model) {
$list = UserScore::getTypeList();
$scores = [];
foreach ($list as $item) {
$scores[$item->key] = 0;
}
$data['scores'] = $scores;
}
return $data;
}
public function incrementScore(PartyCate $info, $type, $score)
{
$scores = $info->scores;
if (isset($scores[$type])) {
$scores[$type] += $score;
}
$info->update([
'score' => $info->score + $score,
'scores' => $scores,
]);
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace App\Admin\Services;
use App\ModelFilters\PartyUserFilter;
use App\Models\Keyword;
use App\Models\PartyUser;
use App\Models\UserScore;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class PartyUserService extends BaseService
{
protected array $withRelationships = ['cate'];
protected string $modelName = PartyUser::class;
protected string $modelFilterName = PartyUserFilter::class;
public function validate($data, $model = null)
{
$createRules = [
'username' => ['required', Rule::unique('party_users', 'username')],
'password' => ['required'],
'name' => ['required'],
];
$updateRules = [
'username' => [Rule::unique('party_users', 'username')->ignore($model?->id)]
];
$validator = Validator::make($data, $model ? $updateRules : $createRules, [
'username.required' => __('party_user.username') . '必填',
'password.required' => __('party_user.password') . '必填',
'name.required' => __('party_user.name') . '必填',
'username.unique' => ':input 已经存在',
]);
if ($validator->fails()) {
return $validator->errors()->first();
}
return true;
}
public function resloveData($data, $model = null)
{
if (!$model) {
$list = UserScore::getTypeList();
$scores = [];
foreach ($list as $item) {
$scores[$item->key] = 0;
}
$data['scores'] = $scores;
}
return $data;
}
public function incrementScore(PartyUser $user, $type, $score)
{
$scores = $user->scores;
if (isset($scores[$type])) {
$scores[$type] += $score;
}
$user->update([
'score' => $user->score + $score,
'scores' => $scores,
]);
if ($user->cate) {
PartyCateService::make()->incrementScore($user->cate, $type, $score);
}
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Admin\Services;
use App\Enums\CheckStatus;
use App\Exceptions\BaseException;
use App\ModelFilters\UserScoreFilter;
use App\Models\UserScore;
use Slowlyo\OwlAdmin\Admin;
class UserScoreService extends BaseService
{
protected array $withRelationships = ['user', 'type', 'checkUser'];
protected string $modelName = UserScore::class;
protected string $modelFilterName = UserScoreFilter::class;
public function check(UserScore $info, $options = [])
{
if ($info->check_status == CheckStatus::Success) {
throw new BaseException('已经审核过了');
}
$status = data_get($options, 'check_status');
$attributes = [
'check_status' => $status,
'check_remarks' => data_get($options, 'check_remarks'),
'check_user_id' => data_get($options, 'check_user_id', Admin::user()->id),
'check_at' => now(),
];
if ($status == CheckStatus::Success->value) {
$attributes['score'] = data_get($options, 'score', 0);
if ($attributes['score'] <= 0) {
throw new BaseException('得分必填');
}
PartyUserService::make()->incrementScore($info->user, $info->type?->key, $attributes['score']);
}
$info->update($attributes);
}
}

View File

@ -29,6 +29,15 @@ Route::group([
// 字典表
$router->resource('keywords', \App\Admin\Controllers\KeywordsController::class)->names('admin.keywords');
$router->resource('articles', \App\Admin\Controllers\ArticleController::class);
// 文章
$router->resource('articles', \App\Admin\Controllers\ArticleController::class)->names('admin.article');
$router->post('quick-edit/article/{article}', [\App\Admin\Controllers\ArticleController::class, 'update']);
// 党支部
$router->resource('party-cate', \App\Admin\Controllers\PartyCateController::class)->names('admin.party_cate');
// 党员
$router->resource('party-user', \App\Admin\Controllers\PartyUserController::class)->names('admin.party_user');
// 评议审核
$router->post('user-score/{id}/check', [\App\Admin\Controllers\UserScoreController::class, 'check']);
$router->resource('user-score', \App\Admin\Controllers\UserScoreController::class)->names('admin.user_score');
});

View File

@ -0,0 +1,33 @@
<?php
namespace App\Enums;
enum CheckStatus: int
{
case None = 0;
case Success = 1;
case Fail = 2;
public static function map()
{
return [
self::None->value => '待审核',
self::Success->value => '通过',
self::Fail->value => '不通过',
];
}
public static function options()
{
$list = [];
foreach (static::map() as $key => $value) {
array_push($list, ['label' => $value, 'value' => $key]);
}
return $list;
}
public function text()
{
return data_get(self::map(), $this->value);
}
}

View File

@ -5,8 +5,14 @@ namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Slowlyo\OwlAdmin\Admin;
class Controller extends BaseController
{
use AuthorizesRequests, ValidatesRequests;
protected function response()
{
return Admin::response();
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
class WebController extends Controller
{
public function upload(Request $request)
{
$path = $request->input('path', 'uploads').'/'.date('Y-m-d');
$result = [];
$disk = $this->getDisk();
// file 文件
$files = $request->except('path');
foreach ($files as $key => $fileData) {
$item = null;
if (is_array($fileData)) {
foreach ($fileData as $file) {
$item[] = $disk->url($this->saveFile($disk, $path, $file));
}
} else {
$item = $disk->url($this->saveFile($disk, $path, $fileData));
}
$result[$key] = $item;
}
return $this->response()->success($result);
}
protected function saveFile($disk, $path, $file = null)
{
$filePath = '';
if ($file instanceof UploadedFile) {
//限制文件类型:
if(in_array($file->getClientOriginalExtension(), [
'jpeg', 'jpg', 'gif', 'bmp', 'png', //图片
'mp4', //视频
'mp3', //音频
])){
$filePath = $disk->putFile($path, $file);
}
} elseif (preg_match('/^(data:\s*image\/(\w+);base64,)/', $file, $result)) {
$type = $result[2];
if (in_array($type, ['jpeg', 'jpg', 'gif', 'bmp', 'png'])) {
$filePath = $path.'/'.uniqid().'.'.$type;
$disk->put($filePath, base64_decode(str_replace($result[1], '', $file)));
}
}
return $filePath;
}
protected function getDisk($disk = null): Filesystem
{
return Storage::disk($disk);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\ModelFilters;
use EloquentFilter\ModelFilter;
class PartyCateFilter extends ModelFilter
{
/**
* Related Models that have ModelFilters as well as the method on the ModelFilter
* As [relationMethod => [input_key1, input_key2]].
*
* @var array
*/
public $relations = [];
public function name($name)
{
$this->whereLike('name', $name);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\ModelFilters;
use EloquentFilter\ModelFilter;
class PartyUserFilter extends ModelFilter
{
/**
* Related Models that have ModelFilters as well as the method on the ModelFilter
* As [relationMethod => [input_key1, input_key2]].
*
* @var array
*/
public $relations = [];
public function name($name)
{
$this->whereLike('name', $name);
}
public function cate($id)
{
$this->where('cate_id', $id);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\ModelFilters;
use EloquentFilter\ModelFilter;
class UserScoreFilter extends ModelFilter
{
/**
* Related Models that have ModelFilters as well as the method on the ModelFilter
* As [relationMethod => [input_key1, input_key2]].
*
* @var array
*/
public $relations = [];
public function user($id)
{
$this->where('user_id', $id);
}
public function type($id)
{
$this->where('type_id', $id);
}
public function checkStatus($id)
{
$this->where('check_status', $id);
}
public function title($key)
{
$this->whereLike('title', $key);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable;
/**
* 党支部
*/
class PartyCate extends Model
{
use HasDateTimeFormatter, Filterable;
protected $fillable = ['name', 'master_id', 'plan_id', 'remarks', 'score', 'scores'];
protected $casts = [
'scores' => 'array'
];
public function master()
{
return $this->belongsTo(PartyUser::class, 'master_id');
}
public function plan()
{
return $this->belongsTo(PartyUser::class, 'plan_id');
}
public function users()
{
return $this->hasMany(PartyUser::class, 'cate_id');
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Models;
use App\Traits\HasDateTimeFormatter;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;
use EloquentFilter\Filterable;
use App\Casts\StorageFile;
/**
* 党员
*/
class PartyUser extends Authenticatable
{
use HasDateTimeFormatter, Filterable, HasApiTokens;
protected $fillable = ['username', 'password', 'name', 'avatar', 'cate_id', 'remarks', 'score', 'scores'];
protected $hidden = ['password'];
protected $casts = [
'password' => 'encrypted',
'avatar' => StorageFile::class,
'scores' => 'array',
];
public function cate()
{
return $this->belongsTo(PartyCate::class, 'cate_id');
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace App\Models;
use App\Casts\StorageFile;
use App\Enums\CheckStatus;
use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Slowlyo\OwlAdmin\Models\AdminUser;
/**
* 党员审核记录
*/
class UserScore extends Model
{
use HasDateTimeFormatter, Filterable;
protected $fillable = ['type_id', 'user_id', 'title', 'content', 'images', 'file', 'check_status', 'check_user_id', 'check_remarks', 'check_at', 'score'];
protected $casts = [
'images' => 'array',
'file' => StorageFile::class,
'check_status' => CheckStatus::class,
'check_at' => 'datetime',
];
protected $attributes = [
'check_status' => CheckStatus::None,
];
protected $appends = ['check_status_text'];
public static function getTypeList()
{
return Keyword::where('key', 'like', 'score_cate_%')->get();
}
public function type()
{
return $this->belongsTo(Keyword::class, 'type_id');
}
public function user()
{
return $this->belongsTo(PartyUser::class, 'user_id');
}
public function checkUser()
{
return $this->belongsTo(AdminUser::class, 'check_user_id');
}
protected function checkStatusText(): Attribute
{
return new Attribute(
get: fn () => $this->check_status ? $this->check_status->text() : '',
);
}
public function scopeSort($q)
{
return $this->orderBy('check_status')->latest('id');
}
}

View File

@ -31,7 +31,7 @@ return [
// 是否开启验证码
'login_captcha' => env('ADMIN_LOGIN_CAPTCHA', true),
// 是否开启鉴权
'enable' => false,
'enable' => true,
// 用户模型
'model' => \Slowlyo\OwlAdmin\Models\AdminUser::class,
'controller' => \Slowlyo\OwlAdmin\Controllers\AuthController::class,

View File

@ -40,6 +40,10 @@ return [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'sanctum',
'provider' => 'party'
]
],
/*
@ -64,6 +68,10 @@ return [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'party' => [
'driver' => 'eloquent',
'model' => App\Models\PartyUser::class,
]
// 'users' => [
// 'driver' => 'database',

View File

@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('party_cates', function (Blueprint $table) {
$table->id();
$table->string('name')->comment('党支部名称');
$table->unsignedBigInteger('master_id')->nullable()->comment('党支部书记');
$table->unsignedBigInteger('plan_id')->nullable()->comment('组织委员');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamps();
$table->comment('党支部');
});
Schema::create('party_users', function (Blueprint $table) {
$table->id();
$table->string('username')->unique()->comment('登录账户');
$table->string('password')->comment('登录密码');
$table->string('name')->comment('姓名');
$table->string('avatar')->nullable()->comment('头像');
$table->unsignedBigInteger('cate_id')->nullable()->comment('党支部id');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamps();
$table->comment('党员');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('party_cates');
Schema::dropIfExists('party_users');
}
};

View File

@ -0,0 +1,55 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_scores', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('type_id')->comment('类别, keywords.id, score_cate');
$table->unsignedBigInteger('user_id')->comment('提交人, party_user.id');
$table->string('title')->nullable()->comment('主题');
$table->text('content')->nullable()->comment('内容');
$table->json('images')->nullable()->comment('图片');
$table->string('file')->nullable()->comment('附件');
$table->unsignedTinyInteger('check_status')->default(0)->comment('审核状态(0: 待审核, 1: 审核通过, 2: 审核不通过)');
$table->unsignedBigInteger('check_user_id')->nullable()->comment('审核人');
$table->timestamp('check_at')->nullable()->comment('审核时间');
$table->string('check_remarks')->nullable()->comment('审核备注');
$table->unsignedInteger('score')->default(0)->comment('得分');
$table->timestamps();
});
Schema::table('party_users', function (Blueprint $table) {
$table->unsignedInteger('score')->default(0)->comment('累计得分');
$table->json('scores')->nullable()->comment('每项得分{score_cate_1: 10}');
});
Schema::table('party_cates', function (Blueprint $table) {
$table->unsignedInteger('score')->default(0)->comment('累计得分');
$table->json('scores')->nullable()->comment('每项得分{score_cate_1: 10}');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_scores');
Schema::table('party_users', function (Blueprint $table) {
$table->dropColumn(['score', 'scores']);
});
Schema::table('party_cates', function (Blueprint $table) {
$table->dropColumn(['score', 'scores']);
});
}
};

View File

@ -19,6 +19,9 @@ class AdminMenuSeeder extends Seeder
// 图标: https://iconpark.oceanengine.com/official
$menus = [
['title' => '主页', 'icon' => 'icon-park:home-two', 'url' => '/dashboard', 'is_home' => 1],
['title' => '支部管理', 'icon' => 'icon-park:flag', 'url' => '/party-cate'],
['title' => '党员管理', 'icon' => 'icon-park:every-user', 'url' => '/party-user'],
['title' => '审核评定', 'icon' => 'icon-park:internal-data', 'url' => '/user-score'],
['title' => '文章管理', 'icon' => 'icon-park:web-page', 'url' => '/articles'],
['title' => '系统管理', 'icon' => 'icon-park:setting', 'url' => '/system', 'children' => [
['title' => '用户管理', 'icon' => 'icon-park:people-plus', 'url' => '/system/admin_users'],

View File

@ -17,30 +17,12 @@ class KeywordSeeder extends Seeder
Keyword::truncate();
$list = [
['key' => 'product_category', 'name' => '商品分类', 'children' => [
['name' => '家用电器', 'children' => [
['name' => '电视'],
['name' => '冰箱'],
['name' => '洗衣机'],
]],
['name' => '手机数码', 'children' => [
['name' => '手机'],
['name' => '手机配件'],
['name' => '摄影摄像'],
]],
['name' => '电脑办公', 'children' => [
['name' => '电脑整机'],
['name' => '外设产品'],
['name' => '网络产品'],
]]
]],
['key' => 'article_category', 'name' => '文章分类', 'children' => [
['name' => '后端'],
['name' => '前端'],
['name' => 'Android'],
['name' => 'IOS'],
['name' => '开发工具'],
['name' => '人工智能'],
['key' => 'score_cate', 'name' => '考核指标', 'children' => [
['key' => 'score_cate_1', 'name' => '政治忠诚'],
['key' => 'score_cate_2', 'name' => '政治定力'],
['key' => 'score_cate_3', 'name' => '政治担当'],
['key' => 'score_cate_4', 'name' => '政治能力'],
['key' => 'score_cate_5', 'name' => '政治自律'],
]]
];
@ -51,9 +33,9 @@ class KeywordSeeder extends Seeder
{
foreach ($list as $index => $item) {
$params = Arr::except($item, ['children']);
$params['sort'] = $index;
$params['sort'] = $index + 1;
$params['parent_id'] = $parent ? $parent->id : 0;
$params['key'] = data_get($item, 'key', data_get($parent, 'key') . '_' . $index);
$params['key'] = data_get($item, 'key', data_get($parent, 'key') . '_' . $params['sort']);
$model = Keyword::create($params);
if ($children = data_get($item, 'children')) {

View File

@ -8,7 +8,7 @@ return [
'parent_id' => '上级',
'type_key' => '上级',
'path' => '上级',
'sort' => '排序(序)',
'sort' => '排序(序)',
'level' => '层级',
'options' => '扩展',
'image' => '图片',

View File

@ -0,0 +1,14 @@
<?php
return [
'id' => 'ID',
'created_at' => '创建时间',
'updated_at' => '更新时间',
'name' => '名称',
'master_id' => '书记',
'plan_id' => '组织委员',
'remarks' => '备注',
'score' => '累计得分',
'scores' => '五星维度',
];

View File

@ -0,0 +1,16 @@
<?php
return [
'id' => 'ID',
'created_at' => '创建时间',
'updated_at' => '更新时间',
'username' => '登录名',
'password' => '登录密码',
'name' => '姓名',
'avatar' => '头像',
'cate_id' => '党支部',
'remarks' => '备注',
'score' => '累计得分',
'scores' => '五星维度',
];

View File

@ -0,0 +1,19 @@
<?php
return [
'id' => 'ID',
'created_at' => '提交时间',
'updated_at' => '更新时间',
'type_id' => '分类',
'user_id' => '党员',
'title' => '主题',
'content' => '内容',
'images' => '图片',
'file' => '附件',
'check_status' => '状态',
'check_user_id' => '审核人',
'check_remarks' => '未通过原因',
'check_at' => '审核时间',
'score' => '得分',
];

View File

@ -14,6 +14,4 @@ use Illuminate\Support\Facades\Route;
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('web/upload', [\App\Http\Controllers\WebController::class, 'upload']);