右键复制

This commit is contained in:
luojiaquan
2026-10-13 17:16:27 +08:00
parent d6a6ec4d53
commit 3598a0d669
5 changed files with 354 additions and 4 deletions
+41 -1
View File
@@ -49,9 +49,12 @@
已选 <b>{{ selectedReceipts.length }}</b> 笔收款,
收款总额(本位币):<b class="money-in">CNY {{ selectedCnyTotal }}</b>
<template v-if="selectedCurrencyText">,原币合计:{{ selectedCurrencyText }}</template>
<span class="copy-tip">(勾选后在表格内<strong>右键</strong>可复制所选列的值)</span>
</div>
<el-table :data="receiptList" border v-loading="receiptLoading" @selection-change="onReceiptSelectionChange">
<el-table :data="receiptList" border v-loading="receiptLoading"
@selection-change="onReceiptSelectionChange"
@row-contextmenu="onReceiptRowContextmenu">
<el-table-column type="selection" width="42" align="center" />
<el-table-column label="收款单号" align="center" prop="receiptNo" width="180" show-overflow-tooltip />
<el-table-column label="客户" align="center" min-width="180" show-overflow-tooltip>
@@ -657,6 +660,14 @@
<el-button @click="cancelWoDialog.visible = false">取 消</el-button>
</template>
</el-dialog>
<!-- ====================== 右键复制列菜单 ====================== -->
<table-copy-menu
ref="copyMenuRef"
:columns="copyColumns"
:selected-rows="selectedReceipts"
entity-label="笔"
/>
</div>
</template>
@@ -785,6 +796,29 @@ function onReceiptSelectionChange(rows) {
selectedReceipts.value = rows || []
}
/* ================= 右键复制列值(复用全局 TableCopyMenu) ================= */
// 可复制的列:label 为菜单显示名,get(row) 取该行列值
const copyColumns = [
{ key: 'receiptNo', label: '收款单号', get: r => r.receiptNo || '' },
{ key: 'customerName', label: '客户名称', get: r => r.customerName || '' },
{ key: 'customerCode', label: '客户编码', get: r => r.customerCode || '' },
{ key: 'receivedAt', label: '收款时间', get: r => (r.receivedAt ? formatDateTime(r.receivedAt) : '') },
{ key: 'amount', label: '原币金额', get: r => `${r.currency || ''} ${formatMoney(r.amount)}`.trim() },
{ key: 'baseAmount', label: '本位币金额(CNY)', get: r => formatMoney(r.baseAmount) },
{ key: 'payMethod', label: '收款方式', get: r => formatOption(payMethodOptions, r.payMethod) },
{ key: 'bankTransactionNo', label: '流水号', get: r => r.bankTransactionNo || '' }
]
const copyMenuRef = ref(null)
/** 表格行右键:有勾选则复制勾选行,否则只复制当前右键行(逻辑在 TableCopyMenu 内) */
function onReceiptRowContextmenu(row, column, event) {
copyMenuRef.value && copyMenuRef.value.open(row, event)
}
function closeContextMenu() {
copyMenuRef.value && copyMenuRef.value.close()
}
/** 选中收款的本位币总额(CNY) */
const selectedCnyTotal = computed(() => {
const sum = selectedReceipts.value.reduce((s, r) => s + (Number(r.baseAmount) || 0), 0)
@@ -801,6 +835,7 @@ const selectedCurrencyText = computed(() => {
})
function getReceiptList() {
closeContextMenu()
receiptLoading.value = true
receiptQuery.pageNum = receiptQuery.pageNum || 1
const params = proxy.addDateRange({ ...receiptQuery }, receiptDateRange.value)
@@ -1368,4 +1403,9 @@ getReceiptList()
font-weight: 600;
margin: 12px 0 8px;
}
.copy-tip {
color: var(--el-text-color-secondary);
font-weight: normal;
font-size: 12px;
}
</style>
@@ -129,7 +129,9 @@
<column-settings :columns="columnDefs" :visible-map="colVisible" @toggle="toggleColumn" @reset="resetColumns" />
</el-row>
<el-table v-loading="loading" border :data="customerList" @selection-change="handleSelectionChange">
<el-table v-loading="loading" border :data="customerList"
@selection-change="handleSelectionChange"
@row-contextmenu="onTableRowContextmenu">
<el-table-column type="selection" width="55" align="center" fixed="left" />
<!-- <el-table-column label="客户ID" align="center" prop="customerId" />-->
<el-table-column v-if="isColVisible('customerCode')" label="客户编码" width="100" align="center" prop="customerCode" />
@@ -285,13 +287,22 @@
:customer-name="logCustomer.customerName"
:customer-code="logCustomer.customerCode"
/>
<!-- 右键复制列值 -->
<table-copy-menu
ref="copyMenuRef"
:columns="copyColumns"
:selected-rows="selectedRows"
:visible-keys="visibleCopyKeys"
/>
</div>
</template>
<script setup name="Customer">
<script setup name="Customerinfo">
import { listCustomer, delCustomer } from "@/api/customersuppliermanagement/customerinfo/customer.js"
import { listPriceSetOption, batchBindCustomerPriceSet } from "@/api/customersuppliermanagement/customerinfo/customerPriceSet.js"
import { useProducts, parseProductCodes } from '@/components/ProductSelect/useProducts'
import { useUsers } from '@/components/UserSelect/useUsers'
import CustomerLogDialog from './components/CustomerLogDialog.vue'
import { useColumnSettings } from '@/utils/columnSettings'
@@ -339,12 +350,48 @@ function productNames(productCodes) {
}
ensureProducts()
/** 员工ID -> 姓名(与表格 UserName 展示同源) */
const { ensureUsers, getUserName } = useUsers()
ensureUsers()
/** 格式化余额(数据源 customer_account 余额表) */
function formatBalance(val) {
const num = Number(val)
return isNaN(num) ? '0.00' : num.toFixed(2)
}
/* ================= 右键复制列值 ================= */
const copyMenuRef = ref(null)
/** 右键可复制列(取值口径与表格展示一致) */
const copyColumns = computed(() => [
{ key: 'customerCode', label: '客户编码', get: r => r.customerCode || '' },
{ key: 'customerName', label: '客户名称', get: r => r.customerName || '' },
{ key: 'customerCodeDw', label: '对外代码', get: r => r.customerCodeDw || '' },
{ key: 'creditCode', label: '统一社会信用代码', get: r => r.creditCode || '' },
{ key: 'customerType', label: '业务类型', get: r => proxy.selectDictLabel(customer_type.value, r.customerType) },
{ key: 'isEnable', label: '启用状态', get: r => proxy.selectDictLabel(sys_normal_disable.value, r.isEnable) },
{ key: 'salesUserId', label: '业务员', get: r => r.salesUserNickName || r.salesUser || r.salesUserId || '' },
{ key: 'zq', label: '回款账期', get: r => (r.zq === null || r.zq === undefined ? '' : r.zq) },
{ key: 'settlementUserId', label: '结算员', get: r => getUserName(r.settlementUserId) },
{ key: 'serviceUserId', label: '客服', get: r => getUserName(r.serviceUserId) },
{ key: 'settlementType', label: '结算方式', get: r => proxy.selectDictLabel(settlement_type.value, r.settlementType) },
{ key: 'tempEd', label: '临时额度', get: r => (r.tempEd === null || r.tempEd === undefined ? '' : r.tempEd) },
{ key: 'accountBalance', label: '账户余额(CNY)', get: r => formatBalance(r.accountBalance) },
{ key: 'weightThreshold', label: '重量阈值', get: r => (r.weightThreshold === null || r.weightThreshold === undefined ? '' : r.weightThreshold) },
{ key: 'throwRatio', label: '抛比', get: r => (r.throwRatio === null || r.throwRatio === undefined ? '' : r.throwRatio) },
{ key: 'creditEd', label: '信用额度', get: r => (r.creditEd === null || r.creditEd === undefined ? '' : r.creditEd) },
{ key: 'productCodes', label: '绑定产品', get: r => productNames(r.productCodes) },
{ key: 'priceSetName', label: '绑定套餐', get: r => r.priceSetName || '' },
{ key: 'remark', label: '备注说明', get: r => r.remark || '' }
])
/** 右键菜单只展示当前「列设置」中可见的列 */
const visibleCopyKeys = computed(() =>
columnDefs.filter(c => isColVisible(c.key)).map(c => c.key)
)
function onTableRowContextmenu(row, column, event) {
copyMenuRef.value && copyMenuRef.value.open(row, event)
}
const data = reactive({
queryParams: {
pageNum: 1,
@@ -376,6 +423,7 @@ const { queryParams } = toRefs(data)
/** 查询客户主列表 */
function getList() {
copyMenuRef.value && copyMenuRef.value.close()
loading.value = true
listCustomer(queryParams.value).then(response => {
customerList.value = response.rows
@@ -119,7 +119,9 @@
<column-settings :columns="columnDefs" :visible-map="colVisible" @toggle="toggleColumn" @reset="resetColumns" />
</el-row>
<el-table v-loading="loading" border :data="supplierList" @selection-change="handleSelectionChange">
<el-table v-loading="loading" border :data="supplierList"
@selection-change="handleSelectionChange"
@row-contextmenu="onTableRowContextmenu">
<el-table-column type="selection" width="55" align="center" fixed="left" />
<el-table-column v-if="isColVisible('supplierCode')" label="供应商编码" align="center" width="130" prop="supplierCode" />
<el-table-column v-if="isColVisible('supplierName')" label="供应商名称" align="center" width="130" prop="supplierName" :show-overflow-tooltip="true" />
@@ -189,12 +191,21 @@
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 右键复制列值 -->
<table-copy-menu
ref="copyMenuRef"
:columns="copyColumns"
:selected-rows="selectedRows"
:visible-keys="visibleCopyKeys"
/>
</div>
</template>
<script setup name="Supplier">
import { listSupplier, delSupplier } from "@/api/customersuppliermanagement/supplierinfo/supplier.js"
import { useChannels, parseChannelCodes } from '@/components/ChannelSelect/useChannels'
import { useUsers } from '@/components/UserSelect/useUsers'
import { useColumnSettings } from '@/utils/columnSettings'
const { proxy } = getCurrentInstance()
@@ -281,6 +292,47 @@ function formatDateOnly(value) {
return s.length > 10 ? s.substring(0, 10) : s
}
/** 员工ID -> 姓名(与表格 UserName 展示同源) */
const { ensureUsers, getUserName } = useUsers()
ensureUsers()
/* ================= 右键复制列值 ================= */
const copyMenuRef = ref(null)
/** 右键可复制列(取值口径与表格展示一致) */
const copyColumns = computed(() => [
{ key: 'supplierCode', label: '供应商编码', get: r => r.supplierCode || '' },
{ key: 'supplierName', label: '供应商名称', get: r => r.supplierName || '' },
{ key: 'supplierCodeDw', label: '对外代码', get: r => r.supplierCodeDw || '' },
{ key: 'creditCode', label: '统一社会信用代码', get: r => r.creditCode || '' },
{ key: 'supplierType', label: '供应商类型', get: r => formatOption(supplierTypeOptions.value, r.supplierType) },
{ key: 'invoiceType', label: '开票类型', get: r => formatOption(invoiceTypeOptions.value, r.invoiceType) },
{ key: 'kacheType', label: '卡车行类型', get: r => formatOption(kacheTypeOptions.value, r.kacheType) },
{ key: 'isEnable', label: '启用状态', get: r => proxy.selectDictLabel(sys_normal_disable.value, r.isEnable) },
{ key: 'purchaserUserId', label: '采购员', get: r => getUserName(r.purchaserUserId) },
{ key: 'ed', label: '应付额度', get: r => (r.ed === null || r.ed === undefined ? '' : r.ed) },
{ key: 'zq', label: '应付账期', get: r => (r.zq === null || r.zq === undefined ? '' : r.zq) },
{ key: 'settlementUserId', label: '结算员', get: r => getUserName(r.settlementUserId) },
{ key: 'serviceUserId', label: '跟单员', get: r => getUserName(r.serviceUserId) },
{ key: 'settlementType', label: '结算方式', get: r => proxy.selectDictLabel(settlement_type.value, r.settlementType) },
{ key: 'tempEd', label: '临时额度', get: r => (r.tempEd === null || r.tempEd === undefined ? '' : r.tempEd) },
{ key: 'accountBalance', label: '应付余额', get: r => (r.accountBalance === null || r.accountBalance === undefined ? '' : r.accountBalance) },
{ key: 'foreignCurrencyBalance', label: '外币应付余额', get: r => (r.foreignCurrencyBalance === null || r.foreignCurrencyBalance === undefined ? '' : r.foreignCurrencyBalance) },
{ key: 'creditEd', label: '信用额度', get: r => (r.creditEd === null || r.creditEd === undefined ? '' : r.creditEd) },
{ key: 'weightThreshold', label: '重量阈值', get: r => (r.weightThreshold === null || r.weightThreshold === undefined ? '' : r.weightThreshold) },
{ key: 'throwRatio', label: '抛比', get: r => (r.throwRatio === null || r.throwRatio === undefined ? '' : r.throwRatio) },
{ key: 'cooperationStartDate', label: '合作开始日期', get: r => formatDateOnly(r.cooperationStartDate) },
{ key: 'cooperationStatus', label: '合作状态', get: r => formatOption(cooperationStatusOptions.value, r.cooperationStatus) },
{ key: 'channelIds', label: '绑定渠道', get: r => channelNames(r.channelIds) },
{ key: 'remark', label: '备注说明', get: r => r.remark || '' }
])
/** 右键菜单只展示当前「列设置」中可见的列 */
const visibleCopyKeys = computed(() =>
columnDefs.filter(c => isColVisible(c.key)).map(c => c.key)
)
function onTableRowContextmenu(row, column, event) {
copyMenuRef.value && copyMenuRef.value.open(row, event)
}
const data = reactive({
queryParams: {
pageNum: 1,
@@ -315,6 +367,7 @@ const { queryParams } = toRefs(data)
/** 查询供应商列表 */
function getList() {
copyMenuRef.value && copyMenuRef.value.close()
loading.value = true
listSupplier(queryParams.value).then(response => {
supplierList.value = response.rows