Files
BMS/bms-front/src/views/customersuppliermanagement/customerinfo/index.vue
T
2026-11-04 18:29:47 +08:00

675 lines
27 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="关键词" prop="keywords">
<el-input
v-model="queryParams.keywords"
type="textarea"
:autosize="{ minRows: 1, maxRows: 4 }"
placeholder="客户编码/客户名称/对外代码,一行一个,模糊查询(多行为或者关系)"
clearable
style="width: 340px;"
@keyup.enter.ctrl="handleQuery"
/>
</el-form-item>
<el-form-item label="启用状态" prop="isEnable">
<el-select
v-model="queryParams.isEnable"
placeholder="请选择启用状态"
clearable
@change="handleQuery"
>
<el-option
label="正常"
:value="0"
/>
<el-option
label="停用"
:value="1"
/>
</el-select>
</el-form-item>
<el-form-item label="客户区域" prop="customerArea">
<el-select
v-model="queryParams.customerArea"
placeholder="请选择客户区域"
clearable
style="width: 160px"
@change="handleQuery"
>
<el-option
v-for="dict in customer_area"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="业务员" prop="salesUserId">
<user-select
v-model="queryParams.salesUserId"
placeholder="姓名/工号搜索"
@change="handleQuery"
/>
</el-form-item>
<el-form-item label="结算员" prop="settlementUserId">
<user-select v-model="queryParams.settlementUserId" placeholder="请选择结算员" @change="handleQuery" />
</el-form-item>
<el-form-item label="客服" prop="serviceUserId">
<user-select v-model="queryParams.serviceUserId" placeholder="请选择客服" @change="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['customersupplier:customerinfo:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['customersupplier:customerinfo:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleCustomerMoney"
v-hasPermi="['customersupplier:customerinfo:balance']"
>客户余额</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Box"
:disabled="multiple"
@click="handleBatchBindPriceSet"
v-hasPermi="['customersupplier:customerinfo:edit']"
>批量绑定套餐</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="Document"
:disabled="single"
@click="handleViewLog()"
v-hasPermi="['customersupplier:customerinfo:query']"
>日志</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['customersupplier:customerinfo:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="User"
@click="unlinkedSalesDialogVisible = true"
v-hasPermi="['customersupplier:customerinfo:list']"
>未关联业务员</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['customersupplier:customerinfo:export']"
>导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<column-settings :columns="columnDefs" :visible-map="colVisible" @toggle="toggleColumn" @reset="resetColumns" />
</el-row>
<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" />
<el-table-column v-if="isColVisible('customerName')" label="客户名称" width="300" align="center" prop="customerName" :show-overflow-tooltip="true" />
<el-table-column v-if="isColVisible('customerCodeDw')" label="对外代码" align="center" prop="customerCodeDw" />
<el-table-column v-if="isColVisible('creditCode')" label="统一社会信用代码" width="200" align="center" prop="creditCode" />
<el-table-column v-if="isColVisible('customerType')" label="业务类型" align="center" prop="customerType">
<template #default="scope">
<dict-tag :options="customer_type" :value="scope.row.customerType" />
</template>
</el-table-column>
<el-table-column v-if="isColVisible('customerArea')" label="客户区域" align="center" prop="customerArea" width="110">
<template #default="scope">
<dict-tag :options="customer_area" :value="scope.row.customerArea" />
</template>
</el-table-column>
<el-table-column v-if="isColVisible('isEnable')" label="启用状态" align="center" prop="isEnable">
<template #default="scope">
<dict-tag :options="sys_normal_disable" :value="scope.row.isEnable" />
</template>
</el-table-column>
<el-table-column v-if="isColVisible('salesUserId')" label="业务员" align="center" prop="salesUserId">
<template #default="scope">{{ scope.row.salesUserNickName || '' }}</template>
</el-table-column>
<!-- <el-table-column v-if="isColVisible('ed')" label="资金额度" align="center" prop="ed" />-->
<el-table-column v-if="isColVisible('zq')" label="回款账期" align="center" prop="zq" />
<el-table-column v-if="isColVisible('settlementUserId')" label="结算员" align="center" prop="settlementUserId">
<template #default="scope"><user-name :user-id="scope.row.settlementUserId" /></template>
</el-table-column>
<el-table-column v-if="isColVisible('serviceUserId')" label="客服" align="center" prop="serviceUserId">
<template #default="scope"><user-name :user-id="scope.row.serviceUserId" /></template>
</el-table-column>
<el-table-column v-if="isColVisible('settlementType')" label="结算方式" align="center" prop="settlementType">
<template #default="scope">
<dict-tag :options="settlement_type" :value="scope.row.settlementType" />
</template>
</el-table-column>
<el-table-column v-if="isColVisible('tempEd')" label="临时额度" align="center" prop="tempEd" />
<el-table-column v-if="isColVisible('accountBalance')" label="账户余额(CNY)" align="center" prop="accountBalance" width="130">
<template #default="scope">{{ formatBalance(scope.row.accountBalance) }}</template>
</el-table-column>
<el-table-column v-if="isColVisible('weightThreshold')" label="重量阈值" align="center" prop="weightThreshold" />
<el-table-column v-if="isColVisible('throwRatio')" label="抛比" align="center" prop="throwRatio" />
<el-table-column v-if="isColVisible('creditEd')" label="信用额度" align="center" prop="creditEd">
<template #default="scope">
<span v-if="Number(scope.row.creditEd) < 0" style="color: var(--el-color-danger); font-weight: 600;"
title="信用额度异常(如临时额度到期失效),请核查客户额度">
{{ scope.row.creditEd }}
</span>
<span v-else>{{ scope.row.creditEd }}</span>
</template>
</el-table-column>
<el-table-column v-if="isColVisible('contractStartDate')" label="合同开始时间" align="center" prop="contractStartDate" width="120">
<template #default="scope">{{ formatDateOnly(scope.row.contractStartDate) }}</template>
</el-table-column>
<el-table-column v-if="isColVisible('contractEndDate')" label="合同结束时间" align="center" prop="contractEndDate" width="120">
<template #default="scope">{{ formatDateOnly(scope.row.contractEndDate) }}</template>
</el-table-column>
<el-table-column v-if="isColVisible('productCodes')" label="绑定产品" align="center" prop="productCodes" min-width="180" show-overflow-tooltip>
<template #default="scope">
<span v-if="productNames(scope.row.productCodes)">{{ productNames(scope.row.productCodes) }}</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column v-if="isColVisible('priceSetName')" label="绑定套餐" align="center" prop="priceSetName" min-width="160">
<template #default="scope">
<el-tag v-if="scope.row.priceSetName" type="primary" size="small" :title="scope.row.priceSetName">
{{ scope.row.priceSetName }}
</el-tag>
<span v-else style="color: #909399;">未绑定</span>
</template>
</el-table-column>
<el-table-column v-if="isColVisible('remark')" label="备注说明" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="370" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['customersupplier:customerinfo:edit']">修改</el-button>
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['customersupplier:customerinfo:remove']">删除</el-button>-->
<el-button link type="primary" icon="Wallet" @click="handleCustomerMoney(scope.row)" v-hasPermi="['customersupplier:customerinfo:balance']">客户余额</el-button>
<el-button link type="primary" icon="Document" @click="handleViewBills(scope.row)" v-hasPermi="['customersupplier:customerinfo:bill']">账单</el-button>
<el-button link type="primary" icon="Document" @click="handleViewLog(scope.row)" v-hasPermi="['customersupplier:customerinfo:query']">日志</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 批量绑定套餐弹窗 -->
<el-dialog title="批量绑定套餐" v-model="batchDialog.visible" width="600px" append-to-body>
<el-alert type="info" :closable="false" show-icon style="margin-bottom: 14px;">
<template #title>
已选 {{ selectedRows.length }} 个客户,其中
<b :style="{ color: boundCount ? '#e6a23c' : '' }">{{ boundCount }}</b>
个已绑定套餐;一个客户只能绑定一个套餐。
</template>
</el-alert>
<div class="batch-customers">
<el-tag
v-for="c in selectedRows"
:key="c.customerId"
:type="c.priceSetId ? 'warning' : 'info'"
size="small"
class="batch-customer-tag"
:title="c.priceSetName ? ('已绑定:' + c.priceSetName) : ''"
>
{{ c.customerName }}<span v-if="c.priceSetName">({{ c.priceSetName }})</span>
</el-tag>
</div>
<el-form ref="batchFormRef" :model="batchForm" :rules="batchRules" label-width="92px" style="margin-top: 14px;">
<el-form-item label="价格套餐" prop="priceSetId">
<el-select v-model="batchForm.priceSetId" filterable placeholder="请选择生效中的套餐" style="width: 100%;">
<el-option
v-for="opt in priceSetOptions"
:key="opt.priceSetId"
:label="((opt.priceSetCode || '') + ' ' + opt.priceSetName).trim()"
:value="opt.priceSetId"
/>
</el-select>
</el-form-item>
<el-form-item label="优先级">
<el-input-number v-model="batchForm.bindPriority" :min="1" controls-position="right" style="width: 100%;" />
<div class="batch-tip">数字越小优先级越高,1 为最高</div>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="batchForm.priceSetNote" type="textarea" :rows="2" maxlength="100"
show-word-limit placeholder="绑定备注(选填)" />
</el-form-item>
<el-form-item v-if="boundCount > 0">
<el-checkbox v-model="batchForm.overwriteExisting">
覆盖已绑定套餐的客户(不勾选则跳过这 {{ boundCount }} 个客户)
</el-checkbox>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" :loading="batchDialog.loading" @click="submitBatchBind">确 定</el-button>
<el-button @click="batchDialog.visible = false">取 消</el-button>
</template>
</el-dialog>
<!-- 客户业务操作日志弹窗 -->
<customer-log-dialog
v-model="logOpen"
:customer-id="logCustomer.customerId"
:customer-name="logCustomer.customerName"
:customer-code="logCustomer.customerCode"
/>
<customer-bill-list-dialog
v-if="billDialogVisible"
:key="billCustomer.customerId"
v-model="billDialogVisible"
:customer-id="billCustomer.customerId"
:customer-name="billCustomer.customerName"
/>
<customer-unlinked-sales-dialog v-model="unlinkedSalesDialogVisible" />
<!-- 右键复制列值 -->
<table-copy-menu
ref="copyMenuRef"
:columns="copyColumns"
:selected-rows="selectedRows"
:visible-keys="visibleCopyKeys"
/>
</div>
</template>
<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 CustomerBillListDialog from './customermoney/CustomerBillListDialog.vue'
import CustomerUnlinkedSalesDialog from './components/CustomerUnlinkedSalesDialog.vue'
import { useColumnSettings } from '@/utils/columnSettings'
const { proxy } = getCurrentInstance()
/** 可自定义列(默认全部可见;选择列固定、操作列固定右侧不参与设置) */
const columnDefs = [
{ key: 'customerCode', label: '客户编码' },
{ key: 'customerName', label: '客户名称' },
{ key: 'customerCodeDw', label: '对外代码' },
{ key: 'creditCode', label: '统一社会信用代码' },
{ key: 'customerType', label: '业务类型' },
{ key: 'customerArea', label: '客户区域' },
{ key: 'isEnable', label: '启用状态' },
{ key: 'salesUserId', label: '业务员' },
// { key: 'ed', label: '资金额度' },
{ key: 'zq', label: '回款账期' },
{ key: 'settlementUserId', label: '结算员' },
{ key: 'serviceUserId', label: '客服' },
{ key: 'settlementType', label: '结算方式' },
{ key: 'tempEd', label: '临时额度' },
{ key: 'accountBalance', label: '账户余额(CNY)' },
{ key: 'weightThreshold', label: '重量阈值' },
{ key: 'throwRatio', label: '抛比' },
{ key: 'creditEd', label: '信用额度' },
{ key: 'contractStartDate', label: '合同开始时间' },
{ key: 'contractEndDate', label: '合同结束时间' },
{ key: 'productCodes', label: '绑定产品' },
{ key: 'priceSetName', label: '绑定套餐' },
{ key: 'remark', label: '备注说明' }
]
const { colVisible, isColVisible, toggleColumn, resetColumns } = useColumnSettings('customer-info-list', columnDefs)
const customerList = ref([])
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const { sys_normal_disable, settlement_type, customer_type, customer_area } = useDict("sys_normal_disable", "settlement_type", "customer_type", "customer_area")
/** 绑定产品代码串 -> 产品名称展示(产品代码+名称;查不到的产品回显原代码) */
const { ensureProducts, getProductLabel } = useProducts()
function productNames(productCodes) {
return parseProductCodes(productCodes).map(code => getProductLabel(code)).join(',')
}
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)
}
function formatDateOnly(value) {
if (!value) return ''
const s = String(value)
return s.length > 10 ? s.substring(0, 10) : s
}
/* ================= 右键复制列值 ================= */
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: 'customerArea', label: '客户区域', get: r => proxy.selectDictLabel(customer_area.value, r.customerArea) },
{ key: 'isEnable', label: '启用状态', get: r => proxy.selectDictLabel(sys_normal_disable.value, r.isEnable) },
{ key: 'salesUserId', label: '业务员', get: r => r.salesUserNickName || '' },
{ 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: 'contractStartDate', label: '合同开始时间', get: r => formatDateOnly(r.contractStartDate) },
{ key: 'contractEndDate', label: '合同结束时间', get: r => formatDateOnly(r.contractEndDate) },
{ 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,
pageSize: 10,
keywords: undefined,
creditCode: undefined,
customerType: undefined,
customerArea: undefined,
isEnable: undefined,
salesUserId: undefined,
salesUser: undefined,
ed: undefined,
zq: undefined,
settlementUserId: undefined,
settlementUser: undefined,
serviceUserId: undefined,
serviceUser: undefined,
settlementType: undefined,
tempEd: undefined,
accountBalance: undefined,
foreignCurrencyBalance: undefined,
weightThreshold: undefined,
throwRatio: undefined,
creditEd: undefined,
productCodes: undefined,
}
})
const { queryParams } = toRefs(data)
/** 查询客户主列表 */
function getList() {
copyMenuRef.value && copyMenuRef.value.close()
loading.value = true
listCustomer(queryParams.value).then(response => {
customerList.value = response.rows
total.value = response.total
loading.value = false
})
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
handleQuery()
}
/** 多选框选中数据 */
const selectedRows = ref([])
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.customerId)
selectedRows.value = selection
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 新增:跳转客户编辑页(页签式,无 customerId) */
function handleAdd() {
proxy.$router.push({ path: '/customersupplier/customer-edit/index' })
}
/** 修改:跳转客户编辑页(操作列传 row;工具栏按钮取勾选行) */
function handleUpdate(row) {
const target = (row && row.customerId) ? row : selectedRows.value[0]
if (!target || !target.customerId) {
proxy.$modal.msgWarning("请先勾选一个客户")
return
}
proxy.$router.push({
path: '/customersupplier/customer-edit/index',
query: {
customerId: target.customerId,
customerName: target.customerName,
customerCode: target.customerCode
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
const _customerIds = row.customerId || ids.value
proxy.$modal.confirm('是否确认删除客户编号为"' + _customerIds + '"的数据项?').then(function() {
return delCustomer(_customerIds)
}).then(() => {
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {})
}
/** 跳转客户余额页面(操作列传 row;工具栏按钮不传参时取勾选行) */
function handleCustomerMoney(row) {
const target = (row && row.customerId) ? row : selectedRows.value[0]
if (!target || !target.customerId) {
proxy.$modal.msgWarning("请先勾选一个客户")
return
}
proxy.$router.push({
path: '/customersupplier/customer-money/index',
query: {
customerId: target.customerId,
customerName: target.customerName,
customerCode: target.customerCode
}
})
}
/** 在客户信息列表内打开只读账单弹窗 */
const billDialogVisible = ref(false)
const billCustomer = ref({})
const unlinkedSalesDialogVisible = ref(false)
function handleViewBills(row) {
if (!row || !row.customerId) {
proxy.$modal.msgWarning('客户信息无效,无法查看账单')
return
}
billCustomer.value = {
customerId: row.customerId,
customerName: row.customerName || ''
}
billDialogVisible.value = true
}
/** ========== 批量绑定套餐 ========== */
const batchDialog = reactive({ visible: false, loading: false })
const batchFormRef = ref(null)
const priceSetOptions = ref([])
const batchForm = ref({})
const batchRules = {
priceSetId: [{ required: true, message: '请选择价格套餐', trigger: 'change' }]
}
/** 勾选客户中已绑定套餐的数量 */
const boundCount = computed(() => selectedRows.value.filter(r => r.priceSetId).length)
/** 打开批量绑定弹窗 */
function handleBatchBindPriceSet() {
if (!selectedRows.value.length) {
proxy.$modal.msgWarning('请先勾选要绑定套餐的客户')
return
}
batchForm.value = {
priceSetId: null,
bindPriority: 1,
priceSetNote: null,
overwriteExisting: false
}
batchDialog.visible = true
// 生效套餐选项只拉一次
if (!priceSetOptions.value.length) {
listPriceSetOption().then(res => { priceSetOptions.value = res.data || [] })
}
nextTick(() => batchFormRef.value && batchFormRef.value.clearValidate())
}
/** 提交批量绑定 */
function submitBatchBind() {
batchFormRef.value.validate(valid => {
if (!valid) return
const total = selectedRows.value.length
const bound = boundCount.value
const setName = (priceSetOptions.value.find(o => o.priceSetId === batchForm.value.priceSetId) || {}).priceSetName || ''
let confirmMsg = `确认将选中的 ${total} 个客户批量绑定套餐「${setName}」?`
if (bound > 0 && !batchForm.value.overwriteExisting) {
confirmMsg += `\n其中 ${bound} 个客户已绑定套餐,将自动跳过。`
} else if (bound > 0) {
confirmMsg += `\n其中 ${bound} 个客户已绑定套餐,将被更换为该套餐(原套餐失效)。`
}
proxy.$modal.confirm(confirmMsg).then(() => {
batchDialog.loading = true
return batchBindCustomerPriceSet({
customerIds: selectedRows.value.map(r => r.customerId),
priceSetId: batchForm.value.priceSetId,
bindPriority: batchForm.value.bindPriority,
priceSetNote: batchForm.value.priceSetNote,
overwriteExisting: batchForm.value.overwriteExisting
})
}).then(res => {
proxy.$modal.msgSuccess(res.msg || '批量绑定成功')
batchDialog.visible = false
getList()
}).catch(() => {}).finally(() => { batchDialog.loading = false })
})
}
/** 导出按钮操作 */
function handleExport() {
proxy.download('/customersupplier/customerinfo/export', {
...queryParams.value
}, `customer_${new Date().getTime()}.xlsx`)
}
/** ========== 客户业务操作日志 ========== */
const logOpen = ref(false)
const logCustomer = ref({})
/** 打开业务日志弹窗(操作列传 row;工具栏按钮取勾选行) */
function handleViewLog(row) {
const target = (row && row.customerId) ? row : selectedRows.value[0]
if (!target || !target.customerId) {
proxy.$modal.msgWarning("请先勾选一个客户")
return
}
logCustomer.value = { customerId: target.customerId, customerName: target.customerName, customerCode: target.customerCode }
logOpen.value = true
}
getList()
</script>
<style scoped>
.batch-customers {
max-height: 150px;
overflow-y: auto;
border: 1px solid var(--el-border-color-lighter);
border-radius: 4px;
padding: 8px 10px;
background: var(--el-fill-color-light);
}
.batch-customer-tag {
margin: 2px 4px 2px 0;
}
.batch-tip {
color: #909399;
font-size: 12px;
line-height: 1.4;
}
</style>