20260721173401
This commit is contained in:
1 parent
fd161dd302
commit
bab8e2972f
32 files changed
+1207
-3171
No files matched your search
+19
-223
@@ -1,190 +1,30 @@
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { Languages, Plus, Trash2 } from "@lucide/vue";
|
||||
import { LOCALES } from "../../../services/moduleManagement";
|
||||
import AutoHeightTable from "../../../components/AutoHeightTable.vue";
|
||||
import FmsTable from "@/components/FmsTable.vue";
|
||||
|
||||
defineProps({
|
||||
canSave: Boolean,
|
||||
});
|
||||
const emit = defineEmits(["add"]);
|
||||
const fields = defineModel("fields", { type: Array, default: () => [] });
|
||||
const translations = defineModel("translations", { type: Object, default: () => ({}) });
|
||||
|
||||
const editingFieldId = ref("");
|
||||
const selectedFieldKeys = ref([]);
|
||||
const columns = [
|
||||
{ title: "字段", key: "b_field", width: 150 },
|
||||
{ title: "名称", key: "b_name", width: 150 },
|
||||
{ title: "类型", key: "b_type", width: 120 },
|
||||
{ title: "列表", key: "b_canlist", width: 64, align: "center" },
|
||||
{ title: "表单", key: "b_canform", width: 64, align: "center" },
|
||||
{ title: "必填", key: "b_must", width: 64, align: "center" },
|
||||
{ title: "查询", key: "b_canquery", width: 64, align: "center" },
|
||||
{ title: "只读", key: "b_readonly", width: 64, align: "center" },
|
||||
{ title: "宽度", key: "b_width", width: 90 },
|
||||
{ title: "顺序", key: "b_xh", width: 80 },
|
||||
{ title: "操作", key: "operation", width: 58, fixed: "right" },
|
||||
{ dataIndex: "b_field", title: "字段", width: 150 },
|
||||
{ dataIndex: "b_name", title: "名称", width: 160 },
|
||||
{ dataIndex: "b_type", title: "类型", width: 120 },
|
||||
{ dataIndex: "b_canlist", title: "列表", width: 64, align: "center", headerAlign: "center" },
|
||||
{ dataIndex: "b_canform", title: "表单", width: 64, align: "center", headerAlign: "center" },
|
||||
{ dataIndex: "b_must", title: "必填", width: 64, align: "center", headerAlign: "center" },
|
||||
{ dataIndex: "b_canquery", title: "查询", width: 64, align: "center", headerAlign: "center" },
|
||||
{ dataIndex: "b_readonly", title: "只读", width: 64, align: "center", headerAlign: "center" },
|
||||
{ dataIndex: "b_width", title: "宽度", width: 90 },
|
||||
{ dataIndex: "b_xh", title: "顺序", width: 80 },
|
||||
];
|
||||
const fieldTypes = [
|
||||
["string", "单行文本"],
|
||||
["text", "多行文本"],
|
||||
["number", "数字"],
|
||||
["select", "选择"],
|
||||
["date", "日期"],
|
||||
["boolean", "布尔"],
|
||||
].map(([value, label]) => ({ value, label }));
|
||||
const rowSelection = computed(() => ({
|
||||
selectedRowKeys: selectedFieldKeys.value,
|
||||
onChange: (keys) => {
|
||||
selectedFieldKeys.value = keys;
|
||||
},
|
||||
columnWidth: 40,
|
||||
}));
|
||||
|
||||
function translationEntry(key) {
|
||||
translations.value[key] ||= {};
|
||||
return translations.value[key];
|
||||
}
|
||||
|
||||
function setFieldTranslation(record, locale, value) {
|
||||
translationEntry(record.b_i18n)[locale] = value;
|
||||
if (locale === "zh-CN") record.b_name = value;
|
||||
}
|
||||
|
||||
function fieldTranslationValue(record, locale) {
|
||||
return translationEntry(record.b_i18n)[locale] ?? (locale === "zh-CN" ? record.b_name : "");
|
||||
}
|
||||
|
||||
function fieldTypeLabel(value) {
|
||||
return fieldTypes.find((item) => item.value === value)?.label || value;
|
||||
}
|
||||
|
||||
function setBoolean(record, field, checked) {
|
||||
record[field] = checked ? 1 : 0;
|
||||
if (field === "b_canform" && !checked) record.b_must = 0;
|
||||
}
|
||||
|
||||
function fieldRow(record) {
|
||||
return {
|
||||
onClick: () => {
|
||||
editingFieldId.value = String(record.b_id);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function leaveEdit(event) {
|
||||
if (!event.target.closest(".ant-table-row")) editingFieldId.value = "";
|
||||
}
|
||||
|
||||
function removeField(record) {
|
||||
fields.value = fields.value.filter((item) => String(item.b_id) !== String(record.b_id));
|
||||
selectedFieldKeys.value = selectedFieldKeys.value.filter(
|
||||
(key) => String(key) !== String(record.b_id),
|
||||
);
|
||||
}
|
||||
|
||||
function deleteSelectedFields() {
|
||||
const ids = new Set(selectedFieldKeys.value.map(String));
|
||||
fields.value = fields.value.filter((item) => !ids.has(String(item.b_id)));
|
||||
selectedFieldKeys.value = [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="table-pane" @click="leaveEdit">
|
||||
<div class="table-toolbar">
|
||||
<a-button type="primary" ghost :disabled="!canSave" @click="emit('add')">
|
||||
<Plus :size="15" />新增字段
|
||||
</a-button>
|
||||
<a-popconfirm title="确定删除选中的字段吗?" @confirm="deleteSelectedFields">
|
||||
<a-button danger :disabled="!canSave || !selectedFieldKeys.length">
|
||||
<Trash2 :size="15" />批量删除 ({{ selectedFieldKeys.length }})
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
|
||||
<AutoHeightTable
|
||||
<section class="table-pane">
|
||||
<FmsTable
|
||||
class="sub-table"
|
||||
row-key="b_id"
|
||||
:columns="columns"
|
||||
:data-source="fields"
|
||||
:pagination="false"
|
||||
:row-class-name="(record) => (String(record.b_id) === editingFieldId ? 'editing-row' : '')"
|
||||
:row-selection="rowSelection"
|
||||
row-key="b_id"
|
||||
@row="fieldRow"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<a-tooltip v-if="column.key === 'operation'" title="删除字段">
|
||||
<a-button type="text" danger @click.stop="removeField(record)">
|
||||
<Trash2 :size="15" />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<template v-else-if="String(record.b_id) === editingFieldId">
|
||||
<a-input v-if="column.key === 'b_field'" v-model:value="record.b_field" />
|
||||
<div v-else-if="column.key === 'b_name'" class="field-name-editor">
|
||||
<a-input
|
||||
:value="record.b_name"
|
||||
@update:value="setFieldTranslation(record, 'zh-CN', $event)"
|
||||
/>
|
||||
<a-popover trigger="click" placement="bottomRight">
|
||||
<template #content>
|
||||
<a-space direction="vertical" size="small" style="width: 260px">
|
||||
<div v-for="locale in LOCALES" :key="locale.value">
|
||||
<div class="locale-label">{{ locale.label }}</div>
|
||||
<a-input
|
||||
:value="fieldTranslationValue(record, locale.value)"
|
||||
@update:value="setFieldTranslation(record, locale.value, $event)"
|
||||
/>
|
||||
</div>
|
||||
</a-space>
|
||||
</template>
|
||||
<a-button type="text" class="i18n-button" @click.stop>
|
||||
<Languages :size="15" />
|
||||
</a-button>
|
||||
</a-popover>
|
||||
</div>
|
||||
<a-select
|
||||
v-else-if="column.key === 'b_type'"
|
||||
v-model:value="record.b_type"
|
||||
:options="fieldTypes"
|
||||
/>
|
||||
<a-switch
|
||||
v-else-if="
|
||||
['b_canlist', 'b_canform', 'b_must', 'b_canquery', 'b_readonly'].includes(column.key)
|
||||
"
|
||||
size="small"
|
||||
:checked="record[column.key] === 1"
|
||||
:disabled="column.key === 'b_must' && record.b_canform === 0"
|
||||
@change="setBoolean(record, column.key, $event)"
|
||||
/>
|
||||
<a-input-number
|
||||
v-else-if="column.key === 'b_width'"
|
||||
v-model:value="record.b_width"
|
||||
:min="40"
|
||||
/>
|
||||
<a-input-number v-else-if="column.key === 'b_xh'" v-model:value="record.b_xh" :min="0" />
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<span v-if="column.key === 'b_field'" class="cell-code">{{ record.b_field }}</span>
|
||||
<span v-else-if="column.key === 'b_name'" class="cell-name">
|
||||
{{ record.b_name }}<Languages v-if="record.b_i18n" :size="13" />
|
||||
</span>
|
||||
<span v-else-if="column.key === 'b_type'">{{ fieldTypeLabel(record.b_type) }}</span>
|
||||
<a-switch
|
||||
v-else-if="
|
||||
['b_canlist', 'b_canform', 'b_must', 'b_canquery', 'b_readonly'].includes(column.key)
|
||||
"
|
||||
size="small"
|
||||
:checked="record[column.key] === 1"
|
||||
disabled
|
||||
/>
|
||||
<span v-else-if="column.key === 'b_width'">{{ record.b_width || "-" }}</span>
|
||||
<span v-else-if="column.key === 'b_xh'">{{ record.b_xh }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</AutoHeightTable>
|
||||
/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -197,52 +37,8 @@ function deleteSelectedFields() {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-toolbar {
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.field-name-editor,
|
||||
.cell-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.field-name-editor .ant-input {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.i18n-button {
|
||||
flex: 0 0 auto;
|
||||
padding-inline: 5px;
|
||||
}
|
||||
|
||||
.cell-name svg {
|
||||
flex: 0 0 auto;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
.cell-code {
|
||||
color: #475569;
|
||||
font-family: Consolas, monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
:deep(.editing-row > td) {
|
||||
background: #f0f7ff !important;
|
||||
}
|
||||
|
||||
:deep(.ant-table-row) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:deep(.ant-table-cell .ant-input-number),
|
||||
:deep(.ant-table-cell .ant-select) {
|
||||
width: 100%;
|
||||
.sub-table {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,120 +1,25 @@
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { Plus, Trash2 } from "@lucide/vue";
|
||||
import AutoHeightTable from "../../../components/AutoHeightTable.vue";
|
||||
import FmsTable from "@/components/FmsTable.vue";
|
||||
|
||||
defineProps({
|
||||
canSave: Boolean,
|
||||
});
|
||||
const emit = defineEmits(["add"]);
|
||||
const powers = defineModel("powers", { type: Array, default: () => [] });
|
||||
|
||||
const editingPowerId = ref("");
|
||||
const selectedPowerKeys = ref([]);
|
||||
const columns = [
|
||||
{ title: "权限代码", key: "b_code", width: 180 },
|
||||
{ title: "名称", key: "b_name", width: 200 },
|
||||
{ title: "多语言键", key: "b_i18n" },
|
||||
{ title: "启用", key: "b_canuse", width: 74, align: "center" },
|
||||
{ title: "顺序", key: "b_xh", width: 90 },
|
||||
{ title: "操作", key: "operation", width: 58 },
|
||||
{ dataIndex: "b_code", title: "权限代码", width: 180 },
|
||||
{ dataIndex: "b_name", title: "名称", width: 200 },
|
||||
{ dataIndex: "b_i18n", title: "多语言键", width: 200 },
|
||||
{ dataIndex: "b_canuse", title: "启用", width: 74, align: "center", headerAlign: "center" },
|
||||
{ dataIndex: "b_xh", title: "顺序", width: 90 },
|
||||
];
|
||||
const rowSelection = computed(() => ({
|
||||
selectedRowKeys: selectedPowerKeys.value,
|
||||
onChange: (keys) => {
|
||||
selectedPowerKeys.value = keys;
|
||||
},
|
||||
columnWidth: 40,
|
||||
}));
|
||||
|
||||
function setBoolean(record, field, checked) {
|
||||
record[field] = checked ? 1 : 0;
|
||||
}
|
||||
|
||||
function powerRow(record) {
|
||||
return {
|
||||
onClick: () => {
|
||||
editingPowerId.value = String(record.b_id);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function leaveEdit(event) {
|
||||
if (!event.target.closest(".ant-table-row")) editingPowerId.value = "";
|
||||
}
|
||||
|
||||
function removePower(record) {
|
||||
powers.value = powers.value.filter((item) => String(item.b_id) !== String(record.b_id));
|
||||
selectedPowerKeys.value = selectedPowerKeys.value.filter(
|
||||
(key) => String(key) !== String(record.b_id),
|
||||
);
|
||||
}
|
||||
|
||||
function deleteSelectedPowers() {
|
||||
const ids = new Set(selectedPowerKeys.value.map(String));
|
||||
powers.value = powers.value.filter((item) => !ids.has(String(item.b_id)));
|
||||
selectedPowerKeys.value = [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="table-pane" @click="leaveEdit">
|
||||
<div class="table-toolbar">
|
||||
<a-button type="primary" ghost :disabled="!canSave" @click="emit('add')">
|
||||
<Plus :size="15" />新增权限
|
||||
</a-button>
|
||||
<a-popconfirm title="确定删除选中的权限吗?" @confirm="deleteSelectedPowers">
|
||||
<a-button danger :disabled="!canSave || !selectedPowerKeys.length">
|
||||
<Trash2 :size="15" />批量删除 ({{ selectedPowerKeys.length }})
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
|
||||
<AutoHeightTable
|
||||
<section class="table-pane">
|
||||
<FmsTable
|
||||
class="sub-table"
|
||||
row-key="b_id"
|
||||
:columns="columns"
|
||||
:data-source="powers"
|
||||
:pagination="false"
|
||||
:row-class-name="(record) => (String(record.b_id) === editingPowerId ? 'editing-row' : '')"
|
||||
:row-selection="rowSelection"
|
||||
row-key="b_id"
|
||||
@row="powerRow"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<a-tooltip v-if="column.key === 'operation'" title="删除权限">
|
||||
<a-button type="text" danger @click.stop="removePower(record)">
|
||||
<Trash2 :size="15" />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<template v-else-if="String(record.b_id) === editingPowerId">
|
||||
<a-input v-if="column.key === 'b_code'" v-model:value="record.b_code" />
|
||||
<a-input v-else-if="column.key === 'b_name'" v-model:value="record.b_name" />
|
||||
<a-input v-else-if="column.key === 'b_i18n'" v-model:value="record.b_i18n" />
|
||||
<a-switch
|
||||
v-else-if="column.key === 'b_canuse'"
|
||||
size="small"
|
||||
:checked="record.b_canuse === 1"
|
||||
@change="setBoolean(record, 'b_canuse', $event)"
|
||||
/>
|
||||
<a-input-number v-else-if="column.key === 'b_xh'" v-model:value="record.b_xh" :min="0" />
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<span v-if="column.key === 'b_code'" class="cell-code">{{ record.b_code }}</span>
|
||||
<span v-else-if="column.key === 'b_name'">{{ record.b_name }}</span>
|
||||
<span v-else-if="column.key === 'b_i18n'" class="cell-code">
|
||||
{{ record.b_i18n || "-" }}
|
||||
</span>
|
||||
<a-switch
|
||||
v-else-if="column.key === 'b_canuse'"
|
||||
size="small"
|
||||
:checked="record.b_canuse === 1"
|
||||
disabled
|
||||
/>
|
||||
<span v-else-if="column.key === 'b_xh'">{{ record.b_xh }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</AutoHeightTable>
|
||||
/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -127,30 +32,8 @@ function deleteSelectedPowers() {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-toolbar {
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.cell-code {
|
||||
color: #475569;
|
||||
font-family: Consolas, monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
:deep(.editing-row > td) {
|
||||
background: #f0f7ff !important;
|
||||
}
|
||||
|
||||
:deep(.ant-table-row) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:deep(.ant-table-cell .ant-input-number) {
|
||||
width: 100%;
|
||||
.sub-table {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
+29
-112
@@ -1,112 +1,43 @@
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { Plus, Trash2 } from "@lucide/vue";
|
||||
import { App } from "antdv-next";
|
||||
import { LOCALES } from "../../../services/moduleManagement";
|
||||
import AutoHeightTable from "../../../components/AutoHeightTable.vue";
|
||||
import { computed } from "vue";
|
||||
import FmsTable from "@/components/FmsTable.vue";
|
||||
|
||||
const LOCALES = [
|
||||
{ value: "zh-CN", label: "简体中文" },
|
||||
{ value: "en-US", label: "English" },
|
||||
{ value: "zh-TW", label: "繁體中文" },
|
||||
];
|
||||
|
||||
const props = defineProps({
|
||||
canSave: Boolean,
|
||||
keys: { type: Array, default: () => [] },
|
||||
});
|
||||
const customKeys = defineModel("customKeys", { type: Array, default: () => [] });
|
||||
const translations = defineModel("translations", { type: Object, default: () => ({}) });
|
||||
const { message } = App.useApp();
|
||||
|
||||
const newI18nKey = ref("");
|
||||
const showI18nInput = ref(false);
|
||||
const columns = [
|
||||
{ title: "多语言键", key: "key", width: 280, fixed: "left" },
|
||||
...LOCALES.map((locale) => ({
|
||||
title: locale.label,
|
||||
key: locale.value,
|
||||
width: 220,
|
||||
})),
|
||||
{ title: "操作", key: "operation", width: 58, fixed: "right" },
|
||||
];
|
||||
const rows = computed(() =>
|
||||
props.keys.map((key) => ({
|
||||
key,
|
||||
isCustom: customKeys.value.includes(key),
|
||||
})),
|
||||
props.keys.map((key) => {
|
||||
const entry = translations.value[key] || {};
|
||||
const row = { key };
|
||||
LOCALES.forEach((locale) => {
|
||||
row[locale.value] = entry[locale.value];
|
||||
});
|
||||
return row;
|
||||
}),
|
||||
);
|
||||
|
||||
function translationEntry(key) {
|
||||
translations.value[key] ||= {};
|
||||
return translations.value[key];
|
||||
}
|
||||
|
||||
function setTranslation(key, locale, value) {
|
||||
translationEntry(key)[locale] = value;
|
||||
}
|
||||
|
||||
function addCustomKey() {
|
||||
const key = newI18nKey.value.trim();
|
||||
if (!key) return;
|
||||
if (props.keys.includes(key)) {
|
||||
message.warning("多语言键已存在");
|
||||
return;
|
||||
}
|
||||
|
||||
customKeys.value = [...customKeys.value, key];
|
||||
translationEntry(key);
|
||||
newI18nKey.value = "";
|
||||
showI18nInput.value = false;
|
||||
}
|
||||
|
||||
function removeCustomKey(key) {
|
||||
customKeys.value = customKeys.value.filter((item) => item !== key);
|
||||
delete translations.value[key];
|
||||
}
|
||||
const columns = [
|
||||
{ dataIndex: "key", title: "多语言键", width: 280, fixed: "left" },
|
||||
...LOCALES.map((locale) => ({ dataIndex: locale.value, title: locale.label, width: 220 })),
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="translation-pane">
|
||||
<div class="table-toolbar">
|
||||
<template v-if="showI18nInput">
|
||||
<a-input
|
||||
v-model:value="newI18nKey"
|
||||
placeholder="输入多语言键名,回车确认"
|
||||
size="small"
|
||||
class="new-key-input"
|
||||
@press-enter="addCustomKey"
|
||||
/>
|
||||
<a-button
|
||||
type="primary"
|
||||
ghost
|
||||
size="small"
|
||||
:disabled="!newI18nKey.trim()"
|
||||
@click="addCustomKey"
|
||||
>
|
||||
<Plus :size="15" />添加
|
||||
</a-button>
|
||||
<a-button size="small" @click="showI18nInput = false">取消</a-button>
|
||||
</template>
|
||||
<a-button v-else type="primary" ghost :disabled="!canSave" @click="showI18nInput = true">
|
||||
<Plus :size="15" />新增多语言键
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<AutoHeightTable :columns="columns" :data-source="rows" :pagination="false" row-key="key">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<code v-if="column.key === 'key'" class="translation-key">{{ record.key }}</code>
|
||||
<a-input
|
||||
v-else-if="LOCALES.some((locale) => locale.value === column.key)"
|
||||
:value="translationEntry(record.key)[column.key]"
|
||||
size="small"
|
||||
:placeholder="column.key === 'zh-CN' ? '必填' : '可选'"
|
||||
@update:value="setTranslation(record.key, column.key, $event)"
|
||||
/>
|
||||
<a-tooltip v-else-if="column.key === 'operation' && record.isCustom" title="删除多语言键">
|
||||
<a-button type="text" danger @click="removeCustomKey(record.key)">
|
||||
<Trash2 :size="15" />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #emptyText>
|
||||
<a-empty description="当前模块没有多语言键" />
|
||||
</template>
|
||||
</AutoHeightTable>
|
||||
<FmsTable
|
||||
class="sub-table"
|
||||
row-key="key"
|
||||
:columns="columns"
|
||||
:data-source="rows"
|
||||
/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -119,22 +50,8 @@ function removeCustomKey(key) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-toolbar {
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.new-key-input {
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
.translation-key {
|
||||
color: #374151;
|
||||
font-family: Consolas, monospace;
|
||||
font-size: 12px;
|
||||
.sub-table {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { RefreshCw, Search } from "@lucide/vue";
|
||||
import FmsTree from "@/components/FmsTree.vue";
|
||||
|
||||
const props = defineProps({
|
||||
modules: { type: Array, required: true },
|
||||
@@ -35,11 +36,15 @@ const treeData = computed(() => {
|
||||
const build = (parent) =>
|
||||
(children.get(parent) || [])
|
||||
.filter((item) => !visible || visible.has(item.b_id))
|
||||
.map((item) => ({
|
||||
key: item.b_id,
|
||||
title: item.b_name,
|
||||
children: build(item.b_id),
|
||||
}));
|
||||
.map((item) => {
|
||||
const nodeChildren = build(item.b_id);
|
||||
return {
|
||||
key: item.b_id,
|
||||
title: item.b_name,
|
||||
children: nodeChildren,
|
||||
isLeaf: nodeChildren.length === 0,
|
||||
};
|
||||
});
|
||||
|
||||
return build("__root__");
|
||||
});
|
||||
@@ -94,16 +99,15 @@ const contextMenu = computed(() => {
|
||||
</a-tooltip>
|
||||
</header>
|
||||
|
||||
<a-input v-model:value="searchText" allow-clear size="small" placeholder="搜索名称或编码">
|
||||
<a-input v-model:value="searchText" allow-clear placeholder="搜索名称或编码">
|
||||
<template #prefix><Search :size="15" /></template>
|
||||
</a-input>
|
||||
|
||||
<a-spin :spinning="loading" class="tree-spin">
|
||||
<a-dropdown :menu="contextMenu" :trigger="['contextmenu']">
|
||||
<a-tree
|
||||
<FmsTree
|
||||
block-node
|
||||
default-expand-all
|
||||
show-line
|
||||
:tree-data="treeData"
|
||||
:selected-keys="selectedKey ? [selectedKey] : []"
|
||||
@right-click="onRightClick"
|
||||
|
||||
Reference in new issue
Block a user