20260805173201

This commit is contained in:
oneao committed 2026-08-05 17:32:01 +08:00
1 parent 7c9761a4fc
commit bca59a2755
7 files changed
+812 -31

No files matched your search

+32 -1
View File
@@ -1,7 +1,30 @@
<script setup>
import zhCN from "antdv-next/locale/zh_CN";
const themeConfig = {};
const themeConfig = {
token: {
controlHeight: 28,
},
components: {
Splitter: {
splitBarSize: 1,
},
Button: {
contentFontSize: 13,
paddingInline: 10,
},
Form: {
labelFontSize: 13,
verticalLabelMargin: "0 0 2px",
itemMarginBottom: 8,
},
Collapse: {
headerBg: "#ffffff",
contentBg: "#ffffff",
borderlessContentBg: "#ffffff",
},
},
};
const timePickerLocale = {
...zhCN.TimePicker,
placeholder: "",
@@ -45,3 +68,11 @@ const locale = {
</a-app>
</a-config-provider>
</template>
<style>
/* 全局:按钮内图标跟随 contentFontSize(13px),覆盖 Lucide 的固定 size */
.ant-btn svg {
width: 1em !important;
height: 1em !important;
}
</style>
@@ -138,7 +138,7 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
:aria-label="appStore.t('common.search', '搜索')"
@click="handleQuickSearch"
>
<Search :size="16" />
<Search />
</a-button>
</a-space-compact>
@@ -152,7 +152,6 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
>
<a-button
shape="circle"
class="toolbar-icon-button"
:class="{ 'toolbar-icon-button--active': advancedOpen }"
:aria-label="
advancedOpen
@@ -161,7 +160,7 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
"
@click="toggleAdvancedSearch"
>
<Search :size="16" />
<Search />
</a-button>
</a-tooltip>
@@ -172,17 +171,14 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
:trigger="['click']"
placement="bottomRight"
>
<span class="more-trigger">
<a-tooltip :title="appStore.t('common.more', '更多')">
<a-button
shape="circle"
class="toolbar-icon-button"
:aria-label="appStore.t('common.more', '更多')"
>
<Ellipsis :size="17" />
</a-button>
</a-tooltip>
</span>
<a-tooltip :title="appStore.t('common.more', '更多')">
<a-button
shape="circle"
:aria-label="appStore.t('common.more', '更多')"
>
<Ellipsis />
</a-button>
</a-tooltip>
</a-dropdown>
</div>
</div>
@@ -211,8 +207,8 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
class="query-more-toggle"
@click="advancedMoreOpen = !advancedMoreOpen"
>
<ChevronUp v-if="advancedMoreOpen" :size="15" />
<ChevronDown v-else :size="15" />
<ChevronUp v-if="advancedMoreOpen" />
<ChevronDown v-else />
{{
advancedMoreOpen
? appStore.t("common.collapseConditions", "收起条件")
@@ -223,11 +219,11 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
<div class="query-actions">
<a-button type="primary" :loading="loading" @click="handleAdvancedSearch">
<Search :size="15" />
<Search />
{{ appStore.t("common.search", "查询") }}
</a-button>
<a-button type="text" :disabled="loading" @click="handleAdvancedReset">
<RotateCcw :size="15" />
<RotateCcw />
{{ appStore.t("common.reset", "重置") }}
</a-button>
</div>
@@ -294,14 +290,6 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
}
.toolbar-icon-button {
display: inline-flex;
width: 34px;
min-width: 34px;
height: 34px;
align-items: center;
justify-content: center;
padding: 0;
&--active {
border-color: #91caff;
background: #e6f4ff;
@@ -311,8 +299,6 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
.more-trigger {
display: inline-flex;
width: 34px;
height: 34px;
}
.query-panel {
+20
View File
@@ -25,6 +25,16 @@ const routes = [
moduleId: "v_b_othercompany",
},
},
{
path: "base/othercompany/detail",
name: "base-othercompany-detail",
component: () => import("@/views/base/othercompany/detail.vue"),
meta: {
title: "合作伙伴详情",
section: "基础数据",
menuKey: "/base/othercompany",
},
},
{
path: "base/contact",
name: "base-contact",
@@ -36,6 +46,16 @@ const routes = [
moduleId: "v_b_contact",
},
},
{
path: "base/contact/detail",
name: "base-contact-detail",
component: () => import("@/views/base/contact/detail.vue"),
meta: {
title: "联系人详情",
section: "基础数据",
menuKey: "/base/contact",
},
},
{
path: "base/otherdata",
name: "base-otherdata",
@@ -0,0 +1,66 @@
<script setup>
import { computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ArrowLeft } from "@lucide/vue";
const route = useRoute();
const router = useRouter();
const isCreate = computed(() => route.query.mode === "create");
const recordId = computed(() => route.query.id || "");
function goBack() {
router.push({ name: "base-contact" });
}
</script>
<template>
<div class="contact-detail">
<div class="detail-header">
<a-button type="text" @click="goBack">
<ArrowLeft :size="16" />返回
</a-button>
<h2 class="detail-title">{{ isCreate ? "新增联系人" : "编辑联系人" }}</h2>
</div>
<div class="detail-body">
<a-empty description="详细内容待实现" />
</div>
</div>
</template>
<style scoped lang="scss">
.contact-detail {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
background: var(--fms-surface);
border: 1px solid var(--fms-border);
border-radius: 6px;
}
.detail-header {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
border-bottom: 1px solid var(--fms-border);
}
.detail-title {
margin: 0;
font-size: 16px;
font-weight: 600;
}
.detail-body {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
min-height: 0;
overflow: auto;
padding: 24px;
}
</style>
@@ -1,10 +1,82 @@
<script setup>
import { computed, ref } from "vue";
import { useRouter } from "vue-router";
import { message, Modal } from "antdv-next";
import { Plus, Trash2 } from "@lucide/vue";
import FmsModuleListPage from "@/components/fms-module-list/FmsModuleListPage.vue";
import { usePermissionStore } from "@/stores/permissions";
const CONTACT_MODULE_CODE = "v_b_contact";
const permissionStore = usePermissionStore();
const canCreateRow = computed(() => permissionStore.canPower(CONTACT_MODULE_CODE, "create"));
const canDeleteRow = computed(() => permissionStore.canPower(CONTACT_MODULE_CODE, "delete"));
const moduleListRef = ref(null);
const selectedRowKeys = ref([]);
const dirtyCount = ref(0);
const router = useRouter();
const rowSelection = computed(() => ({
selectedRowKeys: selectedRowKeys.value,
onChange: (keys) => {
selectedRowKeys.value = keys;
},
}));
function goCreate() {
if (canCreateRow.value) {
router.push({ name: "base-contact-detail", query: { mode: "create" } });
}
}
function confirmBatchDelete() {
if (!canDeleteRow.value || !selectedRowKeys.value.length) {
message.warning("请先选择要删除的记录");
return;
}
Modal.confirm({
title: `确定删除选中的 ${selectedRowKeys.value.length} 条记录?`,
content: "此操作不可恢复",
okText: "删除",
cancelText: "取消",
okButtonProps: { danger: true },
onOk: async () => {
try {
await moduleListRef.value?.deleteSelected?.(selectedRowKeys.value);
selectedRowKeys.value = [];
dirtyCount.value = 0;
} finally {
// noop
}
},
});
}
</script>
<template>
<div class="contact-page">
<FmsModuleListPage data-code="v_b_contact" />
<FmsModuleListPage
ref="moduleListRef"
data-code="v_b_contact"
:row-selection="rowSelection"
>
<template #actions>
<a-space>
<a-button v-if="canCreateRow" type="primary" @click="goCreate">
<Plus :size="15" />新增
</a-button>
<a-button
v-if="canDeleteRow"
danger
:disabled="!selectedRowKeys.length"
@click="confirmBatchDelete"
>
<Trash2 :size="15" />批量删除
</a-button>
</a-space>
</template>
</FmsModuleListPage>
</div>
</template>
@@ -0,0 +1,537 @@
<script setup>
import { ref } from "vue";
import { Save, RotateCcw, Trash2 } from "@lucide/vue";
const activeTab = ref("basic");
const tabItems = [
{ key: "basic", label: "基本信息" },
{ key: "contact", label: "联系信息" },
{ key: "finance", label: "财务信息" },
{ key: "business", label: "业务信息" },
{ key: "attach", label: "附件" },
];
</script>
<template>
<!--
IDEA 沉浸风 Demo
核心思路:
- 背景冷灰,无圆角无阴影,全贴边
- 工具栏极窄,纯功能
- 表单极致紧凑,冷色系
-->
<div class="idea-detail">
<!-- 顶部工具栏:36px,纯功能 -->
<div class="idea-toolbar">
<span class="idea-toolbar-title">合作伙伴详情</span>
<div class="idea-toolbar-actions">
<a-button>
<RotateCcw :size="15" />重置
</a-button>
<a-button danger>
<Trash2 :size="15" />删除
</a-button>
<a-button type="primary">
<Save :size="15" />保存
</a-button>
</div>
</div>
<!-- Tab:极小高度,贴边 -->
<div class="idea-tabs">
<a-tabs v-model:active-key="activeTab" :items="tabItems" />
</div>
<!-- 表单内容区 -->
<div class="idea-body">
<!-- ========== Tab: 基本信息 ========== -->
<div v-show="activeTab === 'basic'" class="idea-form">
<div class="idea-section">
<div class="idea-section-label">基本信息</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="6">
<a-form-item label="合作伙伴编码">
<a-input placeholder="自动生成" disabled />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="合作伙伴名称" required>
<a-input placeholder="请输入名称" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="简称">
<a-input placeholder="请输入简称" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="合作伙伴类型">
<a-select placeholder="请选择类型" allow-clear>
<a-select-option value="1">客户</a-select-option>
<a-select-option value="2">供应商</a-select-option>
<a-select-option value="3">代理商</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="客户级别">
<a-select placeholder="请选择级别" allow-clear>
<a-select-option value="A">A级</a-select-option>
<a-select-option value="B">B级</a-select-option>
<a-select-option value="C">C级</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="客户来源">
<a-select placeholder="请选择来源" allow-clear>
<a-select-option value="1">线上推广</a-select-option>
<a-select-option value="2">线下展会</a-select-option>
<a-select-option value="3">客户介绍</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<div class="idea-section">
<div class="idea-section-label">区域信息</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="6">
<a-form-item label="国家">
<a-select placeholder="请选择国家" allow-clear>
<a-select-option value="CN">中国</a-select-option>
<a-select-option value="US">美国</a-select-option>
<a-select-option value="JP">日本</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="省份">
<a-input placeholder="请输入省份" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="城市">
<a-input placeholder="请输入城市" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<div class="idea-section">
<div class="idea-section-label">状态设置</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="6">
<a-form-item label="是否启用">
<a-switch checked-children="启用" un-checked-children="停用" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="排序号">
<a-input-number placeholder="请输入排序号" :min="0" :style="{ width: '100%' }" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
</div>
<!-- ========== Tab: 联系信息 ========== -->
<div v-show="activeTab === 'contact'" class="idea-form">
<div class="idea-section">
<div class="idea-section-label">主要联系人</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="6">
<a-form-item label="联系人姓名">
<a-input placeholder="请输入姓名" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="职位">
<a-input placeholder="请输入职位" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="手机号码">
<a-input placeholder="请输入手机号码" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="电子邮箱">
<a-input placeholder="请输入邮箱" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<div class="idea-section">
<div class="idea-section-label">地址信息</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="16">
<a-form-item label="详细地址">
<a-textarea placeholder="请输入详细地址" :rows="2" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="邮政编码">
<a-input placeholder="请输入邮政编码" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
</div>
<!-- ========== Tab: 财务信息 ========== -->
<div v-show="activeTab === 'finance'" class="idea-form">
<div class="idea-section">
<div class="idea-section-label">结算信息</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="6">
<a-form-item label="结算币种">
<a-select placeholder="请选择币种" allow-clear>
<a-select-option value="CNY">人民币 (CNY)</a-select-option>
<a-select-option value="USD">美元 (USD)</a-select-option>
<a-select-option value="EUR">欧元 (EUR)</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="结算方式">
<a-select placeholder="请选择结算方式" allow-clear>
<a-select-option value="1">月结</a-select-option>
<a-select-option value="2">票结</a-select-option>
<a-select-option value="3">预付</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="付款条款">
<a-select placeholder="请选择付款条款" allow-clear>
<a-select-option value="1">预付</a-select-option>
<a-select-option value="2">到付</a-select-option>
<a-select-option value="3">月结30天</a-select-option>
<a-select-option value="4">月结60天</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<div class="idea-section">
<div class="idea-section-label">银行账户</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="6">
<a-form-item label="开户银行">
<a-input placeholder="请输入开户银行" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="银行账号">
<a-input placeholder="请输入银行账号" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="账户名称">
<a-input placeholder="请输入账户名称" />
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="税号">
<a-input placeholder="请输入税号" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
</div>
<!-- ========== Tab: 业务信息 ========== -->
<div v-show="activeTab === 'business'" class="idea-form">
<div class="idea-section">
<div class="idea-section-label">业务范围</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="12">
<a-form-item label="主营业务">
<a-select placeholder="请选择主营业务" mode="multiple" allow-clear>
<a-select-option value="1">海运</a-select-option>
<a-select-option value="2">空运</a-select-option>
<a-select-option value="3">陆运</a-select-option>
<a-select-option value="4">报关</a-select-option>
<a-select-option value="5">仓储</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="合作状态">
<a-select placeholder="请选择状态" allow-clear>
<a-select-option value="1">合作中</a-select-option>
<a-select-option value="2">暂停</a-select-option>
<a-select-option value="3">终止</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<div class="idea-section">
<div class="idea-section-label">备注信息</div>
<a-form layout="vertical">
<a-row :gutter="12">
<a-col :span="16">
<a-form-item label="备注">
<a-textarea placeholder="请输入备注信息" :rows="3" />
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
</div>
<!-- ========== Tab: 附件 ========== -->
<div v-show="activeTab === 'attach'" class="idea-form">
<a-empty description="暂无附件" />
</div>
</div>
</div>
</template>
<style scoped lang="scss">
/*
* Modern IDE 风格 v3
* 参考:IDEA 2024 New UI / Linear / Vercel
* 关键词:柔和、圆角、透明度、微妙阴影、过渡动画
*/
// ═══ 颜色令牌 ═══
$bg-root: #f1f3f5; // 根背景 — 暖灰偏冷
$bg-toolbar: #ffffff; // 工具栏白
$bg-tab: #f8f9fb; // Tab 区
$bg-card: #ffffff; // 表单卡片
$border: #e2e5e9; // 边框
$border-light: #eceff3; // 淡边框
$text: #111418; // 主文字
$text-secondary: #5e6470; // 副文字
$text-muted: #9098a5; // 淡文字
$primary: #1a56db; // 主色
$primary-soft: rgba(26, 86, 219, 0.06); // focus 光晕
// ═══════════════════════════════════════════
// 根容器
// ═══════════════════════════════════════════
.idea-detail {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
background: $bg-root;
}
// ═══════════════════════════════════════════
// 工具栏
// ═══════════════════════════════════════════
.idea-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
min-height: 40px;
padding: 0 20px;
flex-shrink: 0;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.idea-toolbar-title {
font-size: 13px;
font-weight: 500;
color: $text-secondary;
letter-spacing: -0.01em;
}
.idea-toolbar-actions {
display: flex;
gap: 8px;
}
// ═══════════════════════════════════════════
// Tab 栏
// ═══════════════════════════════════════════
.idea-tabs {
flex-shrink: 0;
background: $bg-tab;
padding: 0 20px;
border-bottom: 1px solid $border-light;
:deep(.ant-tabs-nav) {
margin-bottom: 0;
&::before {
border-bottom: none;
}
}
:deep(.ant-tabs-tab) {
padding: 8px 16px;
font-size: 13px;
color: $text-muted;
border-radius: 0;
transition: color 0.15s ease;
&:hover {
color: $text;
}
&.ant-tabs-tab-active .ant-tabs-tab-btn {
color: $text;
font-weight: 500;
}
}
:deep(.ant-tabs-ink-bar) {
background: $primary;
height: 2px;
border-radius: 1px;
}
:deep(.ant-tabs-content-holder) {
display: none;
}
}
// ═══════════════════════════════════════════
// 内容区
// ═══════════════════════════════════════════
.idea-body {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 24px;
background: $bg-root;
&::-webkit-scrollbar { width: 6px; }
&::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.12);
border-radius: 3px;
&:hover { background: rgba(0, 0, 0, 0.2); }
}
&::-webkit-scrollbar-track { background: transparent; }
}
// 表单卡片
.idea-form {
max-width: 840px;
margin: 0 auto;
background: $bg-card;
border-radius: 10px;
padding: 32px 40px;
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.04),
0 1px 2px rgba(0, 0, 0, 0.03),
0 2px 8px rgba(0, 0, 0, 0.04);
}
// ═══════════════════════════════════════════
// Section
// ═══════════════════════════════════════════
.idea-section {
margin-bottom: 28px;
&:last-child {
margin-bottom: 0;
}
}
.idea-section-label {
font-size: 12px;
font-weight: 600;
color: $text;
letter-spacing: 0.02em;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 1px solid $border-light;
}
// ═══════════════════════════════════════════
// 表单控件 — 现代圆角、柔和边框
// ═══════════════════════════════════════════
:deep(.ant-form-item) {
margin-bottom: 16px;
}
:deep(.ant-form-item-label) {
padding-bottom: 4px;
> label {
font-size: 13px;
font-weight: 450;
color: $text-secondary;
height: 24px;
line-height: 24px;
}
}
// 输入框 / 选择器 — 6px 圆角,现代感
:deep(.ant-input),
:deep(.ant-input-affix-wrapper),
:deep(.ant-select-selector),
:deep(.ant-input-number) {
font-size: 13px;
border-radius: 6px;
border-color: $border;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
&:hover {
border-color: darken($border, 8%);
}
}
:deep(.ant-input-number-input) {
font-size: 13px;
}
:deep(.ant-select-selection-item) {
font-size: 13px;
}
// Focus — 蓝色光晕
:deep(.ant-input:focus),
:deep(.ant-input-affix-wrapper-focused),
:deep(.ant-select-focused .ant-select-selector),
:deep(.ant-input-number-focused) {
border-color: $primary;
box-shadow: 0 0 0 3px $primary-soft;
}
// disabled 态更柔和
:deep(.ant-input-disabled),
:deep(.ant-select-disabled .ant-select-selector) {
background: #f8f9fb;
color: $text-muted;
}
// Switch 微调
:deep(.ant-switch) {
&.ant-switch-checked {
background: $primary;
}
}
</style>
@@ -6,14 +6,35 @@ import FmsModuleListPage from "@/components/fms-module-list/FmsModuleListPage.vu
import FmsTree from "@/components/FmsTree.vue";
import { escapeSqlText } from "@/components/fms-module-list/moduleListUtils";
import { loadDataApi, nextIdApi, pageDataApi, saveObjectApi } from "@/services/api";
import { usePermissionStore } from "@/stores/permissions";
import { buildTree, sortTree } from "@/utils/tree";
const OTHERCOMPANY_MODULE_CODE = "v_b_othercompany";
const ALL_CATEGORIES_KEY = "__fms_tree_root__";
const categories = ref([]);
const categoryLoading = ref(false);
const selectedCategoryKey = ref(ALL_CATEGORIES_KEY);
const expandedCategoryKeys = ref([ALL_CATEGORIES_KEY]);
const permissionStore = usePermissionStore();
const canCreateRow = computed(() => permissionStore.canPower(OTHERCOMPANY_MODULE_CODE, "create"));
const canUpdateRow = computed(() => permissionStore.canPower(OTHERCOMPANY_MODULE_CODE, "update"));
const canDeleteRow = computed(() => permissionStore.canPower(OTHERCOMPANY_MODULE_CODE, "delete"));
import { useRouter } from "vue-router";
const moduleListRef = ref(null);
const selectedRowKeys = ref([]);
const dirtyCount = ref(0);
const router = useRouter();
const rowSelection = computed(() => ({
selectedRowKeys: selectedRowKeys.value,
onChange: (keys) => {
selectedRowKeys.value = keys;
},
}));
const categoryById = computed(
() => new Map(categories.value.map((item) => [String(item.b_id), item])),
);
@@ -368,6 +389,36 @@ async function confirmDeleteCategory(node) {
});
}
// ── 新增 / 批量删除 ──
function goCreate() {
if (canCreateRow.value) {
router.push({ name: "base-othercompany-detail", query: { mode: "create" } });
}
}
function confirmBatchDelete() {
if (!canDeleteRow.value || !selectedRowKeys.value.length) {
message.warning("请先选择要删除的记录");
return;
}
Modal.confirm({
title: `确定删除选中的 ${selectedRowKeys.value.length} 条记录?`,
content: "此操作不可恢复",
okText: "删除",
cancelText: "取消",
okButtonProps: { danger: true },
onOk: async () => {
try {
await moduleListRef.value?.deleteSelected?.(selectedRowKeys.value);
selectedRowKeys.value = [];
dirtyCount.value = 0;
} finally {
// noop
}
},
});
}
onMounted(() => {
loadCategories();
});
@@ -396,10 +447,28 @@ onMounted(() => {
<a-splitter-panel :min="520">
<main class="partner-panel">
<FmsModuleListPage
ref="moduleListRef"
data-code="v_b_othercompany"
:fixed-search-condition="categoryFilterCondition"
:column-extensions="columnExtensions"
/>
:row-selection="rowSelection"
>
<template #actions>
<a-space>
<a-button v-if="canCreateRow" type="primary" @click="goCreate">
<Plus :size="15" />新增
</a-button>
<a-button
v-if="canDeleteRow"
danger
:disabled="!selectedRowKeys.length"
@click="confirmBatchDelete"
>
<Trash2 :size="15" />批量删除
</a-button>
</a-space>
</template>
</FmsModuleListPage>
</main>
</a-splitter-panel>
</a-splitter>