feat(crm): 添加销售员详情页数据加载功能

- 新增按销售员查询订单明细卷的API接口
- 为CoilTable和DeliveryTable组件添加高度属性
- 实现销售员详情页各标签页数据懒加载功能
- 优化销售员卡片点击和标签页切换时的数据加载逻辑
This commit is contained in:
2026-04-27 18:14:54 +08:00
parent dc170c77d9
commit b85971d532
4 changed files with 185 additions and 56 deletions

View File

@@ -59,4 +59,15 @@ export function listBoundCoil(query) {
method: 'get',
params: query
})
}
// 按销售员查询订单明细的卷
export function listDeliveryWaybillDetailBySaleman(principal) {
return request({
url: '/wms/deliveryWaybillDetail/coilListByPrincipal',
method: 'get',
params: {
principal: principal
}
})
}

View File

@@ -5,7 +5,7 @@
<span style="margin-right: 20px;"><strong>总卷数{{ totalCoils }}</strong></span>
<span><strong>总净重{{ totalNetWeight }} kg</strong></span>
</div>
<KLPTable :data="data" :floatLayer="true" :floatLayerConfig="floatLayerConfig">
<KLPTable :data="data" :floatLayer="true" :floatLayerConfig="floatLayerConfig" :height="tableHeight">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.enterCoilNo"></coil-no>
@@ -84,6 +84,10 @@ export default {
data: {
type: Array,
default: () => []
},
tableHeight: {
type: [String, Number],
default: ''
}
},
components: {

View File

@@ -4,7 +4,7 @@
<span style="margin-right: 20px;"><strong>已发货{{ deliveryCountFinished }}</strong></span>
<span><strong>总单据数{{ deliveryCountTotal }}</strong></span>
</div>
<el-table border :data="data" highlight-current-row>
<el-table border :data="data" highlight-current-row :height="tableHeight">
<el-table-column label="发货单唯一ID" align="center" prop="waybillId" v-if="false" />
<el-table-column label="发货单名称" align="center" prop="waybillName" />
<el-table-column label="车牌" align="center" prop="licensePlate" width="100" />
@@ -43,6 +43,10 @@ export default {
data: {
type: Array,
default: () => []
},
tableHeight: {
type: [String, Number],
default: ''
}
},

View File

@@ -27,11 +27,9 @@
</el-row>
<div v-loading="loading" class="card-container">
<div v-for="item in dataList" :key="item.dictCode"
class="saleman-card"
:class="{ 'saleman-card-selected': selectedItem && selectedItem.dictCode === item.dictCode }"
@click="selectedItem = item"
shadow="hover">
<div v-for="item in dataList" :key="item.dictCode" class="saleman-card"
:class="{ 'saleman-card-selected': selectedItem && selectedItem.dictCode === item.dictCode }"
@click="handleSelect(item)" shadow="hover">
<div class="card-header">
<div class="card-title">
<dict-tag :options="dict.type.sys_normal_disable" :value="item.status" />
@@ -39,7 +37,8 @@
</div>
<div class="card-actions">
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(item)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(item)">删除</el-button>
<el-button size="mini" type="text" icon="el-icon-delete"
@click.stop="handleDelete(item)">删除</el-button>
</div>
</div>
</div>
@@ -52,21 +51,35 @@
</template>
<template #panelB>
<div v-if="selectedItem" class="right-panel">
<el-tabs v-model="activeTab" type="border-card">
<el-tabs v-model="activeTab" type="border-card" v-loading="rightLoading" @tab-click="handleTabClick">
<el-tab-pane label="跟进客户" name="customer">
客户
<el-table :data="customerList" style="width: 100%" height="calc(100vh - 200px)">
<el-table-column prop="companyName" label="公司名称" />
<el-table-column prop="contactWay" label="联系方式" />
<el-table-column prop="taxNumber" label="税号" />
<el-table-column prop="industry" label="行业" />
<el-table-column prop="customerLevel" label="客户等级" />
<el-table-column prop="address" label="地址" />
</el-table>
</el-tab-pane>
<el-tab-pane label="跟进合同" name="contract">
合同
<el-table :data="orderList" style="width: 100%" height="calc(100vh - 200px)">
<el-table-column prop="orderCode" label="合同编号"/>
<el-table-column prop="customer" label="客户名称" />
<el-table-column prop="orderAmount" label="合同总额" />
<el-table-column prop="signTime" label="签订时间" />
<el-table-column prop="deliveryDate" label="交货日期" />
<el-table-column prop="signLocation" label="签订地点" />
</el-table>
</el-tab-pane>
<el-tab-pane label="发货单据" name="delivery">
<DeliveryTable :data="waybillList" />
<DeliveryTable :data="waybillList" table-height="calc(100vh - 240px)" />
</el-tab-pane>
<el-tab-pane label="生产成果" name="production">
<CoilTable :data="productList || []" />
<CoilTable :data="productList || []" table-height="calc(100vh - 240px)" />
</el-tab-pane>
<el-tab-pane label="计划发货" name="planDelivery">
<CoilTable :data="deliveryList || []" />
<CoilTable :data="deliveryList || []" table-height="calc(100vh - 240px)" />
</el-tab-pane>
</el-tabs>
</div>
@@ -85,7 +98,7 @@
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label
}}</el-radio>
}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
@@ -107,6 +120,11 @@ import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/
import CoilTable from "../components/CoilTable.vue";
import DeliveryTable from "../components/DeliveryTable.vue";
import { listDeliveryWaybill } from "@/api/wms/deliveryWaybill";
import { listCustomer } from "@/api/crm/customer";
import { listOrder } from "@/api/crm/order";
import { listDeliveryWaybillDetailBySaleman } from "@/api/wms/deliveryWaybillDetail";
export default {
name: "Data",
components: { DragResizePanel, CoilTable, DeliveryTable },
@@ -135,33 +153,6 @@ export default {
open: false,
// 当前选中的销售员
selectedItem: null,
// 数据标签回显样式
listClassOptions: [
{
value: "default",
label: "默认"
},
{
value: "primary",
label: "主要"
},
{
value: "success",
label: "成功"
},
{
value: "info",
label: "信息"
},
{
value: "warning",
label: "警告"
},
{
value: "danger",
label: "危险"
}
],
// 类型数据销售员
typeOptions: [],
// 查询参数
@@ -182,6 +173,14 @@ export default {
deliveryList: [],
// 发货单据列表
waybillList: [],
// 跟进客户列表
customerList: [],
// 跟进合同列表
orderList: [],
// 原始订单数据缓存
rawOrderList: [],
// 已加载的数据标识
loadedTabs: {},
// 表单校验
rules: {
dictLabel: [
@@ -193,7 +192,8 @@ export default {
dictSort: [
{ required: true, message: "数据顺序不能为空", trigger: "blur" }
],
}
},
rightLoading: false
};
},
created() {
@@ -226,6 +226,128 @@ export default {
this.loading = false;
});
},
handleSelect(row) {
if (this.rightLoading) {
this.$message({
message: '请等待当前数据加载完成',
type: 'warning'
});
return;
}
this.rightLoading = true;
this.selectedItem = row;
this.loadedTabs = {};
// 只加载当前激活tab的数据
this.loadTabData(this.activeTab, row.dictValue)
},
handleTabClick(tab) {
if (!this.selectedItem) return;
this.loadTabData(tab.name, this.selectedItem.dictValue);
},
loadTabData(tabName, dictValue) {
if (this.loadedTabs[tabName]) {
return Promise.resolve();
}
this.rightLoading = true;
switch (tabName) {
case 'customer':
return listCustomer({
contactPerson: dictValue,
pageNum: 1,
pageSize: 10000
}).then(response => {
this.customerList = response.rows;
this.loadedTabs.customer = true;
this.rightLoading = false;
}).catch(() => {
this.rightLoading = false;
});
case 'contract':
return listOrder({
salesman: dictValue,
pageNum: 1,
pageSize: 10000
}).then(response => {
this.rawOrderList = response.rows;
this.orderList = response.rows;
this.loadedTabs.contract = true;
this.rightLoading = false;
}).catch(() => {
this.rightLoading = false;
});
case 'delivery':
return listDeliveryWaybill({
principal: dictValue,
pageNum: 1,
pageSize: 10000
}).then(response => {
this.waybillList = response.rows;
this.loadedTabs.delivery = true;
this.rightLoading = false;
}).catch(() => {
this.rightLoading = false;
});
case 'production':
// 生产成果和contract使用同一个api获取数据
if (this.loadedTabs.contract) {
// 合同数据已加载,直接处理
this.processProductionData();
return Promise.resolve();
} else {
// 合同数据未加载,先请求合同数据
return listOrder({
salesman: dictValue,
pageNum: 1,
pageSize: 10000
}).then(response => {
this.rawOrderList = response.rows;
this.orderList = response.rows;
this.loadedTabs.contract = true;
this.processProductionData();
}).catch(() => {
this.rightLoading = false;
});
}
case 'planDelivery':
return listDeliveryWaybillDetailBySaleman(dictValue).then(response => {
this.deliveryList = response;
this.loadedTabs.planDelivery = true;
this.rightLoading = false;
}).catch(() => {
this.rightLoading = false;
});
default:
this.rightLoading = false;
return Promise.resolve();
}
},
processProductionData() {
// 扁平化处理所有合同下的生产成果(coilList)
const allCoils = [];
this.rawOrderList.forEach(order => {
if (order.coilList && Array.isArray(order.coilList)) {
allCoils.push(...order.coilList);
}
});
this.productList = allCoils;
this.loadedTabs.production = true;
this.rightLoading = false;
},
processPlanDeliveryData() {
// 扁平化处理所有合同下的计划发货数据
const allDeliveryCoils = [];
this.rawOrderList.forEach(order => {
if (order.coilList && Array.isArray(order.coilList)) {
// 可以根据需要过滤未发货的钢卷
const deliveryCoils = order.coilList.filter(coil => coil.status !== 1);
allDeliveryCoils.push(...deliveryCoils);
}
});
this.deliveryList = allDeliveryCoils;
this.loadedTabs.planDelivery = true;
this.rightLoading = false;
},
// 取消按钮
cancel() {
this.open = false;
@@ -267,12 +389,6 @@ export default {
this.title = "添加销售员数据";
this.form.dictType = this.queryParams.dictType;
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.dictCode)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
@@ -284,7 +400,7 @@ export default {
});
},
/** 提交按钮 */
submitForm () {
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
// 确保dictLabel和dictValue保持一致
@@ -318,12 +434,6 @@ export default {
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
}).catch(() => { });
},
/** 导出按钮操作 */
handleExport() {
this.download('system/dict/data/export', {
...this.queryParams
}, `data_${new Date().getTime()}.xlsx`)
},
}
};
</script>