20260726225220
This commit is contained in:
1 parent
e3c7c6f8da
commit
a8478d60ed
170 files changed
+6786
-1678
No files matched your search
@@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, shallowRef, watch } from "vue";
|
||||
import { ref, watch, computed } from "vue";
|
||||
import { message, Modal } from "antdv-next";
|
||||
import FmsTable from "@/components/fms-table/FmsTable.vue";
|
||||
|
||||
const FIELD_TYPES = [
|
||||
@@ -25,24 +26,95 @@ const emit = defineEmits(["update", "sync"]);
|
||||
const localFields = ref([]);
|
||||
const activeKey = ref(null);
|
||||
|
||||
// 同步:未配置查询视图时,手动输入表/视图名
|
||||
const syncOpen = ref(false);
|
||||
const syncTable = ref("");
|
||||
|
||||
function onSyncClick() {
|
||||
if (props.viewTable) {
|
||||
emit("sync", props.viewTable);
|
||||
return;
|
||||
}
|
||||
syncTable.value = "";
|
||||
syncOpen.value = true;
|
||||
}
|
||||
|
||||
function onSyncConfirm() {
|
||||
const name = syncTable.value.trim();
|
||||
if (!name) {
|
||||
message.warning("请输入表或视图名");
|
||||
return;
|
||||
}
|
||||
syncOpen.value = false;
|
||||
emit("sync", name);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.fields,
|
||||
(val) => {
|
||||
if (val === localFields.value) return;
|
||||
localFields.value = val?.map((r) => ({ ...r })) || [];
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
function emitUpdate() {
|
||||
emit(
|
||||
"update",
|
||||
localFields.value.map((r) => ({ ...r })),
|
||||
);
|
||||
emit("update", localFields.value);
|
||||
}
|
||||
|
||||
const columns = shallowRef([
|
||||
// 编辑器已直接更新当前行,这里只向父级同步草稿。
|
||||
function onCellChange() {
|
||||
emitUpdate();
|
||||
}
|
||||
|
||||
// 行多选:selectedRowKeys 由 FmsTable 的选择列回写;
|
||||
// 传了 rowSelection 时 FmsTable 会在最前列插入复选框列(也是单击进入编辑态所需的机制)。
|
||||
const selectedRowKeys = ref([]);
|
||||
const rowSelection = computed(() => ({
|
||||
selectedRowKeys: selectedRowKeys.value,
|
||||
onChange: (keys) => {
|
||||
selectedRowKeys.value = keys;
|
||||
},
|
||||
}));
|
||||
|
||||
function deleteRow(record) {
|
||||
if (props.loading) return;
|
||||
localFields.value = localFields.value.filter((r) => r.b_id !== record.b_id);
|
||||
const k = String(record.b_id);
|
||||
if (selectedRowKeys.value.includes(k)) {
|
||||
selectedRowKeys.value = selectedRowKeys.value.filter((x) => x !== k);
|
||||
}
|
||||
emitUpdate();
|
||||
}
|
||||
|
||||
// 批量删除选中行
|
||||
function batchDelete() {
|
||||
if (props.loading) return;
|
||||
const keys = selectedRowKeys.value;
|
||||
if (!keys.length) return;
|
||||
Modal.confirm({
|
||||
title: `确定删除选中的 ${keys.length} 条记录?`,
|
||||
okText: "删除",
|
||||
okType: "danger",
|
||||
cancelText: "取消",
|
||||
onOk: () => {
|
||||
const delSet = new Set(keys);
|
||||
localFields.value = localFields.value.filter((r) => !delSet.has(r.b_id));
|
||||
selectedRowKeys.value = [];
|
||||
if (activeKey.value && delSet.has(activeKey.value)) activeKey.value = "";
|
||||
emitUpdate();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const columns = ref([
|
||||
{ dataIndex: "b_field", title: "字段名", width: 140 },
|
||||
{ dataIndex: "b_name", title: "字段名称", width: 140 },
|
||||
{
|
||||
dataIndex: "b_name",
|
||||
title: "字段名称",
|
||||
width: 140,
|
||||
editor: { type: "input", onChange: () => emitUpdate() },
|
||||
},
|
||||
{
|
||||
dataIndex: "b_type",
|
||||
title: "控件类型",
|
||||
@@ -53,8 +125,18 @@ const columns = shallowRef([
|
||||
onChange: () => emitUpdate(),
|
||||
},
|
||||
},
|
||||
{ dataIndex: "b_default_value", title: "默认值", width: 120 },
|
||||
{ dataIndex: "b_i18n", title: "多语言键", width: 140 },
|
||||
{
|
||||
dataIndex: "b_default_value",
|
||||
title: "默认值",
|
||||
width: 120,
|
||||
editor: { type: "input", onChange: () => emitUpdate() },
|
||||
},
|
||||
{
|
||||
dataIndex: "b_i18n",
|
||||
title: "多语言键",
|
||||
width: 140,
|
||||
editor: { type: "input", onChange: () => emitUpdate() },
|
||||
},
|
||||
{
|
||||
dataIndex: "b_canuse",
|
||||
title: "启用",
|
||||
@@ -62,6 +144,19 @@ const columns = shallowRef([
|
||||
align: "center",
|
||||
editor: { type: "checkbox", onChange: () => emitUpdate() },
|
||||
},
|
||||
{
|
||||
dataIndex: "actions",
|
||||
title: "操作",
|
||||
width: 60,
|
||||
actions: [
|
||||
{
|
||||
type: "delete",
|
||||
label: "删除",
|
||||
confirm: "确定删除该字段?",
|
||||
onClick: (row) => deleteRow(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
||||
@@ -69,18 +164,39 @@ const columns = shallowRef([
|
||||
<div class="fields-panel">
|
||||
<div class="panel-toolbar">
|
||||
<a-space>
|
||||
<a-button v-if="viewTable" type="primary" @click="emit('sync')">
|
||||
同步字段 ({{ viewTable }})
|
||||
<a-button type="primary" :disabled="loading" @click="onSyncClick">
|
||||
同步字段{{ viewTable ? ` (${viewTable})` : "" }}
|
||||
</a-button>
|
||||
<a-button danger :disabled="loading || !selectedRowKeys.length" @click="batchDelete">
|
||||
批量删除{{ selectedRowKeys.length ? `(${selectedRowKeys.length})` : "" }}
|
||||
</a-button>
|
||||
<span v-if="!viewTable" class="panel-hint">未配置查询视图,点击后手动输入表名</span>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<a-modal
|
||||
v-model:open="syncOpen"
|
||||
title="同步字段"
|
||||
@ok="onSyncConfirm"
|
||||
:confirm-loading="loading"
|
||||
>
|
||||
<p>当前模块未配置查询视图,请填写要同步字段的表或视图名:</p>
|
||||
<a-input
|
||||
v-model:value="syncTable"
|
||||
placeholder="例如 s_log_login 或 v_biz"
|
||||
@press-enter="onSyncConfirm"
|
||||
/>
|
||||
</a-modal>
|
||||
<div class="panel-body">
|
||||
<FmsTable
|
||||
v-model:columns="columns"
|
||||
:data-source="localFields"
|
||||
:editable="!loading"
|
||||
row-key="b_id"
|
||||
:active-row-key="activeKey"
|
||||
@row-click="(ev, row) => (activeKey = row.b_id)"
|
||||
:row-selection="rowSelection"
|
||||
@row-click="(_, row) => (activeKey = String(row.b_id))"
|
||||
@change="onCellChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user