feat: permissions

This commit is contained in:
JaguarJack
2022-12-07 19:28:57 +08:00
parent a1d9468a91
commit 8c537e6656
45 changed files with 1030 additions and 372 deletions

View File

@@ -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
*

View File

@@ -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})");
}

View File

@@ -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();
}

View File

@@ -10,29 +10,21 @@
<script lang="ts" setup>
import { useCreate } from '/admin/composables/curd/useCreate'
import { useShow } from '/admin/composables/curd/useShow'
import { onMounted, watch } from 'vue'
import { onMounted } from 'vue'
const props = defineProps({
primary: String | Number,
api: String,
})
const { formData, form, loading, submitForm, close } = useCreate(props.api, props.primary)
if (props.primary) {
useShow(props.api, props.primary, formData)
}
const emit = defineEmits(['close'])
const { formData, form, loading, submitForm, isClose } = useCreate(props.api, props.primary)
watch(isClose, function (value) {
if (value) {
emit('close')
}
})
onMounted(() => {
if (props.primary) {
useShow(props.api, props.primary).then(r => {
formData.value = r.data
})
}
close(() => emit('close'))
})
</script>

View File

@@ -1,5 +1,5 @@
<el-form-item label="{label}" prop="{prop}">
<el-select v-model="{model-value}" placeholder="请选择" clearable ${multiple}>
<el-select v-model="{model-value}" placeholder="请选择" clearable multiple>
<el-option
v-for="item in options"
:key="item.value"

View File

@@ -5,13 +5,13 @@
{search}
</template>
</Search>
<div class="pl-2 pr-2 bg-white dark:bg-regal-dark rounded-lg mt-4">
<Operate :show="show" />
<el-table :data="tableData" class="mt-3" v-loading="loading">
<div class="pl-2 pr-2 bg-white dark:bg-regal-dark rounded-lg mt-4 pb-10">
<Operate :show="open" />
<el-table :data="tableData" class="mt-3" v-loading="loading"{tree}>
{table}
<el-table-column label="操作" width="200">
<template #default="scope">
<Update @click="show(scope.row.id)" />
<Update @click="open(scope.row.id)" />
<Destroy @click="destroy(api, scope.row.id)" />
</template>
</el-table-column>
@@ -20,43 +20,28 @@
</div>
<Dialog v-model="visible" :title="title" destroy-on-close>
<Create @close="close" :primary="id" :api="api" />
<Create @close="close(reset)" :primary="id" :api="api" />
</Dialog>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue'
import { computed, onMounted } from 'vue'
import Create from './create.vue'
import { useGetList } from '/admin/composables/curd/useGetList'
import { useDestroy } from '/admin/composables/curd/useDestroy'
import { t } from '/admin/support/helper'
import { useOpen } from '/admin/composables/curd/useOpen'
const visible = ref<boolean>(false)
const id = ref(null)
const api = '{api}'
const title = ref<string>('')
// const { data, query, search, reset, loading } = useGetList(api)
{useList}
const { destroy, deleted } = useDestroy()
const { open, close, title, visible, id } = useOpen()
const tableData = computed(() => data.value?.data)
const close = () => {
visible.value = false
reset()
}
const show = primary => {
title.value = primary ? t('system.edit') : t('system.add')
id.value = primary
visible.value = true
}
onMounted(() => {
search()
deleted(reset)
})
</script>

View File

@@ -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)
}
</script>

View File

@@ -1,26 +1,14 @@
<template>
<div>
<div class="w-full min-h-0 bg-white dark:bg-regal-dark pl-5 pt-5 pr-5 rounded-lg">
<el-form :inline="true">
<Search :search="search" :reset="reset">
<template v-slot:body>
<el-form-item label="模块名称">
<el-input v-model="query.name" name="name" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search()">
<Icon name="magnifying-glass" class="w-4 mr-1 -ml-1" />
搜索
</el-button>
<el-button @click="reset()">
<Icon name="arrow-path" class="w-4 mr-1 -ml-1" />
重置
</el-button>
</el-form-item>
</el-form>
</div>
<div class="pl-2 pr-2 bg-white dark:bg-regal-dark rounded-lg mt-4">
<div class="pt-5 pl-2">
<Add @click="show(null)" />
</div>
</template>
</Search>
<div class="pl-2 pr-2 bg-white dark:bg-regal-dark rounded-lg mt-4 pb-6">
<Operate :show="open" />
<el-table :data="tableData" class="mt-3" v-loading="loading">
<el-table-column prop="name" label="模块名称" width="180" />
<el-table-column prop="path" label="模块目录" width="180" />
@@ -31,31 +19,17 @@
</el-table-column>
<el-table-column prop="enable" label="模块状态">
<template #default="scope">
<el-switch v-model="scope.row.enable" @change="enabled(api, scope.row.name)" />
<Status v-model="scope.row.status" :id="scope.row.id" :api="api" />
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template #default="scope">
<Update @click="show(scope.row.name)" />
<Update @click="open(scope.row.name)" />
<Destroy @click="destroy(api, scope.row.name)" />
</template>
</el-table-column>
</el-table>
<div class="pt-2 pb-2 flex justify-end">
<el-pagination
background
layout="total,sizes,prev, pager,next"
:current-page="query.page"
:page-size="query.limit"
@current-change="changePage"
@size-change="changeLimit"
:total="total"
:page-sizes="[10, 20, 30, 50]"
/>
</div>
</div>
<Dialog v-model="visible" :title="title" destroy-on-close>
<Create @close="close" :primary="id" :api="api" />
</Dialog>
@@ -63,41 +37,23 @@
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue'
import { computed, onMounted } from 'vue'
import Create from './create.vue'
import { useGetList } from '/admin/composables/curd/useGetList'
import { useDestroy } from '/admin/composables/curd/useDestroy'
import { useEnabled } from '/admin/composables/curd/useEnabled'
import { t } from '/admin/support/helper'
import Sortable from 'sortablejs'
import { useOpen } from '/admin/composables/curd/useOpen'
const visible = ref<boolean>(false)
const id = ref(null)
const api = 'module'
const title = ref<string>('')
const { data, query, search, reset, changePage, changeLimit, loading } = useGetList(api)
const { destroy, isDeleted } = useDestroy('确认删除吗? ⚠️将会删除模块下所有文件')
const { enabled } = useEnabled()
onMounted(() => search())
const { data, query, search, reset, loading } = useGetList(api)
const { destroy, deleted } = useDestroy('确认删除吗? ⚠️将会删除模块下所有文件')
const { open, close, title, visible, id } = useOpen()
const tableData = computed(() => data.value?.data)
const total = computed(() => data.value?.total)
const close = () => {
visible.value = false
reset()
}
onMounted(() => {
search()
const show = primary => {
title.value = primary ? t('system.edit') : t('system.add')
id.value = primary
visible.value = true
}
watch(isDeleted, function () {
isDeleted.value = false
reset()
deleted()
})
</script>

View File

@@ -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')
}
},
)
</script>

View File

@@ -1,35 +1,23 @@
<template>
<div>
<div class="w-full min-h-0 bg-white dark:bg-regal-dark pl-5 pt-5 pr-5 rounded-lg">
<el-form :inline="true">
<Search :search="search" :reset="reset">
<template v-slot:body>
<el-form-item label="模块名称">
<el-input v-model="query.module" name="module" clearable />
</el-form-item>
<el-form-item label="Schema 名称">
<el-input v-model="query.name" name="name" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search()">
<Icon name="magnifying-glass" class="w-4 mr-1 -ml-1" />
搜索
</el-button>
<el-button @click="reset()">
<Icon name="arrow-path" class="w-4 mr-1 -ml-1" />
重置
</el-button>
</el-form-item>
</el-form>
</div>
<div class="pl-2 pr-2 bg-white dark:bg-regal-dark rounded-lg mt-4">
<div class="pt-5 pl-2">
<Add @click="add(null)" />
</div>
</template>
</Search>
<div class="pl-2 pr-2 bg-white dark:bg-regal-dark rounded-lg mt-4 pb-6">
<Operate :show="open" />
<el-table :data="tableData" class="mt-3" v-loading="loading">
<el-table-column prop="module" label="所属模块" />
<el-table-column prop="name" label="schema 名称" />
<el-table-column prop="columns" label="字段">
<template #default="scope">
<el-button size="small" type="success" @click="show(scope.row.id)"><Icon name="eye" class="w-3 mr-1" /> 查看</el-button>
<el-button size="small" type="success" @click="view(scope.row.id)"><Icon name="eye" class="w-3 mr-1" /> 查看</el-button>
</template>
</el-table-column>
<el-table-column prop="is_soft_delete" label="?软删">
@@ -48,73 +36,48 @@
</template>
</el-table-column>
</el-table>
<div class="pt-2 pb-2 flex justify-end">
<el-pagination
background
layout="total,sizes,prev, pager,next"
:current-page="query.page"
:page-size="query.limit"
@current-change="changePage"
@size-change="changeLimit"
:total="total"
:page-sizes="[10, 20, 30, 50]"
/>
</div>
<Paginate />
</div>
<!-- schema 创建 -->
<Dialog v-model="visible" :title="$t('generate.schema.title')" width="650px" destroy-on-close>
<Create @close="close" :primary="id" :api="api" />
<Dialog v-model="visible" :title="title" width="650px" destroy-on-close>
<Create @close="close(reset)" :api="api" />
</Dialog>
<!-- schema 表结构 -->
<Dialog v-model="showVisible" title="Schema 结构" width="650px" destroy-on-close>
<Dialog v-model="schemaVisible" title="Schema 结构" width="650px" destroy-on-close>
<Show :id="id" :api="api" />
</Dialog>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue'
import { computed, onMounted, ref } from 'vue'
import Create from './create.vue'
import Show from './show.vue'
import { useGetList } from '/admin/composables/curd/useGetList'
import { useDestroy } from '/admin/composables/curd/useDestroy'
import { useOpen } from '/admin/composables/curd/useOpen'
const visible = ref<boolean>(false)
const showVisible = ref<boolean>(false)
const schemaVisible = ref<boolean>(false)
const id = ref<number>()
const api = 'schema'
const title = ref<string>('')
const { data, query, search, reset, changePage, changeLimit, loading } = useGetList(api)
const { destroy, isDeleted } = useDestroy('确认删除吗? 将会删除数据库的 Schema请提前做好备份一旦删除将无法恢复!')
onMounted(() => search())
const { data, query, search, reset, loading } = useGetList(api)
const { destroy, deleted } = useDestroy('确认删除吗? 将会删除数据库的 Schema请提前做好备份一旦删除将无法恢复!')
const { open, close, title, visible, id } = useOpen()
const tableData = computed(() => data.value?.data)
const total = computed(() => data.value?.total)
const close = () => {
visible.value = false
reset()
}
const add = () => {
visible.value = true
}
const show = primaryId => {
showVisible.value = true
const view = primaryId => {
schemaVisible.value = true
id.value = primaryId
}
watch(isDeleted, function () {
isDeleted.value = false
reset()
onMounted(() => {
search()
deleted(reset)
})
</script>

View File

@@ -1,5 +1,5 @@
<template>
<el-table :data="data" class="mt-3" v-loading="loading">
<el-table :data="data?.columns" class="mt-3" v-loading="loading">
<el-table-column prop="name" label="字段名称" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="nullable" label="nullable">
@@ -17,8 +17,6 @@
<script lang="ts" setup>
import { useShow } from '/admin/composables/curd/useShow'
import { onMounted } from 'vue'
import { ref } from 'vue'
const props = defineProps({
id: {
type: Number,
@@ -26,13 +24,8 @@ const props = defineProps({
},
})
const data = ref<Array<object>>()
onMounted(() => {
useShow('schema', props.id).then(r => {
data.value = r.data.columns
})
})
// const data = ref<Array<object>>()
const { data, loading } = useShow('schema', props.id)
</script>
<style scoped></style>

View File

@@ -75,7 +75,7 @@ schemaStore.start()
const emits = defineEmits(['prev', 'next'])
const schema = reactive(schemaStore.getSchema)
const schema = ref(schemaStore.getSchema)
const form = ref<FormInstance>()
const submitCreateTable = (formEl: FormInstance | undefined) => {
if (!formEl) return