完善部分数据管理

main
vine_liutk 2024-01-16 16:59:42 +08:00
parent 0719b391a8
commit 0cf6c539fa
14 changed files with 289 additions and 101 deletions

View File

@ -1,66 +0,0 @@
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
<p align="center">
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
### Premium Partners
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[WebReinvent](https://webreinvent.com/)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
- **[Jump24](https://jump24.co.uk)**
- **[Redberry](https://redberry.international/laravel/)**
- **[Active Logic](https://activelogic.com)**
- **[byte5](https://byte5.de)**
- **[OP.GG](https://op.gg)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

View File

@ -15,7 +15,7 @@ class Components extends BaseRenderer {
{
return amisMake()->TreeSelectControl()->source($apiUrl)
->name($name)->label($label ?? __('admin.components.parent_select'))
->showIcon(false)
// ->showIcon(false)
->labelField($labelField)
->valueField($valueField);
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\TableColumn;
use Slowlyo\OwlAdmin\Renderers\TextControl;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\BuildingService;
use App\Models\Keyword;
use App\Admin\Components;
use Illuminate\Http\Request;
class BuildingController extends AdminController
{
protected string $serviceName = BuildingService::class;
public function list(): Page
{
$crud = $this->baseCRUD()
//去掉分页-start
->loadDataOnce(true)
->footerToolbar([])
//去掉分页-end
->headerToolbar([
$this->createButton(true),
amis('reload')->align('right'),
amis('filter-toggler')->align('right'),
])
->filter($this->baseFilter()->body([
amis()->TextControl('name', __('admin.keyword'))
->size('md')
->placeholder(__('admin.keywords.search_name')),
// amis()->TextControl('parent_name', __('admin.keywords.parent_keyword'))
// ->size('md')
// ->placeholder(__('admin.keywords.search_name'))
]
))
->columns([
// TableColumn::make()->name('id')->label('ID')->sortable(true),
TableColumn::make()->name('parent.name')->label('小区'),
TableColumn::make()->name('name')->label('名称'),
TableColumn::make()->name('sort')->label('排序'),
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
amisMake()->Operation()->label(__('admin.actions'))->buttons([
$this->rowEditButton(true),
$this->rowDeleteButton(),
]),
]);
return $this->baseList($crud);
}
public function form(): Form
{
$form = $this->baseForm()->body([
TextControl::make()->name('name')->label('名称')->required(true),
amisMake()->selectControl('parent_id', '小区')->options(Keyword::where('parent_key', 'housing_estate')->pluck('name', 'id')->toArray())->required(true),
amisMake()->NumberControl()->name('sort')->value(0)->min()->label('排序'),
]);
return $form;
}
public function getTreeList(Request $request){
return $this->service->getTree();
}
}

View File

@ -8,6 +8,7 @@ use Slowlyo\OwlAdmin\Renderers\TableColumn;
use Slowlyo\OwlAdmin\Renderers\TextControl;
use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\KeywordService;
use App\Models\Keyword;
use App\Admin\Components;
use Illuminate\Http\Request;
@ -17,6 +18,24 @@ class KeywordController extends AdminController
public function list(): Page
{
//区分特殊管理和通用管理
$columnsArr = [];
$parentName = request()->get('parent_name', '');
if(!empty($parentName)){
$parentId = Keyword::where('key', $parentName)->value('id');
}
if($parentId > 0 && in_array($parentName, ['financial_cate', 'file_cate', 'department', 'area_cate', 'organized_body', 'housing_estate'])){
$columnsArr [] = TableColumn::make()->name('name')->label('名称');
if($parentName == 'department'){
$columnsArr [] = TableColumn::make()->name('value')->label('类型')->type('mapping')->map([
'1'=> '发文部门', '2'=>'收文部门',
]);
}
}else{
$columnsArr [] = TableColumn::make()->name('name')->label('名称');
$columnsArr [] = TableColumn::make()->name('key')->label('KEY')->copyable(true);
$columnsArr [] = TableColumn::make()->name('value')->label('值');
}
$crud = $this->baseCRUD()
//去掉分页-start
->loadDataOnce(true)
@ -31,36 +50,53 @@ class KeywordController extends AdminController
amis()->TextControl('name', __('admin.keyword'))
->size('md')
->placeholder(__('admin.keywords.search_name')),
amis()->TextControl('parent_name', __('admin.keywords.parent_keyword'))
->size('md')
->placeholder(__('admin.keywords.search_name'))
// amis()->TextControl('parent_name', __('admin.keywords.parent_keyword'))
// ->size('md')
// ->placeholder(__('admin.keywords.search_name'))
]
))
->columns([
->columns(array_merge($columnsArr, [
// TableColumn::make()->name('id')->label('ID')->sortable(true),
TableColumn::make()->name('name')->label('名称'),
TableColumn::make()->name('key')->label('KEY')->copyable(true),
TableColumn::make()->name('value')->label('值'),
TableColumn::make()->name('sort')->label('排序'),
TableColumn::make()->name('created_at')->label('创建时间')->type('datetime')->sortable(true),
amisMake()->Operation()->label(__('admin.actions'))->buttons([
$this->rowEditButton(true),
$this->rowDeleteButton(),
]),
]);
]));
return $this->baseList($crud);
}
public function form(): Form
{
return $this->baseForm()->body([
Components::make()->parentControl(admin_url('api/keywords/tree-list')),
//区分特殊管理和通用管理
$parentName = request()->get('parent_name', '');
$parentId = 0;
if(!empty($parentName)){
$parentId = Keyword::where('key', $parentName)->value('id');
}
$formBody = [
TextControl::make()->name('name')->label('名称')->required(true),
TextControl::make()->name('key')->label('KEY')->required(true),
TextControl::make()->name('value')->label('值'),
];
if($parentId > 0 && in_array($parentName, ['financial_cate', 'file_cate', 'department', 'area_cate', 'organized_body', 'housing_estate'])){
$formBody[] = Components::make()->sortControl('parent_id')->value($parentId)->hidden(true)->readOnly(true);
if($parentName == 'department'){
$formBody[] = amisMake()->RadiosControl('value', '类型')->options([
'1'=> '发文部门', '2'=>'收文部门',
])->required(true);
}
}else{
$formBody[] = Components::make()->parentControl(admin_url('api/keywords/tree-list'));
$formBody[] = TextControl::make()->name('key')->label('KEY')->required(true);
$formBody[] = TextControl::make()->name('value')->label('值');
}
$form = $this->baseForm()->body(array_merge($formBody, [
amisMake()->NumberControl()->name('sort')->value(0)->min()->label('排序'),
]);
]));
return $form;
}
public function getTreeList(Request $request){

View File

@ -32,6 +32,16 @@ Route::group([
$router->resource('ads', \App\Admin\Controllers\AdController::class);
//数据管理
$router->resource('financial_cate', \App\Admin\Controllers\KeywordController::class);
$router->resource('file_cate', \App\Admin\Controllers\KeywordController::class);
$router->resource('department', \App\Admin\Controllers\KeywordController::class);
$router->resource('area_cate', \App\Admin\Controllers\KeywordController::class);
$router->resource('organized_body', \App\Admin\Controllers\KeywordController::class);
$router->resource('housing_estate', \App\Admin\Controllers\KeywordController::class);
$router->resource('building', \App\Admin\Controllers\BuildingController::class);
//修改上传
$router->post('upload_file', [\App\Admin\Controllers\IndexController::class, 'uploadFile']);
$router->post('upload_image', [\App\Admin\Controllers\IndexController::class, 'uploadImage']);

View File

@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use EloquentFilter\Filterable;
use App\Admin\Components;
use Illuminate\Support\Facades\Str;
class Keyword extends Model
{
@ -30,12 +31,19 @@ class Keyword extends Model
$keyword->lv = 1;
// 将 path 设为 -
$keyword->path = '-';
if(empty($keyword->key)){
$keyword->key = Str::quickRandom($length = 16);
}
} else {
// 将层级设为父类目的层级 + 1
$keyword->lv = $keyword->parent->lv ++;
$keyword->lv = $keyword->parent->lv + 1;
$keyword->parent_key = $keyword->parent->key;
// 将 path 值设为父类目的 path 追加父类目 ID 以及最后跟上一个 - 分隔符
$keyword->path = $keyword->parent->path.$keyword->parent_id.'-';
//当前key是否为空
if(empty($keyword->key)){
$keyword->key = $keyword->parent_key . '_' . (self::where('parent_key', $keyword->parent_key)->count() + 1);
}
}
});
}

View File

@ -0,0 +1,114 @@
<?php
namespace App\Services\Admin;
use Illuminate\Support\Arr;
use App\Models\Keyword;
use App\Models\Filters\KeywordFilter;
use Illuminate\Database\Eloquent\Builder;
/**
* @method Keyword getModel()
* @method Keyword|\Illuminate\Database\Query\Builder query()
*/
class BuildingService extends BaseService
{
protected string $modelName = Keyword::class;
protected string $modelFilterName = KeywordFilter::class;
protected array $withRelationships = ['parent'];
public function parentIsChild($id, $pid): bool
{
$parent = $this->query()->find($pid);
do {
if ($parent->parent_id == $id) {
return true;
}
// 如果没有parent 则为顶级 退出循环
$parent = $parent->parent;
} while ($parent);
return false;
}
public function query(): Builder
{
$parentIds = Keyword::where('parent_key', 'housing_estate')->pluck('id');
$query = $this->modelName::query();
return $query->whereIn('parent_id', $parentIds);
}
public function store($data): bool
{
if (isset($data['key']) && $this->hasRepeated($data)) {
return false;
}
$columns = $this->getTableColumns();
$model = $this->getModel();
foreach ($data as $k => $v) {
if (!in_array($k, $columns)) {
continue;
}
$model->setAttribute($k, $v);
}
return $model->save();
}
public function update($primaryKey, $data): bool
{
if (isset($data['key']) && $this->hasRepeated($data, $primaryKey)) {
return false;
}
$columns = $this->getTableColumns();
$pid = Arr::get($data, 'parent_id');
if ($pid != 0) {
if ($this->parentIsChild($primaryKey, $pid)) {
$this->setError('父级不允许设置为当前子权限');
return false;
}
}
$model = $this->query()->whereKey($primaryKey)->first();
foreach ($data as $k => $v) {
if (!in_array($k, $columns)) {
continue;
}
$model->setAttribute($k, $v);
}
return $model->save();
}
public function hasRepeated($data, $id = 0): bool
{
$query = $this->query()->when($id, fn($query) => $query->where('id', '<>', $id));
if ((clone $query)->where('key', $data['key'])->exists()) {
$this->setError('KEY重复');
return true;
}
return false;
}
public function delete(string $ids): mixed
{
$ids = explode(',', $ids);
if(count($ids) == 1){
$this->query()->where('path', 'like', '%-'.$ids[0].'-%')->delete();
}
return $this->query()->whereIn('id', $ids)->delete();
}
}

View File

@ -44,7 +44,7 @@ class KeywordService extends BaseService
public function store($data): bool
{
if ($this->hasRepeated($data)) {
if (isset($data['key']) && $this->hasRepeated($data)) {
return false;
}
@ -65,7 +65,7 @@ class KeywordService extends BaseService
public function update($primaryKey, $data): bool
{
if ($this->hasRepeated($data, $primaryKey)) {
if (isset($data['key']) && $this->hasRepeated($data, $primaryKey)) {
return false;
}

View File

@ -2,7 +2,7 @@
return [
// 应用名称
'name' => 'Owl Admin',
'name' => '道角村智慧党群服务平台',
// 应用 logo
'logo' => '/admin/logo.png',
@ -84,7 +84,7 @@ return [
'layout' => [
// 浏览器标题, 功能名称使用 %title% 代替
'title' => '%title% | OwlAdmin',
'title' => '道角村智慧党群服务平台 | %title%',
'header' => [
// 是否显示 [刷新] 按钮
'refresh' => true,

View File

@ -24,16 +24,24 @@ class AdminMenuSeeder extends Seeder
'children' => [
['title' => 'admin_users', 'icon' => 'ph:user-gear', 'url' => '/system/admin_users', 'order'=>1],
['title' => 'admin_roles', 'icon' => 'carbon:user-role', 'url' => '/system/admin_roles', 'order'=>2],
['title' => 'admin_permission', 'icon' => 'carbon:user-role', 'url' => '/system/admin_permissions', 'order'=>3],
['title' => 'admin_menu', 'icon' => 'fluent-mdl2:permissions', 'url' => '/system/admin_menus', 'order'=>4],
// ['title' => 'admin_permission', 'icon' => 'carbon:user-role', 'url' => '/system/admin_permissions', 'order'=>3],
// ['title' => 'admin_menu', 'icon' => 'fluent-mdl2:permissions', 'url' => '/system/admin_menus', 'order'=>4],
['title' => 'admin_setting', 'icon' => 'akar-icons:settings-horizontal', 'url' => '/system/settings', 'order'=>5],
['title' => 'keywords', 'icon' => 'ph:codesandbox-logo-light', 'url' => '/system/keywords', 'order'=>6]
],
],
['title' => 'web_content', 'icon' => 'ic:outline-collections-bookmark', 'url' => '', 'order'=>3,
['title' => 'data_content', 'icon' => 'ph:codesandbox-logo-light', 'url' => '', 'order'=>3,
'children' =>[
['title'=>'articles', 'icon'=>'ic:outline-article','url'=>'/articles', 'order'=>1],
['title'=>'ads', 'icon'=>'lets-icons:img-box','url'=>'/ads', 'order'=>2],
//财务报表类型,档案类型,部门管理,地区类型,社别管理,小区管理,楼栋管理,户籍类型,民族管理,政治面貌,文化程度,机构管理,口头纠纷类型,卫生检查类型,图书类型,企业地区管理,收支情况类型,福利类型,工种管理
['title' => 'financial_cate', 'icon' => 'tabler:zoom-money', 'url' => '/financial_cate?parent_name=financial_cate&has_owner=0', 'order'=>0],//财务报表类型
['title' => 'file_cate', 'icon' => 'carbon:document-unknown', 'url' => '/file_cate?parent_name=file_cate&has_owner=0', 'order'=>1],//档案类型
['title' => 'department', 'icon' => 'mingcute:department-line', 'url' => '/department?parent_name=department&has_owner=0', 'order'=>2],//部门管理
['title' => 'area_cate', 'icon' => 'majesticons:map-marker-area-line', 'url' => '/area_cate?parent_name=area_cate&has_owner=0', 'order'=>3],//地区类型
['title' => 'organized_body', 'icon' => 'ic:baseline-people-outline', 'url' => '/organized_body?parent_name=organized_body&has_owner=0', 'order'=>4],//社别管理
['title' => 'housing_estate', 'icon' => 'bx:building-house', 'url' => '/housing_estate?parent_name=housing_estate&has_owner=0', 'order'=>5],//小区管理
['title' => 'building', 'icon' => 'fe:building', 'url' => '/building', 'order'=>6],//楼栋管理
// ['title'=>'articles', 'icon'=>'ic:outline-article','url'=>'/articles', 'order'=>1],
// ['title'=>'ads', 'icon'=>'lets-icons:img-box','url'=>'/ads', 'order'=>2],
]
]
];

View File

@ -17,15 +17,16 @@ class KeywordSeeder extends Seeder
{
Keyword::truncate();
$list = [
['key' => 'article_category', 'name' => '文章分类', 'list' => [
]],
['key' => 'article_tag', 'name' => '文章标签', 'list' => [//标签value填写色号指定标签颜色
]],
['key' => 'banner_address', 'name' => '广告位置', 'list' => [
]],
['key' => 'article_category', 'name' => '文章分类', 'list' => []],
//标签value填写色号指定标签颜色
['key' => 'article_tag', 'name' => '文章标签', 'list' => []],
['key' => 'banner_address', 'name' => '广告位置', 'list' => []],
['key' => 'financial_cate', 'name' => '财务报表类型', 'list' => []],
['key' => 'file_cate', 'name' => '档案类型', 'list' => []],
['key' => 'department', 'name' => '部门管理', 'list' => []],
['key' => 'area_cate', 'name' => '地区类型', 'list' => []],
['key' => 'organized_body', 'name' => '社别管理', 'list' => []],
['key' => 'housing_estate', 'name' => '小区管理', 'list' => []],
];
foreach ($list as $item) {

View File

@ -13,4 +13,12 @@ return [
'web_content' => '内容管理',
'articles' => '文章管理',
'ads' => '广告管理',
'data_content' => '数据管理',
'financial_cate' => '财务报表类型',
'file_cate' => '档案类型',
'department' => '部门管理',
'area_cate' => '地区类型',
'organized_body' => '社别管理',
'housing_estate' => '小区管理',
'building' => '楼栋管理',
];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB