675 lines
27 KiB
Vue
675 lines
27 KiB
Vue
<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>
|