|
|
@@ -28,58 +28,66 @@
|
|
|
</el-form>
|
|
|
</el-card>
|
|
|
|
|
|
- <div class="title-container">
|
|
|
- <span class="list-title">拜访日程信息列表</span>
|
|
|
+ <!-- 列表标题 -->
|
|
|
+ <div class="filter-action-bar">
|
|
|
+ <div class="page-title">拜访日程信息列表</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 列表区域 -->
|
|
|
<el-card shadow="never" class="table-card">
|
|
|
- <el-table v-loading="loading" :data="dataList" border class="custom-table" :header-cell-style="{ background: '#f8fafc', color: '#333' }">
|
|
|
- <el-table-column label="日程编号" align="center" prop="scheduleNo" width="160">
|
|
|
+ <el-table v-loading="loading" :data="dataList" border class="standard-table">
|
|
|
+ <el-table-column label="记录编号" align="center" width="140" fixed>
|
|
|
<template #default="scope">
|
|
|
- <span class="link-text" @click="handleDetail(scope.row)">{{ scope.row.scheduleNo }}</span>
|
|
|
+ <span class="link-text-emphasize" @click="handleDetail(scope.row)">{{ scope.row.scheduleNo?.replace('RC', '') }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="关联计划" align="center" prop="planNo" width="160" />
|
|
|
- <el-table-column label="客户名称" align="center" prop="customerName" min-width="200" show-overflow-tooltip />
|
|
|
- <el-table-column label="拜访人" align="center" prop="callPeopleName" width="100">
|
|
|
+ <el-table-column label="客户名称" align="center" prop="customerName" min-width="250" show-overflow-tooltip />
|
|
|
+ <el-table-column label="部门" align="center" width="120">
|
|
|
<template #default="scope">
|
|
|
- <span>{{ staffOptions.find(s => String(s.staffId) === String(scope.row.callPeopleNo || scope.row.callPeopleName))?.staffName || scope.row.callPeopleName || '' }}</span>
|
|
|
+ <span>{{ findStaffDept(scope.row.callPeopleNo) || scope.row.deptName || scope.row.visitorDeptName || '' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="拜访日期" align="center" prop="callDate" width="120" >
|
|
|
+ <el-table-column label="行业" align="center" width="100">
|
|
|
<template #default="scope">
|
|
|
- <span>{{ parseTime(scope.row.callDate, '{y}-{m}-{d}') }}</span>
|
|
|
+ <span>{{ findCustomerAttr(scope.row.customerName, 'industry') || scope.row.profession || scope.row.industry || '' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="随访人" align="center" prop="followPeopleName" width="120" />
|
|
|
- <el-table-column label="关联对象" align="center" prop="objectName" width="180" show-overflow-tooltip>
|
|
|
+ <el-table-column label="业务员" align="center" width="100" show-overflow-tooltip>
|
|
|
<template #default="scope">
|
|
|
- <span>{{ scope.row.objectName || scope.row.customerName || '' }}</span>
|
|
|
+ <span>{{ findCustomerAttr(scope.row.customerName, 'salesman') || scope.row.salesman || scope.row.createByName || '' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="状态" align="center" prop="scheduleStatus" width="100">
|
|
|
+ <el-table-column label="对象类型" align="center" width="100">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ scope.row.relevanceType === '0' ? '客户' : (scope.row.relevanceType === '1' ? '项目商机' : '年度入围') }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="拜访对象" align="center" prop="objectName" width="160" show-overflow-tooltip />
|
|
|
+ <el-table-column label="拜访人" align="center" width="100">
|
|
|
<template #default="scope">
|
|
|
- <el-tag :type="String(scope.row.scheduleStatus) === '0' ? 'warning' : (String(scope.row.scheduleStatus) === '1' ? 'success' : 'danger')">
|
|
|
- {{ scheduleStatusOptions.find(d => String(d.value) === String(scope.row.scheduleStatus))?.label || (String(scope.row.scheduleStatus) === '0' ? '未执行' : (String(scope.row.scheduleStatus) === '1' ? '已执行' : '放弃执行')) }}
|
|
|
- </el-tag>
|
|
|
+ <span>{{ findStaffName(scope.row.callPeopleNo || scope.row.callPeopleName) }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="关联类型" align="center" prop="relevanceType" width="100">
|
|
|
+ <el-table-column label="随访人" align="center" width="100">
|
|
|
<template #default="scope">
|
|
|
- {{ relevanceOptions.find(d => String(d.value) === String(scope.row.relevanceType))?.label || (String(scope.row.relevanceType) === '0' ? '客户' : (String(scope.row.relevanceType) === '1' ? '项目' : '供应商')) }}
|
|
|
+ <span>{{ scope.row.followPeopleName || scope.row.followPeople || '' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="重要级别" align="center" prop="importantLevel" width="100">
|
|
|
+ <el-table-column label="拜访日期" align="center" prop="callDate" width="110">
|
|
|
<template #default="scope">
|
|
|
- <span>{{ importanceOptions.find(d => String(d.value) === String(scope.row.importantLevel))?.label || scope.row.importantLevel || '' }}</span>
|
|
|
+ <span>{{ parseTime(scope.row.callDate, '{y}-{m}-{d}') }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" align="center" width="180" fixed="right">
|
|
|
+ <el-table-column label="操作" align="center" width="120" fixed="right">
|
|
|
+ <template #header>
|
|
|
+ <div class="op-header">
|
|
|
+ <span>操作</span>
|
|
|
+ <el-icon class="setting-icon"><Setting /></el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
<template #default="scope">
|
|
|
- <el-button link type="primary" @click="handleDetail(scope.row)">详情</el-button>
|
|
|
- <el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['visit:routine:edit']">编辑</el-button>
|
|
|
- <el-button link type="danger" @click="handleDelete(scope.row)" v-hasPermi="['visit:routine:remove']">删除</el-button>
|
|
|
+ <el-button link class="op-btn" @click="handleDetail(scope.row)">详情</el-button>
|
|
|
+ <el-button link class="op-btn-danger" @click="handleDelete(scope.row)">删除</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
@@ -101,7 +109,10 @@
|
|
|
<script setup name="VisitRoutine">
|
|
|
import { ref, reactive, onMounted, getCurrentInstance, toRefs } from 'vue';
|
|
|
import { listRoutine, delRoutine } from "@/api/visit/routine";
|
|
|
-import { selectStaffOptionList } from "@/api/customer/crmStaff";
|
|
|
+import { listComStaff } from "@/api/system/comStaff/index";
|
|
|
+import { listIndustryCategory } from "@/api/customer/industryCategory";
|
|
|
+import { listCustomerInfo } from "@/api/customer/customerInfo/index";
|
|
|
+import { Setting } from '@element-plus/icons-vue';
|
|
|
import AddRoutine from './add.vue';
|
|
|
import EditRoutine from './edit.vue';
|
|
|
import DetailRoutine from './detail.vue';
|
|
|
@@ -114,6 +125,8 @@ const {
|
|
|
} = toRefs(reactive(proxy.useDict("importance_level", "schedule_status", "relevance_type")));
|
|
|
|
|
|
const staffOptions = ref([]);
|
|
|
+const industryOptions = ref([]);
|
|
|
+const customerList = ref([]);
|
|
|
|
|
|
const queryRef = ref(null);
|
|
|
const loading = ref(false);
|
|
|
@@ -146,6 +159,35 @@ const getList = () => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+const findStaffName = (val) => {
|
|
|
+ if (!val) return '';
|
|
|
+ const staff = staffOptions.value.find(s => String(s.staffId) === String(val) || String(s.userId) === String(val) || String(s.staffName) === String(val));
|
|
|
+ return staff ? staff.staffName : val;
|
|
|
+};
|
|
|
+
|
|
|
+const findStaffDept = (val) => {
|
|
|
+ if (!val) return '';
|
|
|
+ const staff = staffOptions.value.find(s => String(s.staffId) === String(val) || String(s.userId) === String(val) || String(s.staffName) === String(val));
|
|
|
+ return staff ? staff.deptName : '';
|
|
|
+};
|
|
|
+
|
|
|
+// 通过客户名称反查行业和业务员
|
|
|
+const findCustomerAttr = (customerName, attr) => {
|
|
|
+ if (!customerName) return '';
|
|
|
+ const customer = customerList.value.find(c => c.customerName === customerName);
|
|
|
+ if (!customer) return '';
|
|
|
+
|
|
|
+ if (attr === 'industry') {
|
|
|
+ const indId = customer.profession || customer.industry;
|
|
|
+ const ind = industryOptions.value.find(o => String(o.id) === String(indId));
|
|
|
+ return ind ? ind.industryCategoryName : (indId || '');
|
|
|
+ }
|
|
|
+ if (attr === 'salesman') {
|
|
|
+ return customer.leaderName || customer.salesman || '';
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+};
|
|
|
+
|
|
|
const handleQuery = () => {
|
|
|
queryParams.pageNum = 1;
|
|
|
getList();
|
|
|
@@ -184,7 +226,9 @@ const handleDelete = (row) => {
|
|
|
};
|
|
|
|
|
|
const getOptions = () => {
|
|
|
- selectStaffOptionList().then(res => { staffOptions.value = res.data || []; });
|
|
|
+ listComStaff({ pageSize: 1000 }).then(res => { staffOptions.value = res.rows || res.data || []; });
|
|
|
+ listIndustryCategory({ pageSize: 1000 }).then(res => { industryOptions.value = res.rows || []; });
|
|
|
+ listCustomerInfo({ pageSize: 1000 }).then(res => { customerList.value = res.rows || []; });
|
|
|
};
|
|
|
|
|
|
onMounted(() => {
|
|
|
@@ -259,4 +303,26 @@ onMounted(() => {
|
|
|
}
|
|
|
|
|
|
.link-text { color: #409eff; cursor: pointer; }
|
|
|
+.link-text-emphasize { color: #e6a23c; cursor: pointer; } /* 橙色强调 */
|
|
|
+
|
|
|
+.op-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 4px;
|
|
|
+ .setting-icon { font-size: 14px; cursor: pointer; color: #909399; }
|
|
|
+}
|
|
|
+
|
|
|
+.op-btn {
|
|
|
+ color: #409eff;
|
|
|
+ font-weight: normal;
|
|
|
+ &:hover { opacity: 0.8; }
|
|
|
+}
|
|
|
+
|
|
|
+.op-btn-danger {
|
|
|
+ color: #f56c6c;
|
|
|
+ font-weight: normal;
|
|
|
+ margin-left: 12px;
|
|
|
+ &:hover { opacity: 0.8; }
|
|
|
+}
|
|
|
</style>
|