From 8c537e665694593697db32ba22ab2c3035487cd1 Mon Sep 17 00:00:00 2001 From: JaguarJack Date: Wed, 7 Dec 2022 19:28:57 +0800 Subject: [PATCH] feat: permissions --- .../Contracts/ModuleRepositoryInterface.php | 2 + .../Support/Module/Driver/DatabaseDriver.php | 12 ++ .../src/Support/Module/Driver/FileDriver.php | 11 ++ catch/src/Support/Module/ModuleRepository.php | 11 ++ catch/src/Traits/DB/BaseOperate.php | 39 +++++- .../Support/Generate/Create/FrontTable.php | 23 +++- .../Support/Generate/Create/Schema.php | 8 +- .../Support/Generate/stubs/controller.stub | 2 +- .../Support/Generate/stubs/vue/form.stub | 24 ++-- .../Generate/stubs/vue/formItems/select.stub | 2 +- .../Support/Generate/stubs/vue/table.stub | 31 ++--- modules/Develop/views/module/create.vue | 12 +- modules/Develop/views/module/index.vue | 76 +++-------- modules/Develop/views/schema/create.vue | 16 ++- modules/Develop/views/schema/index.vue | 83 ++++-------- modules/Develop/views/schema/show.vue | 13 +- modules/Develop/views/schema/steps/schema.vue | 2 +- .../Controllers/DepartmentsController.php | 51 +++++++ .../Http/Controllers/JobsController.php | 9 +- .../Controllers/PermissionsController.php | 46 +++++++ .../Permissions/Models/DepartmentsModel.php | 51 +++++++ modules/Permissions/Models/JobsModel.php | 4 +- .../Permissions/Models/PermissionsModel.php | 58 ++++++++ .../2022_12_06_110551_create_jobs.php | 25 ++-- .../2022_12_07_075441_create_departments.php | 43 ++++++ .../2022_12_07_102456_create_permissions.php | 48 +++++++ .../2022_12_07_103318_create_permissions.php | 48 +++++++ modules/Permissions/route.php | 15 +- .../Permissions/views/departments/create.vue | 79 +++++++++++ .../Permissions/views/departments/index.vue | 56 ++++++++ modules/Permissions/views/jobs/create.vue | 21 +-- modules/Permissions/views/jobs/index.vue | 46 +++---- .../Permissions/views/permissions/create.vue | 128 ++++++++++++++++++ .../Permissions/views/permissions/index.vue | 52 +++++++ modules/Permissions/views/roles/create.vue | 41 +++--- modules/Permissions/views/roles/index.vue | 57 ++------ modules/Permissions/views/router.ts | 12 ++ .../admin/components/admin/paginate/index.vue | 24 +--- .../admin/components/admin/status/index.vue | 12 +- .../admin/components/admin/table/operate.vue | 22 ++- resources/admin/composables/curd/useCreate.ts | 12 +- .../admin/composables/curd/useEnabled.ts | 20 ++- resources/admin/composables/curd/useOpen.ts | 21 +++ resources/admin/composables/curd/useShow.ts | 32 +++-- .../admin/layout/components/header/index.vue | 2 +- 45 files changed, 1030 insertions(+), 372 deletions(-) create mode 100644 modules/Permissions/Http/Controllers/DepartmentsController.php create mode 100644 modules/Permissions/Http/Controllers/PermissionsController.php create mode 100644 modules/Permissions/Models/DepartmentsModel.php create mode 100644 modules/Permissions/Models/PermissionsModel.php create mode 100644 modules/Permissions/database/migrations/2022_12_07_075441_create_departments.php create mode 100644 modules/Permissions/database/migrations/2022_12_07_102456_create_permissions.php create mode 100644 modules/Permissions/database/migrations/2022_12_07_103318_create_permissions.php create mode 100644 modules/Permissions/views/departments/create.vue create mode 100644 modules/Permissions/views/departments/index.vue create mode 100644 modules/Permissions/views/permissions/create.vue create mode 100644 modules/Permissions/views/permissions/index.vue create mode 100644 resources/admin/composables/curd/useOpen.ts diff --git a/catch/src/Contracts/ModuleRepositoryInterface.php b/catch/src/Contracts/ModuleRepositoryInterface.php index 737a9b7..c5dbe06 100644 --- a/catch/src/Contracts/ModuleRepositoryInterface.php +++ b/catch/src/Contracts/ModuleRepositoryInterface.php @@ -32,4 +32,6 @@ interface ModuleRepositoryInterface public function disOrEnable(string $name): bool|int; public function getEnabled(): Collection; + + public function enabled(string $moduleName): bool; } diff --git a/catch/src/Support/Module/Driver/DatabaseDriver.php b/catch/src/Support/Module/Driver/DatabaseDriver.php index 0294860..90dca40 100644 --- a/catch/src/Support/Module/Driver/DatabaseDriver.php +++ b/catch/src/Support/Module/Driver/DatabaseDriver.php @@ -135,6 +135,18 @@ class DatabaseDriver implements ModuleRepositoryInterface return $this->model->where('status', Status::Enable->value())->get(); } + /** + * enabled + * + * @param string $moduleName + * @return bool + */ + public function enabled(string $moduleName): bool + { + // TODO: Implement enabled() method. + return $this->getEnabled()->pluck('path')->contains($moduleName); + } + /** * * @param array $module diff --git a/catch/src/Support/Module/Driver/FileDriver.php b/catch/src/Support/Module/Driver/FileDriver.php index 5aaeccf..709f8ce 100644 --- a/catch/src/Support/Module/Driver/FileDriver.php +++ b/catch/src/Support/Module/Driver/FileDriver.php @@ -172,6 +172,17 @@ class FileDriver implements ModuleRepositoryInterface return $this->all()->where('enable', true)->values(); } + /** + * enabled + * @param string $moduleName + * @return bool + */ + public function enabled(string $moduleName): bool + { + // TODO: Implement enabled() method. + return $this->getEnabled()->pluck('path')->contains($moduleName); + } + /** * * @param array $module diff --git a/catch/src/Support/Module/ModuleRepository.php b/catch/src/Support/Module/ModuleRepository.php index ba85043..a7dfe8b 100644 --- a/catch/src/Support/Module/ModuleRepository.php +++ b/catch/src/Support/Module/ModuleRepository.php @@ -141,4 +141,15 @@ class ModuleRepository // TODO: Implement getEnabled() method. return $this->moduleRepository->getEnabled(); } + + /** + * enabled + * + * @param string $moduleName + * @return bool + */ + public function enabled(string $moduleName): bool + { + return $this->moduleRepository->enabled($moduleName); + } } diff --git a/catch/src/Traits/DB/BaseOperate.php b/catch/src/Traits/DB/BaseOperate.php index e43bb96..30f3076 100644 --- a/catch/src/Traits/DB/BaseOperate.php +++ b/catch/src/Traits/DB/BaseOperate.php @@ -15,7 +15,9 @@ declare(strict_types=1); namespace Catch\Traits\DB; use Catch\Enums\Status; +use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Request; /** @@ -27,6 +29,12 @@ trait BaseOperate protected bool $sortDesc = true; + + /** + * @var string + */ + protected string $parentId = 'parent_id'; + /** * * @@ -178,7 +186,36 @@ trait BaseOperate $model->{$field} = $model->{$field} == Status::Enable->value() ? Status::Disable->value() : Status::Enable->value(); - return $model->save(); + if ($model->save() && in_array($this->parentId, $this->getFillable())) { + $this->updateChildren($id, $field, $model->{$field}); + } + + return true; + } + + + /** + * 递归处理 + * + * @param int|array $parentId + * @param string $field + * @param int $value + */ + public function updateChildren(mixed $parentId, string $field, mixed $value): void + { + if (! $parentId instanceof Arrayable) { + $parentId = Collection::make([$parentId]); + } + + $childrenId = $this->whereIn('parent_id', $parentId)->pluck('id'); + + if ($childrenId->count()) { + if ($this->whereIn('parent_id', $parentId)->update([ + $field => $value + ])) { + $this->updateChildren($childrenId, $field, $value); + } + } } /** diff --git a/modules/Develop/Support/Generate/Create/FrontTable.php b/modules/Develop/Support/Generate/Create/FrontTable.php index 8c32e0d..c75025f 100644 --- a/modules/Develop/Support/Generate/Create/FrontTable.php +++ b/modules/Develop/Support/Generate/Create/FrontTable.php @@ -64,6 +64,10 @@ class FrontTable extends Creator */ protected string $useList = '{useList}'; + /** + * @var string + */ + protected string $tree = '{tree}'; /** * @var array @@ -91,13 +95,14 @@ class FrontTable extends Creator { // TODO: Implement getContent() method. return Str::of(File::get($this->getTableStub()))->replace([ - $this->table, $this->search, $this->api, $this->paginate, $this->useList + $this->table, $this->search, $this->api, $this->paginate, $this->useList, $this->tree ], [ $this->getTableContent(), $this->getSearchContent(), $this->apiString, $this->getPaginateStubContent(), - $this->getUseList() + $this->getUseList(), + $this->getTreeProps() ])->toString(); } @@ -230,6 +235,20 @@ HTML; return 'const { data, query, search, reset, loading } = useGetList(api)'; } + /** + * get tree props + * + * @return string + */ + public function getTreeProps(): string + { + if (in_array('parent_id', array_column($this->structures, 'field'))) { + return ' row-key="id" default-expand-all :tree-props="{ children: \'children\' }"'; + } + + return ' '; + } + /** * set structures * diff --git a/modules/Develop/Support/Generate/Create/Schema.php b/modules/Develop/Support/Generate/Create/Schema.php index c8fcd9d..22b113d 100644 --- a/modules/Develop/Support/Generate/Create/Schema.php +++ b/modules/Develop/Support/Generate/Create/Schema.php @@ -128,8 +128,11 @@ class Schema extends Creator $column = $column->nullable($structure['nullable']); - if ($structure['default']) { - $column = $column->default($structure['default']); + if (is_null($structure['default'])) { + } else { + if (is_numeric($structure['default']) || mb_strlen($structure['default'])) { + $column = $column->default($structure['default']); + } } if ($structure['comment']) { @@ -206,6 +209,7 @@ class Schema extends Creator }) ->when(isset($structure['default']), function ($str, $default) { if (is_numeric($default)) { + $default = intval($default); return $str->append("->default({$default})"); } diff --git a/modules/Develop/Support/Generate/stubs/controller.stub b/modules/Develop/Support/Generate/stubs/controller.stub index dc68af8..1595503 100644 --- a/modules/Develop/Support/Generate/stubs/controller.stub +++ b/modules/Develop/Support/Generate/stubs/controller.stub @@ -16,7 +16,7 @@ class {controller} extends Controller * @param Request $request * @return mixed */ - public function index(Request $request): mixed + public function index(): mixed { return $this->model->getList(); } diff --git a/modules/Develop/Support/Generate/stubs/vue/form.stub b/modules/Develop/Support/Generate/stubs/vue/form.stub index 79683af..8eb9c5b 100644 --- a/modules/Develop/Support/Generate/stubs/vue/form.stub +++ b/modules/Develop/Support/Generate/stubs/vue/form.stub @@ -10,29 +10,21 @@ diff --git a/modules/Develop/Support/Generate/stubs/vue/formItems/select.stub b/modules/Develop/Support/Generate/stubs/vue/formItems/select.stub index 2da70cd..ccebfdb 100644 --- a/modules/Develop/Support/Generate/stubs/vue/formItems/select.stub +++ b/modules/Develop/Support/Generate/stubs/vue/formItems/select.stub @@ -1,5 +1,5 @@ - + -
- - +
+ + {table} @@ -20,43 +20,28 @@
- +
diff --git a/modules/Develop/views/module/create.vue b/modules/Develop/views/module/create.vue index b744625..3248812 100644 --- a/modules/Develop/views/module/create.vue +++ b/modules/Develop/views/module/create.vue @@ -48,7 +48,7 @@ import { useCreate } from '/admin/composables/curd/useCreate' import { useShow } from '/admin/composables/curd/useShow' -import { onMounted, watch } from 'vue' +import { computed, onMounted, watch } from 'vue' const props = defineProps({ primary: String | Number, @@ -79,11 +79,7 @@ watch(isClose, function (value) { } }) -onMounted(() => { - if (props.primary) { - useShow(props.api, props.primary).then(r => { - formData.value = r.data - }) - } -}) +if (props.primary) { + useShow(props.api, props.primary, formData) +} diff --git a/modules/Develop/views/module/index.vue b/modules/Develop/views/module/index.vue index 53a3a52..becd5d5 100644 --- a/modules/Develop/views/module/index.vue +++ b/modules/Develop/views/module/index.vue @@ -1,26 +1,14 @@ diff --git a/modules/Develop/views/schema/create.vue b/modules/Develop/views/schema/create.vue index 49832df..705249a 100644 --- a/modules/Develop/views/schema/create.vue +++ b/modules/Develop/views/schema/create.vue @@ -18,7 +18,7 @@ const next = () => { active.value = 2 } } - +console.log(123) const prev = () => { if (active.value-- === 1) { active.value = 1 @@ -26,10 +26,12 @@ const prev = () => { } const emit = defineEmits(['close']) -watch(() => schemaStore.getFinished, function (value){ - if (value) { - emit('close') - } -}) - +watch( + () => schemaStore.getFinished, + function (value) { + if (value) { + emit('close') + } + }, +) diff --git a/modules/Develop/views/schema/index.vue b/modules/Develop/views/schema/index.vue index 39bc476..f324136 100644 --- a/modules/Develop/views/schema/index.vue +++ b/modules/Develop/views/schema/index.vue @@ -1,35 +1,23 @@ - -
- -
+ - - + + - + diff --git a/modules/Develop/views/schema/show.vue b/modules/Develop/views/schema/show.vue index 39f90b2..36af6cb 100644 --- a/modules/Develop/views/schema/show.vue +++ b/modules/Develop/views/schema/show.vue @@ -1,5 +1,5 @@ diff --git a/modules/Permissions/views/permissions/index.vue b/modules/Permissions/views/permissions/index.vue new file mode 100644 index 0000000..cd450cb --- /dev/null +++ b/modules/Permissions/views/permissions/index.vue @@ -0,0 +1,52 @@ + + + diff --git a/modules/Permissions/views/roles/create.vue b/modules/Permissions/views/roles/create.vue index 851e946..cbd9c35 100644 --- a/modules/Permissions/views/roles/create.vue +++ b/modules/Permissions/views/roles/create.vue @@ -43,7 +43,7 @@ diff --git a/modules/Permissions/views/roles/index.vue b/modules/Permissions/views/roles/index.vue index b16cf4c..70b729d 100644 --- a/modules/Permissions/views/roles/index.vue +++ b/modules/Permissions/views/roles/index.vue @@ -1,25 +1,15 @@ diff --git a/modules/Permissions/views/router.ts b/modules/Permissions/views/router.ts index 6fda820..4590ba2 100644 --- a/modules/Permissions/views/router.ts +++ b/modules/Permissions/views/router.ts @@ -13,12 +13,24 @@ const router: RouteRecordRaw[] = [ meta: { title: '角色管理', icon: 'home' }, component: () => import('./roles/index.vue'), }, + { + path: 'permissions', + name: 'permissions', + meta: { title: '菜单管理', icon: 'home' }, + component: () => import('./permissions/index.vue'), + }, { path: 'jobs', name: 'jobs', meta: { title: '岗位管理', icon: 'home' }, component: () => import('./jobs/index.vue'), }, + { + path: 'departments', + name: 'departments', + meta: { title: '部门管理', icon: 'home' }, + component: () => import('./departments/index.vue'), + }, ], }, ] diff --git a/resources/admin/components/admin/paginate/index.vue b/resources/admin/components/admin/paginate/index.vue index a3b0b30..3d046af 100644 --- a/resources/admin/components/admin/paginate/index.vue +++ b/resources/admin/components/admin/paginate/index.vue @@ -1,29 +1,17 @@ - + diff --git a/resources/admin/components/admin/status/index.vue b/resources/admin/components/admin/status/index.vue index 5f191cd..20372ae 100644 --- a/resources/admin/components/admin/status/index.vue +++ b/resources/admin/components/admin/status/index.vue @@ -5,7 +5,6 @@ diff --git a/resources/admin/components/admin/table/operate.vue b/resources/admin/components/admin/table/operate.vue index 3ff9341..7775ad1 100644 --- a/resources/admin/components/admin/table/operate.vue +++ b/resources/admin/components/admin/table/operate.vue @@ -1,21 +1,17 @@ - - diff --git a/resources/admin/composables/curd/useCreate.ts b/resources/admin/composables/curd/useCreate.ts index f473b83..5f04fb2 100644 --- a/resources/admin/composables/curd/useCreate.ts +++ b/resources/admin/composables/curd/useCreate.ts @@ -1,5 +1,5 @@ import http from '/admin/support/http' -import { ref, unref } from 'vue' +import { ref, unref, watch } from 'vue' import { Code } from '/admin/enum/app' import Message from '/admin/support/message' import { FormInstance } from 'element-plus' @@ -64,5 +64,13 @@ export function useCreate(path: string, id: string | number | null = null, _form .then(() => {}) } - return { formData, loading, form, submitForm, isClose, beforeCreate, beforeUpdate } + const close = (func: Function) => { + watch(isClose, function (value) { + if (value && isFunction(func)) { + func() + } + }) + } + + return { formData, loading, form, submitForm, close, beforeCreate, beforeUpdate } } diff --git a/resources/admin/composables/curd/useEnabled.ts b/resources/admin/composables/curd/useEnabled.ts index a3dfd47..b540fd6 100644 --- a/resources/admin/composables/curd/useEnabled.ts +++ b/resources/admin/composables/curd/useEnabled.ts @@ -1,19 +1,24 @@ import http from '/admin/support/http' import { Code } from '/admin/assets/enum/app' import Message from '/admin/support/message' -import { ref } from 'vue' +import { ref, watch } from 'vue' +import { isFunction } from '/admin/support/helper' export function useEnabled() { - const success = ref(false) + const isSuccess = ref(false) const loading = ref(false) + const afterEnabled = ref() function enabled(path: string, id: string | number, data: object = {}) { loading.value = true http .put(path + '/enable/' + id, data) .then(r => { if (r.data.code === Code.SUCCESS) { - success.value = true + isSuccess.value = true Message.success(r.data.message) + if (isFunction(afterEnabled.value)) { + afterEnabled.value() + } } else { Message.error(r.data.message) } @@ -23,5 +28,12 @@ export function useEnabled() { }) } - return { enabled, success, loading } + const success = (func: Function) => { + watch(isSuccess, function () { + isSuccess.value = false + func() + }) + } + + return { enabled, success, loading, afterEnabled } } diff --git a/resources/admin/composables/curd/useOpen.ts b/resources/admin/composables/curd/useOpen.ts new file mode 100644 index 0000000..224a557 --- /dev/null +++ b/resources/admin/composables/curd/useOpen.ts @@ -0,0 +1,21 @@ +import { ref } from 'vue' +import { t } from '/admin/support/helper' + +const visible = ref(false) +const id = ref(null) +const title = ref('') +export function useOpen() { + const open = (primary: any) => { + console.log(primary) + title.value = primary ? t('system.edit') : t('system.add') + id.value = primary + visible.value = true + } + + const close = (func: Function) => { + visible.value = false + func() + } + + return { open, close, title, visible, id } +} diff --git a/resources/admin/composables/curd/useShow.ts b/resources/admin/composables/curd/useShow.ts index 4797d25..be62db9 100644 --- a/resources/admin/composables/curd/useShow.ts +++ b/resources/admin/composables/curd/useShow.ts @@ -1,14 +1,26 @@ import http from '/admin/support/http' +import { Ref, ref } from 'vue' +import { isFunction } from '../../support/helper' -export function useShow(path: string, id: string | number) { - return new Promise((resolve, reject) => { - http - .get(path + '/' + id) - .then(response => { - resolve(response.data) - }) - .catch(e => { - reject(e) - }) +const loading = ref(true) + +const data = ref() + +// 后置钩子 +const afterShow = ref() + +export function useShow(path: string, id: string | number, fillData: null | Ref = null) { + http.get(path + '/' + id).then(r => { + loading.value = false + data.value = r.data.data + if (fillData) { + fillData.value = r.data.data + + if (isFunction(afterShow.value)) { + afterShow.value(fillData) + } + } }) + + return { data, loading, afterShow } } diff --git a/resources/admin/layout/components/header/index.vue b/resources/admin/layout/components/header/index.vue index 4167637..d71cd9b 100644 --- a/resources/admin/layout/components/header/index.vue +++ b/resources/admin/layout/components/header/index.vue @@ -28,7 +28,7 @@