feat: complete platform administration pages
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/audit/aud_approval');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/audit/aud_export_log');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/audit/aud_operation_log');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/commerce/ec_cart');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/commerce/ec_category');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/commerce/ec_order');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/commerce/ec_product');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/commerce/ec_product_attribute');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/commerce/ec_product_image');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/commerce/ec_review');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/content/cnt_content');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/customer_service/cs_ticket');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/delivery/delivery_account');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/delivery/delivery_basic');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/delivery/delivery_task');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/delivery/delivery_track');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/delivery/delivery_track_point');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/device/dev_device_binding');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/device/dev_smart_cylinder_valve');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/device/dev_telemetry');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/device/saf_event');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/device/saf_event_disposal');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/device/saf_inspection');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/device/saf_rule');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/finance/fin_payment');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/finance/fin_reconciliation');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/finance/fin_settlement');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/gas/gas_account');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/gas/gas_basic');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/notification/ntf_template');
|
||||
</script>
|
||||
@@ -1 +1,6 @@
|
||||
<template><a-card title="菜单管理" :bordered="false"><a-tree :data="tree" :field-names="{ key: 'identity', title: 'name', children: 'children' }" /></a-card></template><script setup lang="ts">import { Message } from '@arco-design/web-vue'; import { computed, onMounted, ref } from 'vue'; import { platformApi, type PlatformMenu } from '@/api/platform'; type Node = PlatformMenu & { children: Node[] }; const list = ref<PlatformMenu[]>([]); const tree = computed<any[]>(() => { const byId = new Map<number, Node>(); const roots: Node[] = []; list.value.forEach((item) => byId.set(item.id, { ...item, children: [] })); byId.forEach((item) => { if (item.parent_id && byId.has(item.parent_id)) byId.get(item.parent_id)?.children.push(item); else roots.push(item); }); return roots; }); onMounted(async () => { try { list.value = (await platformApi.listMenu()).list; } catch (error) { Message.error((error as Error).message); } });</script>
|
||||
<template><TreePage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import TreePage from '@/views/shared/TreePage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/platform/platform_menu');
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><TreePage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import TreePage from '@/views/shared/TreePage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/platform/platform_menu');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/platform/platform_role');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/platform/platfrom_account');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/report/report');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/report/report_item');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/report/report_metric_snapshot');
|
||||
</script>
|
||||
@@ -1,40 +1,49 @@
|
||||
<template>
|
||||
<a-card :title="title" :bordered="false">
|
||||
<template #extra><a-space><a-button @click="load">刷新</a-button><a-button type="primary" @click="openCreate">新建</a-button></a-space></template>
|
||||
<a-card :title="definition.title" :bordered="false">
|
||||
<template #extra>
|
||||
<a-space><a-button @click="load">刷新</a-button><a-button v-if="canCreate" type="primary" @click="openCreate">新建</a-button></a-space>
|
||||
</template>
|
||||
<a-form :model="filters" layout="inline" class="filters" @submit.prevent="load">
|
||||
<a-form-item label="关键字"><a-input v-model="filters.keyword" allow-clear placeholder="服务端筛选" /></a-form-item>
|
||||
<a-button type="primary" html-type="submit">查询</a-button>
|
||||
</a-form>
|
||||
<a-table :data="list" :loading="loading" :pagination="false" row-key="identity">
|
||||
<template #columns>
|
||||
<a-table-column title="业务标识" data-index="identity" :width="220" ellipsis tooltip />
|
||||
<a-table-column v-for="field in fields" :key="field.key" :title="field.label" :data-index="field.key" ellipsis tooltip />
|
||||
<a-table-column title="状态" data-index="status" :width="100"><template #cell="{ record }"><a-tag :color="record.status === 'enabled' ? 'green' : 'orange'">{{ record.status }}</a-tag></template></a-table-column>
|
||||
<a-table-column title="操作" :width="210" fixed="right"><template #cell="{ record }"><a-space><a-button size="mini" @click="openDetail(record)">详情</a-button><a-button size="mini" @click="openEdit(record)">编辑</a-button><a-button size="mini" @click="changeStatus(record)">{{ record.status === 'enabled' ? '停用' : '启用' }}</a-button></a-space></template></a-table-column>
|
||||
<a-table-column v-for="field in displayFields" :key="field.key" :title="field.label" :data-index="field.key" ellipsis tooltip />
|
||||
<a-table-column title="操作" :width="190" fixed="right"><template #cell="{ record }"><a-space><a-button size="mini" @click="openDetail(record)">详情</a-button><a-button v-if="canEdit" size="mini" @click="openEdit(record)">编辑</a-button><a-button v-if="canArchive" size="mini" status="danger" @click="confirmArchive(record)">归档</a-button></a-space></template></a-table-column>
|
||||
</template>
|
||||
</a-table>
|
||||
<div class="pagination"><a-pagination :total="total" :current="page" :page-size="pageSize" show-total @change="changePage" /></div>
|
||||
</a-card>
|
||||
<a-drawer :visible="formVisible" :title="editingIdentity ? `编辑${title}` : `新建${title}`" :width="480" @cancel="formVisible = false" @ok="save">
|
||||
<a-form :model="form" layout="vertical"><a-form-item v-for="field in fields" :key="field.key" :label="field.label" :required="field.required"><a-input v-model="form[field.key]" :placeholder="`请输入${field.label}`" /></a-form-item></a-form>
|
||||
<a-drawer :visible="formVisible" :title="editingIdentity ? `编辑${definition.title}` : `新建${definition.title}`" :width="480" @cancel="formVisible = false" @ok="save">
|
||||
<a-form :model="form" layout="vertical"><a-form-item v-for="field in definition.fields" :key="field.key" :label="field.label" :required="field.required"><a-input v-model="form[field.key]" :placeholder="`请输入${field.label}`" /></a-form-item></a-form>
|
||||
</a-drawer>
|
||||
<a-drawer :visible="detailVisible" title="详情" :width="540" @cancel="detailVisible = false"><a-descriptions :column="1" bordered><a-descriptions-item v-for="(value, key) in detail" :key="String(key)" :label="String(key)">{{ value ?? '-' }}</a-descriptions-item></a-descriptions></a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Message, Modal } from '@arco-design/web-vue';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { resourceApi } from '@/api/resource';
|
||||
import type { ResourceUiDefinition } from '@/api/resources';
|
||||
|
||||
type Field = { key: string; label: string; required?: boolean };
|
||||
type Row = Record<string, any>;
|
||||
const props = defineProps<{ title: string; resource: string; fields: Field[] }>();
|
||||
const loading = ref(false); const page = ref(1); const pageSize = 20; const total = ref(0); const list = ref<Row[]>([]);
|
||||
const formVisible = ref(false); const detailVisible = ref(false); const editingIdentity = ref(''); const form = reactive<Row>({}); const detail = ref<Row>({});
|
||||
function resetForm(data?: Row) { props.fields.forEach((field) => { form[field.key] = data?.[field.key] ?? ''; }); }
|
||||
async function load() { loading.value = true; try { const result = await resourceApi.list<Row>(props.resource, page.value, pageSize); list.value = result.list; total.value = result.total; } catch (error) { Message.error((error as Error).message); } finally { loading.value = false; } }
|
||||
type Row = Record<string, unknown>;
|
||||
const props = defineProps<{ definition: ResourceUiDefinition }>();
|
||||
const loading = ref(false); const page = ref(1); const pageSize = 20; const total = ref(0); const list = ref<Row[]>([]); const filters = reactive({ keyword: '' });
|
||||
const formVisible = ref(false); const detailVisible = ref(false); const editingIdentity = ref(''); const form = reactive<Record<string, string>>({}); const detail = ref<Row>({});
|
||||
const canCreate = computed(() => props.definition.mode !== 'readonly');
|
||||
const canEdit = computed(() => props.definition.mode === 'writable');
|
||||
const canArchive = computed(() => props.definition.mode === 'writable');
|
||||
const displayFields = computed(() => props.definition.fields.filter((field) => field.key !== 'status'));
|
||||
function resetForm(data?: Row) { props.definition.fields.forEach((field) => { form[field.key] = data?.[field.key] == null ? '' : String(data[field.key]); }); }
|
||||
async function load() { loading.value = true; try { const result = await resourceApi.list<Row>(props.definition.resource, page.value, pageSize, filters.keyword ? { keyword: filters.keyword } : {}); list.value = result.list; total.value = result.total; } catch (error) { Message.error((error as Error).message); } finally { loading.value = false; } }
|
||||
function openCreate() { editingIdentity.value = ''; resetForm(); formVisible.value = true; }
|
||||
function openEdit(row: Row) { editingIdentity.value = row.identity; resetForm(row); formVisible.value = true; }
|
||||
function openDetail(row: Row) { detail.value = row; detailVisible.value = true; }
|
||||
async function save() { if (props.fields.some((field) => field.required && !form[field.key])) { Message.warning('请填写必填字段'); return; } try { if (editingIdentity.value) await resourceApi.update(props.resource, editingIdentity.value, form); else await resourceApi.create(props.resource, form); Message.success('保存成功'); formVisible.value = false; await load(); } catch (error) { Message.error((error as Error).message); } }
|
||||
async function changeStatus(row: Row) { try { await resourceApi.updateStatus(props.resource, row.identity, row.status === 'enabled' ? 'disabled' : 'enabled'); await load(); } catch (error) { Message.error((error as Error).message); } }
|
||||
function openEdit(row: Row) { editingIdentity.value = String(row.identity ?? ''); resetForm(row); formVisible.value = true; }
|
||||
async function openDetail(row: Row) { try { detail.value = await resourceApi.detail<Row>(props.definition.resource, String(row.identity)); detailVisible.value = true; } catch (error) { Message.error((error as Error).message); } }
|
||||
async function save() { if (props.definition.fields.some((field) => field.required && !form[field.key])) { Message.warning('请填写必填字段'); return; } try { if (editingIdentity.value) await resourceApi.update(props.definition.resource, editingIdentity.value, form); else await resourceApi.create(props.definition.resource, form); Message.success('保存成功'); formVisible.value = false; await load(); } catch (error) { Message.error((error as Error).message); } }
|
||||
function confirmArchive(row: Row) { Modal.warning({ title: '确认归档', content: '归档后该记录将不再参与日常业务。', onOk: async () => { try { await resourceApi.archive(props.definition.resource, String(row.identity)); Message.success('已归档'); await load(); } catch (error) { Message.error((error as Error).message); } } }); }
|
||||
async function changePage(next: number) { page.value = next; await load(); }
|
||||
onMounted(load);
|
||||
</script>
|
||||
<style scoped lang="less">.pagination { display: flex; justify-content: flex-end; margin-top: 16px; }</style>
|
||||
<style scoped lang="less">.filters { margin-bottom: 16px; } .pagination { display: flex; justify-content: flex-end; margin-top: 16px; }</style>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from './CrudListPage.vue';
|
||||
import type { ResourceUiDefinition } from '@/api/resources';
|
||||
defineProps<{ definition: ResourceUiDefinition }>();
|
||||
</script>
|
||||
24
frontend/platform_admin/src/views/shared/TreePage.vue
Normal file
24
frontend/platform_admin/src/views/shared/TreePage.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<a-card :title="definition.title" :bordered="false">
|
||||
<template #extra><a-button @click="load">刷新</a-button></template>
|
||||
<a-tree :data="tree" :loading="loading" :field-names="{ key: 'identity', title: 'name', children: 'children' }" />
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { resourceApi } from '@/api/resource';
|
||||
import type { ResourceUiDefinition } from '@/api/resources';
|
||||
|
||||
type Node = Record<string, unknown> & { identity: string; parent_identity?: string; children: Node[] };
|
||||
const props = defineProps<{ definition: ResourceUiDefinition }>();
|
||||
const loading = ref(false); const list = ref<Node[]>([]);
|
||||
const tree = computed(() => {
|
||||
const nodes = new Map<string, Node>(); const roots: Node[] = [];
|
||||
list.value.forEach((item) => nodes.set(item.identity, { ...item, children: [] }));
|
||||
nodes.forEach((item) => { const parent = item.parent_identity && nodes.get(item.parent_identity); if (parent) parent.children.push(item); else roots.push(item); });
|
||||
return roots;
|
||||
});
|
||||
async function load() { loading.value = true; try { list.value = (await resourceApi.list<Node>(props.definition.resource, 1, 500)).list; } catch (error) { Message.error((error as Error).message); } finally { loading.value = false; } }
|
||||
onMounted(load);
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/staff/staff_account');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/staff/staff_credential');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/user/user_account');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/user/user_address');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><CrudListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import CrudListPage from '@/views/shared/CrudListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/user/user_service_relation');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/wallet/wallet');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/wallet/wallet_ledger');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/wallet/wallet_recharge');
|
||||
</script>
|
||||
@@ -0,0 +1,6 @@
|
||||
<template><ReadOnlyListPage :definition="definition" /></template>
|
||||
<script setup lang="ts">
|
||||
import ReadOnlyListPage from '@/views/shared/ReadOnlyListPage.vue';
|
||||
import { getResource } from '@/api/resources';
|
||||
const definition = getResource('/wallet/wallet_withdrawal');
|
||||
</script>
|
||||
Reference in New Issue
Block a user