|
@@ -1,7 +1,7 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="app-container">
|
|
<div class="app-container">
|
|
|
<el-card shadow="never" class="search-card">
|
|
<el-card shadow="never" class="search-card">
|
|
|
- <el-form :model="queryParams" ref="queryRef" label-width="100px">
|
|
|
|
|
|
|
+ <el-form :model="queryParams" ref="queryRef" label-width="85px">
|
|
|
<!-- 第一行 -->
|
|
<!-- 第一行 -->
|
|
|
<el-row :gutter="24">
|
|
<el-row :gutter="24">
|
|
|
<el-col :span="6">
|
|
<el-col :span="6">
|
|
@@ -88,26 +88,30 @@
|
|
|
</el-row>
|
|
</el-row>
|
|
|
|
|
|
|
|
<!-- 第三行 -->
|
|
<!-- 第三行 -->
|
|
|
- <el-row :gutter="24" style="margin-top: 10px;">
|
|
|
|
|
|
|
+ <el-row :gutter="24" style="margin-top: 5px;">
|
|
|
<el-col :span="6">
|
|
<el-col :span="6">
|
|
|
<el-form-item label="时间范围" prop="dateRange">
|
|
<el-form-item label="时间范围" prop="dateRange">
|
|
|
<el-date-picker v-model="dateRange" type="daterange" range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间" style="width: 100%" />
|
|
<el-date-picker v-model="dateRange" type="daterange" range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间" style="width: 100%" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="18">
|
|
<el-col :span="18">
|
|
|
- <div class="search-btns" style="padding-left: 10px;">
|
|
|
|
|
- <el-button type="default" icon="Search" @click="handleQuery">搜索</el-button>
|
|
|
|
|
- <el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
|
|
|
- <el-button type="primary" icon="Plus" @click="handleAdd" class="btn-new">新增</el-button>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <el-form-item label-width="0">
|
|
|
|
|
+ <div class="search-btns">
|
|
|
|
|
+ <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
|
|
|
|
+ <el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
|
|
|
+ <el-button type="primary" icon="Plus" @click="handleAdd" class="btn-new">新增</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
</el-card>
|
|
</el-card>
|
|
|
|
|
|
|
|
<div class="summary-stripe">
|
|
<div class="summary-stripe">
|
|
|
- <span class="stripe-title">销售线索信息列表</span>
|
|
|
|
|
- <span class="stripe-total">金额总计<span class="red-text">{{ totalAmount.toFixed(2) }}</span> (万)</span>
|
|
|
|
|
|
|
+ <div class="stripe-left">
|
|
|
|
|
+ <span class="stripe-title">销售线索信息列表</span>
|
|
|
|
|
+ <span class="stripe-total"><span class="total-label">金额总计</span><span class="red-text">{{ totalAmount.toFixed(2) }}</span> (万)</span>
|
|
|
|
|
+ </div>
|
|
|
<div class="stripe-actions">
|
|
<div class="stripe-actions">
|
|
|
<el-button type="primary" size="small" :disabled="multipleSelection.length === 0" icon="Switch" @click="handleTransfer">转移给他人</el-button>
|
|
<el-button type="primary" size="small" :disabled="multipleSelection.length === 0" icon="Switch" @click="handleTransfer">转移给他人</el-button>
|
|
|
<el-button type="primary" size="small" :disabled="multipleSelection.length === 0" icon="Link" @click="handleBatchClaim">批量认领</el-button>
|
|
<el-button type="primary" size="small" :disabled="multipleSelection.length === 0" icon="Link" @click="handleBatchClaim">批量认领</el-button>
|
|
@@ -126,12 +130,12 @@
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="客户名称" align="center" prop="customerName" min-width="200" show-overflow-tooltip />
|
|
<el-table-column label="客户名称" align="center" prop="customerName" min-width="200" show-overflow-tooltip />
|
|
|
- <el-table-column label="行业" align="center" width="150">
|
|
|
|
|
|
|
+ <el-table-column label="行业" align="center" width="150" show-overflow-tooltip>
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
{{ industryOptions.find(i => i.id == scope.row.profession)?.industryCategoryName || scope.row.profession }}
|
|
{{ industryOptions.find(i => i.id == scope.row.profession)?.industryCategoryName || scope.row.profession }}
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="部门" align="center" min-width="150">
|
|
|
|
|
|
|
+ <el-table-column label="部门" align="center" min-width="150" show-overflow-tooltip>
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
{{ findDeptName(scope.row.deptNo) || scope.row.deptNo }}
|
|
{{ findDeptName(scope.row.deptNo) || scope.row.deptNo }}
|
|
|
</template>
|
|
</template>
|
|
@@ -146,13 +150,13 @@
|
|
|
<span>{{ scope.row.winRate }}%</span>
|
|
<span>{{ scope.row.winRate }}%</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="项目级别" align="center" width="120">
|
|
|
|
|
|
|
+ <el-table-column label="项目级别" align="center" width="120" show-overflow-tooltip>
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
{{ findProjectLevelName(scope.row.projectLevel) }}
|
|
{{ findProjectLevelName(scope.row.projectLevel) }}
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="项目负责人" align="center" prop="leaderName" width="120" />
|
|
|
|
|
- <el-table-column label="产品支持" align="center" prop="productSupport" width="100" />
|
|
|
|
|
|
|
+ <el-table-column label="项目负责人" align="center" prop="leaderName" width="120" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column label="产品支持" align="center" prop="productSupport" width="100" show-overflow-tooltip />
|
|
|
<el-table-column label="创建时间" align="center" prop="createTime" width="120" sortable>
|
|
<el-table-column label="创建时间" align="center" prop="createTime" width="120" sortable>
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
|
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
|
@@ -273,7 +277,7 @@
|
|
|
|
|
|
|
|
<div class="drawer-body-standard">
|
|
<div class="drawer-body-standard">
|
|
|
<el-form :model="projectContactForm" :rules="projectContactRules" ref="projectContactFormRef" label-width="100px" label-position="right">
|
|
<el-form :model="projectContactForm" :rules="projectContactRules" ref="projectContactFormRef" label-width="100px" label-position="right">
|
|
|
- <div class="section-title">基本信息</div>
|
|
|
|
|
|
|
+ <div class="section-title"><span>基本信息</span></div>
|
|
|
<el-row :gutter="32">
|
|
<el-row :gutter="32">
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
<el-form-item label="姓名" prop="name" required>
|
|
<el-form-item label="姓名" prop="name" required>
|
|
@@ -426,19 +430,19 @@
|
|
|
class="leads-drawer"
|
|
class="leads-drawer"
|
|
|
:with-header="false"
|
|
:with-header="false"
|
|
|
>
|
|
>
|
|
|
- <div class="drawer-header">
|
|
|
|
|
- <div class="header-title">
|
|
|
|
|
- <span class="main-title">销售线索</span>
|
|
|
|
|
- <span class="sub-title">(3个月以上出结果或金额不明确的项目信息,计入:销售线索)</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <el-button link icon="Close" @click="cancelForm" class="close-btn"></el-button>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
<div class="drawer-content">
|
|
<div class="drawer-content">
|
|
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="110px" label-position="left">
|
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="110px" label-position="left">
|
|
|
|
|
+ <div class="drawer-header">
|
|
|
|
|
+ <div class="header-title">
|
|
|
|
|
+ <span class="main-title">销售线索</span>
|
|
|
|
|
+ <span class="sub-title">(3个月以上出结果或金额不明确的项目信息,计入:销售线索)</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-button link icon="Close" @click="cancelForm" class="close-btn"></el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<!-- 基本信息 -->
|
|
<!-- 基本信息 -->
|
|
|
<div class="form-section">
|
|
<div class="form-section">
|
|
|
- <div class="section-title">基本信息</div>
|
|
|
|
|
|
|
+ <div class="section-title"><span>基本信息</span></div>
|
|
|
<el-row :gutter="30">
|
|
<el-row :gutter="30">
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="归属公司" prop="companyNo">
|
|
<el-form-item label="归属公司" prop="companyNo">
|
|
@@ -479,35 +483,35 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="项目名称" prop="projectName" required>
|
|
|
|
|
|
|
+ <el-form-item label="项目名称" prop="projectName">
|
|
|
<el-input v-model="form.projectName" placeholder="请输入" />
|
|
<el-input v-model="form.projectName" placeholder="请输入" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="30">
|
|
<el-row :gutter="30">
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
- <el-form-item label="金额(万)" prop="projectBudget" required>
|
|
|
|
|
|
|
+ <el-form-item label="金额(万)" prop="projectBudget">
|
|
|
<el-input v-model="form.projectBudget" placeholder="请输入" type="number">
|
|
<el-input v-model="form.projectBudget" placeholder="请输入" type="number">
|
|
|
<template #append>万</template>
|
|
<template #append>万</template>
|
|
|
</el-input>
|
|
</el-input>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
- <el-form-item label="赢单率(%)" prop="winRate" required>
|
|
|
|
|
|
|
+ <el-form-item label="赢单率(%)" prop="winRate">
|
|
|
<el-input v-model="form.winRate" placeholder="请输入" type="number">
|
|
<el-input v-model="form.winRate" placeholder="请输入" type="number">
|
|
|
<template #append>%</template>
|
|
<template #append>%</template>
|
|
|
</el-input>
|
|
</el-input>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
- <el-form-item label="立项时间" prop="expectedCompletionTime" required>
|
|
|
|
|
|
|
+ <el-form-item label="立项时间" prop="expectedCompletionTime">
|
|
|
<el-date-picker v-model="form.expectedCompletionTime" type="date" placeholder="请选择" style="width: 100%" />
|
|
<el-date-picker v-model="form.expectedCompletionTime" type="date" placeholder="请选择" style="width: 100%" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="30">
|
|
<el-row :gutter="30">
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="成交时间" prop="approvalDate">
|
|
|
|
|
|
|
+ <el-form-item label="成单时间" prop="approvalDate">
|
|
|
<el-date-picker v-model="form.approvalDate" type="date" placeholder="请选择" style="width: 100%" />
|
|
<el-date-picker v-model="form.approvalDate" type="date" placeholder="请选择" style="width: 100%" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
@@ -523,7 +527,7 @@
|
|
|
|
|
|
|
|
<!-- 项目信息 -->
|
|
<!-- 项目信息 -->
|
|
|
<div class="form-section">
|
|
<div class="form-section">
|
|
|
- <div class="section-title">项目信息</div>
|
|
|
|
|
|
|
+ <div class="section-title"><span>项目信息</span></div>
|
|
|
<el-row :gutter="30">
|
|
<el-row :gutter="30">
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
<el-form-item label="项目级别" prop="projectLevel">
|
|
<el-form-item label="项目级别" prop="projectLevel">
|
|
@@ -538,7 +542,7 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
- <el-form-item label="项目区域" prop="projectArea" required>
|
|
|
|
|
|
|
+ <el-form-item label="项目区域" prop="projectArea">
|
|
|
<el-input v-model="form.projectArea" placeholder="请输入" />
|
|
<el-input v-model="form.projectArea" placeholder="请输入" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
@@ -571,14 +575,14 @@
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="30">
|
|
<el-row :gutter="30">
|
|
|
<el-col :span="24">
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="采购内容" prop="purchaseContent" required>
|
|
|
|
|
|
|
+ <el-form-item label="采购内容" prop="purchaseContent">
|
|
|
<el-input v-model="form.purchaseContent" type="textarea" :rows="3" placeholder="请输入采购内容" />
|
|
<el-input v-model="form.purchaseContent" type="textarea" :rows="3" placeholder="请输入采购内容" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="30">
|
|
<el-row :gutter="30">
|
|
|
<el-col :span="24">
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="项目描述" prop="projectDescription" required>
|
|
|
|
|
|
|
+ <el-form-item label="项目描述" prop="projectDescription">
|
|
|
<el-input v-model="form.projectDescription" type="textarea" :rows="3" placeholder="请输入项目描述" />
|
|
<el-input v-model="form.projectDescription" type="textarea" :rows="3" placeholder="请输入项目描述" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
@@ -586,7 +590,7 @@
|
|
|
<el-row :gutter="30">
|
|
<el-row :gutter="30">
|
|
|
<el-col :span="24">
|
|
<el-col :span="24">
|
|
|
<el-form-item label="竞争对手" prop="competitor">
|
|
<el-form-item label="竞争对手" prop="competitor">
|
|
|
- <el-input v-model="form.competitor" type="textarea" :rows="2" placeholder="请输入竞争对手" />
|
|
|
|
|
|
|
+ <el-input v-model="form.competitor" placeholder="请输入竞争对手" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
@@ -1232,11 +1236,11 @@ const formatLogTarget = (log) => {
|
|
|
return log.targetObject;
|
|
return log.targetObject;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const fetchOperationLogs = async (id) => {
|
|
|
|
|
- if (!id) return;
|
|
|
|
|
|
|
+const fetchOperationLogs = async (projectNo) => {
|
|
|
|
|
+ if (!projectNo) return;
|
|
|
logLoading.value = true;
|
|
logLoading.value = true;
|
|
|
try {
|
|
try {
|
|
|
- const res = await listOperationLog({ dataType: 1, objectNo: id });
|
|
|
|
|
|
|
+ const res = await listOperationLog({ dataType: 1, objectNo: projectNo });
|
|
|
logList.value = res.data || [];
|
|
logList.value = res.data || [];
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
} finally {
|
|
} finally {
|
|
@@ -1575,7 +1579,10 @@ const rules = reactive({
|
|
|
projectBudget: [{ required: true, message: '金额不能为空', trigger: 'blur' }],
|
|
projectBudget: [{ required: true, message: '金额不能为空', trigger: 'blur' }],
|
|
|
winRate: [{ required: true, message: '赢单率不能为空', trigger: 'blur' }],
|
|
winRate: [{ required: true, message: '赢单率不能为空', trigger: 'blur' }],
|
|
|
expectedCompletionTime: [{ required: true, message: '立项时间不能为空', trigger: 'change' }],
|
|
expectedCompletionTime: [{ required: true, message: '立项时间不能为空', trigger: 'change' }],
|
|
|
|
|
+ projectLevel: [{ required: true, message: '项目级别不能为空', trigger: 'change' }],
|
|
|
projectArea: [{ required: true, message: '项目区域不能为空', trigger: 'blur' }],
|
|
projectArea: [{ required: true, message: '项目区域不能为空', trigger: 'blur' }],
|
|
|
|
|
+ procurementMethod: [{ required: true, message: '采购方式不能为空', trigger: 'change' }],
|
|
|
|
|
+ infoSource: [{ required: true, message: '信息来源不能为空', trigger: 'change' }],
|
|
|
purchaseContent: [{ required: true, message: '采购内容不能为空', trigger: 'blur' }],
|
|
purchaseContent: [{ required: true, message: '采购内容不能为空', trigger: 'blur' }],
|
|
|
projectDescription: [{ required: true, message: '项目描述不能为空', trigger: 'blur' }],
|
|
projectDescription: [{ required: true, message: '项目描述不能为空', trigger: 'blur' }],
|
|
|
});
|
|
});
|
|
@@ -1589,8 +1596,8 @@ const queryParams = reactive({
|
|
|
leader: undefined,
|
|
leader: undefined,
|
|
|
deptNo: undefined,
|
|
deptNo: undefined,
|
|
|
productSupport: undefined,
|
|
productSupport: undefined,
|
|
|
- status: undefined,
|
|
|
|
|
- timeType: undefined
|
|
|
|
|
|
|
+ status: '1',
|
|
|
|
|
+ timeType: '1'
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const transferForm = reactive({
|
|
const transferForm = reactive({
|
|
@@ -1602,6 +1609,8 @@ const claimForm = reactive({
|
|
|
newManager: '',
|
|
newManager: '',
|
|
|
keepOldManager: true
|
|
keepOldManager: true
|
|
|
});
|
|
});
|
|
|
|
|
+// 单条认领时暂存行数据,批量认领时为 null
|
|
|
|
|
+const claimSingleRow = ref(null);
|
|
|
|
|
|
|
|
const getList = async () => {
|
|
const getList = async () => {
|
|
|
loading.value = true;
|
|
loading.value = true;
|
|
@@ -1645,18 +1654,20 @@ const handleTransfer = () => {
|
|
|
transferVisible.value = true;
|
|
transferVisible.value = true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/** 单条认领 */
|
|
|
|
|
-const handleClaim = async (row) => {
|
|
|
|
|
- try {
|
|
|
|
|
- await claimLeads({
|
|
|
|
|
- ids: [row.id],
|
|
|
|
|
- leader: userStore.userId,
|
|
|
|
|
- leaderName: userStore.nickname
|
|
|
|
|
- });
|
|
|
|
|
- proxy.$modal.msgSuccess("认领成功");
|
|
|
|
|
- getList();
|
|
|
|
|
- } catch (e) {
|
|
|
|
|
- }
|
|
|
|
|
|
|
+/** 获取当前用户在 userOptions 中对应的 staffId */
|
|
|
|
|
+const getCurrentUserStaffId = () => {
|
|
|
|
|
+ const currentUser = userOptions.value.find(
|
|
|
|
|
+ u => String(u.staffId) === String(userStore.userId) || String(u.userId) === String(userStore.userId)
|
|
|
|
|
+ );
|
|
|
|
|
+ return currentUser ? currentUser.staffId : undefined;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/** 单条认领 - 弹出认领弹窗 */
|
|
|
|
|
+const handleClaim = (row) => {
|
|
|
|
|
+ claimSingleRow.value = row;
|
|
|
|
|
+ claimForm.newManager = getCurrentUserStaffId();
|
|
|
|
|
+ claimForm.keepOldManager = true;
|
|
|
|
|
+ claimVisible.value = true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleBatchClaim = () => {
|
|
const handleBatchClaim = () => {
|
|
@@ -1664,6 +1675,9 @@ const handleBatchClaim = () => {
|
|
|
proxy.$modal.msgWarning("请先选择要认领的线索");
|
|
proxy.$modal.msgWarning("请先选择要认领的线索");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
+ claimSingleRow.value = null; // 批量认领模式
|
|
|
|
|
+ claimForm.newManager = getCurrentUserStaffId();
|
|
|
|
|
+ claimForm.keepOldManager = true;
|
|
|
claimVisible.value = true;
|
|
claimVisible.value = true;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -1690,19 +1704,27 @@ const submitClaim = async () => {
|
|
|
proxy.$modal.msgWarning("请选择项目负责人");
|
|
proxy.$modal.msgWarning("请选择项目负责人");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- const ids = multipleSelection.value.map(item => item.id);
|
|
|
|
|
|
|
+ // 判断是单条认领还是批量认领
|
|
|
|
|
+ const rows = claimSingleRow.value
|
|
|
|
|
+ ? [claimSingleRow.value]
|
|
|
|
|
+ : multipleSelection.value;
|
|
|
// 根据用户ID查找用户名称
|
|
// 根据用户ID查找用户名称
|
|
|
const managerUser = userOptions.value.find(u => u.staffId == claimForm.newManager || u.userId == claimForm.newManager);
|
|
const managerUser = userOptions.value.find(u => u.staffId == claimForm.newManager || u.userId == claimForm.newManager);
|
|
|
const leaderName = managerUser ? managerUser.staffName : '';
|
|
const leaderName = managerUser ? managerUser.staffName : '';
|
|
|
try {
|
|
try {
|
|
|
- await claimLeads({
|
|
|
|
|
- ids,
|
|
|
|
|
- leader: claimForm.newManager,
|
|
|
|
|
- leaderName: leaderName
|
|
|
|
|
|
|
+ // 逐条修改项目负责人
|
|
|
|
|
+ const promises = rows.map(row => {
|
|
|
|
|
+ return updateLeads({
|
|
|
|
|
+ id: row.id,
|
|
|
|
|
+ leader: claimForm.newManager,
|
|
|
|
|
+ leaderName: leaderName
|
|
|
|
|
+ });
|
|
|
});
|
|
});
|
|
|
- proxy.$modal.msgSuccess("认领成功,线索已转为项目商机");
|
|
|
|
|
|
|
+ await Promise.all(promises);
|
|
|
|
|
+ proxy.$modal.msgSuccess("认领成功");
|
|
|
claimVisible.value = false;
|
|
claimVisible.value = false;
|
|
|
- getList(); // 刷新列表,项目负责人会更新
|
|
|
|
|
|
|
+ claimSingleRow.value = null;
|
|
|
|
|
+ getList(); // 刷新列表
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
/* API error handled by request interceptor */
|
|
/* API error handled by request interceptor */
|
|
|
}
|
|
}
|
|
@@ -1971,7 +1993,7 @@ const handleDetail = (row) => {
|
|
|
loadFollowupList();
|
|
loadFollowupList();
|
|
|
loadProjectContacts(); // 加载联系人
|
|
loadProjectContacts(); // 加载联系人
|
|
|
loadAnalysisData(); // 加载结果分析
|
|
loadAnalysisData(); // 加载结果分析
|
|
|
- fetchOperationLogs(data.id); // 加载操作日志
|
|
|
|
|
|
|
+ fetchOperationLogs(data.projectNo); // 加载操作日志(按项目编号过滤)
|
|
|
}).finally(() => {
|
|
}).finally(() => {
|
|
|
detailLoading.value = false;
|
|
detailLoading.value = false;
|
|
|
});
|
|
});
|
|
@@ -1983,8 +2005,7 @@ const loadProjectContacts = async () => {
|
|
|
contactLoading.value = true;
|
|
contactLoading.value = true;
|
|
|
try {
|
|
try {
|
|
|
const params = {
|
|
const params = {
|
|
|
- customerNo: detailData.customerNo,
|
|
|
|
|
- companyNo: detailData.companyNo
|
|
|
|
|
|
|
+ platformCode: String(detailData.id)
|
|
|
};
|
|
};
|
|
|
console.log('加载项目联系人参数:', params);
|
|
console.log('加载项目联系人参数:', params);
|
|
|
const res = await listContact(params);
|
|
const res = await listContact(params);
|
|
@@ -2265,6 +2286,7 @@ const submitProjectContact = () => {
|
|
|
companyNo: projectContactForm.companyNo,
|
|
companyNo: projectContactForm.companyNo,
|
|
|
customerNo: projectContactForm.customerNo,
|
|
customerNo: projectContactForm.customerNo,
|
|
|
customName: projectContactForm.customName,
|
|
customName: projectContactForm.customName,
|
|
|
|
|
+ platformCode: String(detailData.id),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
@@ -2661,54 +2683,59 @@ const getProjectRoleList = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.search-card {
|
|
.search-card {
|
|
|
- margin-bottom: 12px;
|
|
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
border: none;
|
|
border: none;
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
- border-radius: 10px;
|
|
|
|
|
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
|
|
|
|
|
|
|
+ border-radius: 8px;
|
|
|
:deep(.el-form-item) {
|
|
:deep(.el-form-item) {
|
|
|
margin-bottom: 2px;
|
|
margin-bottom: 2px;
|
|
|
}
|
|
}
|
|
|
|
|
+ :deep(.el-form-item__label) {
|
|
|
|
|
+ font-weight: normal;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.search-btns {
|
|
.search-btns {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- justify-content: flex-start;
|
|
|
|
|
|
|
+ flex-wrap: nowrap;
|
|
|
gap: 12px;
|
|
gap: 12px;
|
|
|
- padding-left: 0;
|
|
|
|
|
|
|
|
|
|
.el-button {
|
|
.el-button {
|
|
|
- border-radius: 6px;
|
|
|
|
|
height: 32px;
|
|
height: 32px;
|
|
|
- padding: 8px 16px;
|
|
|
|
|
|
|
+ padding: 0 20px;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.summary-stripe {
|
|
.summary-stripe {
|
|
|
- margin: 15px 0;
|
|
|
|
|
- background: #fff;
|
|
|
|
|
- padding: 10px 20px;
|
|
|
|
|
- border-radius: 4px;
|
|
|
|
|
|
|
+ margin: 12px 0;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
|
|
+ padding: 0 4px;
|
|
|
|
|
|
|
|
- .stripe-title {
|
|
|
|
|
- font-size: 15px;
|
|
|
|
|
- font-weight: 600;
|
|
|
|
|
- color: #333;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .stripe-total {
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- color: #475569;
|
|
|
|
|
- margin-left: -200px; // 拉近标题与总计
|
|
|
|
|
- .red-text {
|
|
|
|
|
- color: #f43f5e;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
- margin: 0 5px;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .stripe-left {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 20px;
|
|
|
|
|
+
|
|
|
|
|
+ .stripe-title {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 400;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .stripe-total {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #f43f5e;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ .total-label { color: #64748b; margin-right: 4px; }
|
|
|
|
|
+ .red-text {
|
|
|
|
|
+ font-weight: normal;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.stripe-actions {
|
|
.stripe-actions {
|
|
@@ -2727,7 +2754,7 @@ const getProjectRoleList = () => {
|
|
|
:deep(th.el-table__cell) {
|
|
:deep(th.el-table__cell) {
|
|
|
background-color: #f8fafc !important;
|
|
background-color: #f8fafc !important;
|
|
|
color: #475569;
|
|
color: #475569;
|
|
|
- font-weight: 600;
|
|
|
|
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2909,8 +2936,15 @@ const getProjectRoleList = () => {
|
|
|
|
|
|
|
|
// 详情抽屉样式
|
|
// 详情抽屉样式
|
|
|
.detail-drawer {
|
|
.detail-drawer {
|
|
|
|
|
+ :deep(.el-drawer) {
|
|
|
|
|
+ top: 0 !important;
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.el-drawer__header) {
|
|
|
|
|
+ display: none !important;
|
|
|
|
|
+ }
|
|
|
:deep(.el-drawer__body) {
|
|
:deep(.el-drawer__body) {
|
|
|
- padding: 0;
|
|
|
|
|
|
|
+ padding: 0 !important;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
background-color: #fff;
|
|
background-color: #fff;
|
|
@@ -3017,10 +3051,21 @@ const getProjectRoleList = () => {
|
|
|
margin-bottom: 16px;
|
|
margin-bottom: 16px;
|
|
|
|
|
|
|
|
.section-label {
|
|
.section-label {
|
|
|
- font-size: 16px;
|
|
|
|
|
|
|
+ font-size: 15px;
|
|
|
font-weight: 600;
|
|
font-weight: 600;
|
|
|
- color: #1e293b;
|
|
|
|
|
- position: relative;
|
|
|
|
|
|
|
+ color: #409eff;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+
|
|
|
|
|
+ &::before {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ width: 4px;
|
|
|
|
|
+ height: 14px;
|
|
|
|
|
+ background-color: #409eff;
|
|
|
|
|
+ border-radius: 2px;
|
|
|
|
|
+ margin-right: 8px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3341,6 +3386,7 @@ const getProjectRoleList = () => {
|
|
|
color: #1d2129;
|
|
color: #1d2129;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
.leader-tag {
|
|
.leader-tag {
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
height: 20px;
|
|
height: 20px;
|
|
@@ -3512,10 +3558,25 @@ const getProjectRoleList = () => {
|
|
|
|
|
|
|
|
.section-title {
|
|
.section-title {
|
|
|
color: #409eff;
|
|
color: #409eff;
|
|
|
- font-size: 15px;
|
|
|
|
|
- padding: 12px 16px;
|
|
|
|
|
- margin: 0 -24px 20px -24px;
|
|
|
|
|
- background: #f5f7fa;
|
|
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ padding: 0 16px;
|
|
|
|
|
+ height: 34px;
|
|
|
|
|
+ line-height: 34px;
|
|
|
|
|
+ margin: 0 -24px 24px -24px;
|
|
|
|
|
+ background: #f0f7ff;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+
|
|
|
|
|
+ &::before {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ width: 4px;
|
|
|
|
|
+ height: 14px;
|
|
|
|
|
+ background-color: #409eff;
|
|
|
|
|
+ border-radius: 2px;
|
|
|
|
|
+ margin-right: 8px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -3540,8 +3601,15 @@ const getProjectRoleList = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.project-contact-drawer {
|
|
.project-contact-drawer {
|
|
|
|
|
+ :deep(.el-drawer) {
|
|
|
|
|
+ top: 0 !important;
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.el-drawer__header) {
|
|
|
|
|
+ display: none !important;
|
|
|
|
|
+ }
|
|
|
:deep(.el-drawer__body) {
|
|
:deep(.el-drawer__body) {
|
|
|
- padding: 0;
|
|
|
|
|
|
|
+ padding: 0 !important;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
}
|
|
}
|
|
@@ -3588,4 +3656,177 @@ const getProjectRoleList = () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+// 销售线索抽屉样式
|
|
|
|
|
+.leads-drawer {
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ :deep(.el-drawer) {
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.el-drawer__header) {
|
|
|
|
|
+ display: none !important;
|
|
|
|
|
+ margin: 0 !important;
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.el-drawer__body) {
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .drawer-header {
|
|
|
|
|
+ padding: 16px 24px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-bottom: 1px solid #f1f5f9;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ margin: 0 0 12px 0;
|
|
|
|
|
+
|
|
|
|
|
+ .header-title {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: baseline;
|
|
|
|
|
+ .main-title {
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ color: #1e293b;
|
|
|
|
|
+ }
|
|
|
|
|
+ .sub-title {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #94a3b8;
|
|
|
|
|
+ margin-left: 12px;
|
|
|
|
|
+ font-weight: normal;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .close-btn {
|
|
|
|
|
+ font-size: 20px;
|
|
|
|
|
+ color: #94a3b8;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ &:hover { color: #ef4444; }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .drawer-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ background-color: #fff;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-form) {
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .form-section {
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ margin: 0 0 24px;
|
|
|
|
|
+ border-radius: 0;
|
|
|
|
|
+ box-shadow: none;
|
|
|
|
|
+
|
|
|
|
|
+ &:first-child {
|
|
|
|
|
+ margin-top: 0 !important;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .section-title {
|
|
|
|
|
+ margin: 0 0 20px 0;
|
|
|
|
|
+ color: #409eff;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ padding: 0 12px;
|
|
|
|
|
+ height: 34px;
|
|
|
|
|
+ line-height: 34px;
|
|
|
|
|
+ background: #f0f7ff;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ span {
|
|
|
|
|
+ color: #409eff !important;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.attachment-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+
|
|
|
|
|
+ .upload-btn {
|
|
|
|
|
+ margin-right: 0;
|
|
|
|
|
+ :deep(.el-button) {
|
|
|
|
|
+ font-weight: normal;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 4px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 为表单项增加内边距,因为 section-title 是全宽的
|
|
|
|
|
+ .el-row {
|
|
|
|
|
+ padding: 0 24px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .at-table {
|
|
|
|
|
+ margin: 0 24px 24px 24px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-form-item) {
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-form-item__label) {
|
|
|
|
|
+ font-weight: normal;
|
|
|
|
|
+ color: #475569;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-input-group__append) {
|
|
|
|
|
+ background-color: #f8fafc;
|
|
|
|
|
+ color: #64748b;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .drawer-footer {
|
|
|
|
|
+ padding: 16px 24px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-top: 1px solid #f1f5f9;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: flex-end;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-button) {
|
|
|
|
|
+ padding: 10px 30px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ font-weight: normal;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .at-table {
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+
|
|
|
|
|
+ :deep(th.el-table__cell) {
|
|
|
|
|
+ background-color: #f8fafc !important;
|
|
|
|
|
+ color: #475569;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ padding: 12px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(td.el-table__cell) {
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ padding: 10px 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .empty-text {
|
|
|
|
|
+ padding: 30px 0;
|
|
|
|
|
+ color: #94a3b8;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|
|
|
|
|
+
|