| | |
| | | > |
| | | <template slot="title"> |
| | | <div class="header"> |
| | | <span class="header-label">机会名称</span> |
| | | <span class="header-label">销售机会</span> |
| | | <span class="header-title">{{ detailConfig.infomation.name }}</span> |
| | | </div> |
| | | </template> |
| | |
| | | <div>跟进记录<el-badge type="primary" :value="2"> </el-badge></div> |
| | | </template> --> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="收款预测" name="collectionForecast"></el-tab-pane> |
| | | <!-- <el-tab-pane label="收款预测" name="collectionForecast"></el-tab-pane> --> |
| | | <el-tab-pane label="报价单" name="quotation"></el-tab-pane> |
| | | <el-tab-pane label="销售明细单" name="detail"></el-tab-pane> |
| | | <el-tab-pane label="服务合同" name="serviceContract"></el-tab-pane> |
| | |
| | | </div> |
| | | <div v-show="isSchduleExpand" class="basic-info-content"> |
| | | <div class="step-view"> |
| | | <el-steps :active="active" align-center> |
| | | <el-step :active-color="'#fff'" :title="item.title" :key="index" v-for="(item, index) in stepsList"> |
| | | <el-steps :active="sale_active" align-center> |
| | | <el-step :active-color="'#fff'" :title="item.name" :key="item.id" v-for="(item, index) in stepsList"> |
| | | <template slot="title"> |
| | | <div class="step-title-view"> |
| | | <div class="step-label">{{ item.title }}</div> |
| | | <div v-show="index === active" class="step-btn" @click="advanceClick(item)">推进</div> |
| | | <div class="step-desc">{{ item.desc }}</div> |
| | | <div class="step-label">{{ item.name }}</div> |
| | | <div v-show="sale_active === index" class="step-btn" @click="advanceClick(item)"> |
| | | <!-- && sale_stage_id !== stepsList.length --> |
| | | 推进 |
| | | </div> |
| | | <!-- <div class="step-desc">{{ item.desc }}</div> --> |
| | | </div> |
| | | </template> |
| | | </el-step> |
| | |
| | | <li v-for="(item, i) in basicInfoList" :key="i"> |
| | | <div class="left"> |
| | | <div class="content-title">{{ item.leftStr + ":" }}</div> |
| | | <div class="content-data">{{ item.leftValue }}</div> |
| | | <div class="content-data">{{ item.leftValue ? item.leftValue : "--" }}</div> |
| | | </div> |
| | | <div class="right"> |
| | | <div class="content-title">{{ item.rightStr }}</div> |
| | | <div class="content-data">{{ item.rightValue }}</div> |
| | | <div v-if="item.rightStr" class="right"> |
| | | <div class="content-title">{{ item.rightStr + ":" }}</div> |
| | | <div class="content-data">{{ item.rightValue ? item.rightValue : "--" }}</div> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | |
| | | <li v-for="(item, i) in forecastList" :key="i"> |
| | | <div class="left"> |
| | | <div class="content-title">{{ item.leftStr + ":" }}</div> |
| | | <div class="content-data">{{ item.leftValue }}</div> |
| | | <div class="content-data">{{ item.leftValue ? item.leftValue : "--" }}</div> |
| | | </div> |
| | | <div class="right"> |
| | | <div class="content-title">{{ item.rightStr }}</div> |
| | | <div class="content-data">{{ item.rightValue }}</div> |
| | | <div v-if="item.rightStr" class="right"> |
| | | <div class="content-title">{{ item.rightStr + ":" }}</div> |
| | | <div class="content-data">{{ item.rightValue ? item.rightValue : "--" }}</div> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | |
| | | <li v-for="(item, i) in dynamicInfoList" :key="i"> |
| | | <div class="left"> |
| | | <div class="content-title">{{ item.leftStr + ":" }}</div> |
| | | <div class="content-data">{{ item.leftValue }}</div> |
| | | <div class="content-data">{{ item.leftValue ? item.leftValue : "--" }}</div> |
| | | </div> |
| | | <div class="right"> |
| | | <div class="content-title">{{ item.rightStr }}</div> |
| | | <div class="content-data">{{ item.rightValue }}</div> |
| | | <div v-if="item.rightStr" class="right"> |
| | | <div class="content-title">{{ item.rightStr + ":" }}</div> |
| | | <div class="content-data">{{ item.rightValue ? item.rightValue : "--" }}</div> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | |
| | | <div class="content-title">{{ item.leftStr + ":" }}</div> |
| | | <div class="content-data">{{ item.leftValue }}</div> |
| | | </div> |
| | | <div class="right"> |
| | | <div class="content-title">{{ item.rightStr }}</div> |
| | | <div v-if="item.rightStr" class="right"> |
| | | <div class="content-title">{{ item.rightStr + ":" }}</div> |
| | | <div class="content-data">{{ item.rightValue }}</div> |
| | | </div> |
| | | </li> |
| | |
| | | <li v-for="(item, i) in addressInfoList" :key="i"> |
| | | <div class="left"> |
| | | <div class="content-title">{{ item.leftStr + ":" }}</div> |
| | | <div class="content-data">{{ item.leftValue }}</div> |
| | | <div class="content-data">{{ item.leftValue ? item.leftValue : "--" }}</div> |
| | | </div> |
| | | <div class="right"> |
| | | <div class="content-title">{{ item.rightStr }}</div> |
| | | <div class="content-data">{{ item.rightValue }}</div> |
| | | <div v-if="item.rightStr" class="right"> |
| | | <div class="content-title">{{ item.rightStr + ":" }}</div> |
| | | <div class="content-data">{{ item.rightValue ? item.rightValue : "--" }}</div> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | |
| | | <li> |
| | | <div class="left remark"> |
| | | <div class="content-title">{{ "备注:" }}</div> |
| | | <div class="content-data">{{ "备注内容" }}</div> |
| | | <div class="content-data">{{ detailConfig.infomation.remark }}</div> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | <!-- 附件信息 --> |
| | | <div class="basic-info"> |
| | | <!-- <div class="basic-info"> |
| | | <div class="basic-info-label" @click="expandClick('annex')"> |
| | | <i v-if="isAnnexExpand" class="el-icon-arrow-down"></i> |
| | | <i v-else class="el-icon-arrow-up"></i> |
| | |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | </div> --> |
| | | <!-- 销售机会阶段推进历史 --> |
| | | <div class="basic-info"> |
| | | <!-- <div class="basic-info"> |
| | | <div class="basic-info-label" @click="expandClick('history')"> |
| | | <i v-if="isHistoryExpand" class="el-icon-arrow-down"></i> |
| | | <i v-else class="el-icon-arrow-up"></i> |
| | |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | </div> --> |
| | | </div> |
| | | <div v-if="activeName === 'second'" class="second"> |
| | | <FollowupRecords :isDetail="true" /> |
| | | <FollowupRecords :isDetail="true" :add-config="addConfig" /> |
| | | </div> |
| | | <div v-if="activeName === 'collectionForecast'" class="second"> |
| | | <!-- <SalesOpportunity :isDetail="true" /> --> |
| | | </div> |
| | | <div v-if="activeName === 'quotation'" class="second"> |
| | | <Quotation :isDetail="true" /> |
| | | <Quotation :isDetail="true" :add-config="addConfig" /> |
| | | </div> |
| | | <div v-if="activeName === 'detail'" class="second"> |
| | | <SalesDetails :isDetail="true" /> |
| | | <SalesDetails :isDetail="true" :add-config="addConfig" /> |
| | | </div> |
| | | <div v-if="activeName === 'serviceContract'" class="second"> |
| | | <ServiceContract :isDetail="true" /> |
| | | <ServiceContract :isDetail="true" :add-config="addConfig" /> |
| | | </div> |
| | | </div> |
| | | <!-- 推进 --> |
| | | <DetailAdvanceDialog v-if="advanceConfig.visible" :advance-config="advanceConfig" /> |
| | | <DetailAdvanceDialog v-if="advanceConfig.visible" :advance-config="advanceConfig" @pushed="updatePushData" /> |
| | | </el-drawer> |
| | | </div> |
| | | </template> |
| | |
| | | import SalesDetails from "@/views/sales/salesDetails" |
| | | import ServiceContract from "@/views/service/serviceContract" |
| | | import DetailAdvanceDialog from "@/views/sales/salesOpportunity/DetailAdvanceDialog" |
| | | import { getSaleStageList } from "@/api/sales/salesOpportunity" |
| | | import {getAllData} from "@/api/client/client"; |
| | | export default { |
| | | name: "DetailClientManage", |
| | | props: { |
| | |
| | | computed: {}, |
| | | data() { |
| | | return { |
| | | statusList: [], |
| | | detailConfig: this.opportunityDetail, |
| | | activeName: "first", |
| | | isSchduleExpand: true, // 进度追踪 |
| | | stepsList: [ |
| | | { title: "初期沟通", desc: "停留: 1月8天20小时" }, |
| | | { title: "需求分析", desc: "" }, |
| | | { title: "方案报价", desc: "" }, |
| | | { title: "商务谈判", desc: "" }, |
| | | { title: "成功结案", desc: "" }, |
| | | { title: "失败结案", desc: "" } |
| | | ], |
| | | stepsList: [], |
| | | isBasicExpand: true, // 基本信息展开 |
| | | basicInfoList: [], |
| | | isForecastExpand: true, // 销售预测 |
| | |
| | | isAnnexExpand: true, // 附件信息 |
| | | isHistoryExpand: true, // 推进历史 |
| | | historyList: [], |
| | | active: 2, |
| | | sale_active: 0, |
| | | advanceConfig: { |
| | | visible: false, |
| | | active: "" |
| | | } |
| | | active: "", |
| | | allOptions: [], |
| | | options: [] |
| | | }, |
| | | addConfig: {} |
| | | } |
| | | }, |
| | | created() { |
| | | this.setData() |
| | | this.setData(this.detailConfig.infomation) |
| | | this.addConfig = { |
| | | id_name: "sale_chance_id", |
| | | keywordType: "销售机会", |
| | | keyword: this.detailConfig.infomation.name, |
| | | id: this.detailConfig.infomation.id, |
| | | common_name: this.detailConfig.infomation.name, |
| | | client_name: this.detailConfig.infomation.client.name, |
| | | contact_name: this.detailConfig.infomation.contact_name, |
| | | client_id: this.detailConfig.infomation.client_id, |
| | | contact_id: this.detailConfig.infomation.contact_id, |
| | | sale_chance_name: this.detailConfig.infomation.name, |
| | | sale_chance_id: this.detailConfig.infomation.id |
| | | } |
| | | this.getSaleStageList().then(()=>{ |
| | | return this.getAllData() |
| | | }).then((statusList)=>{ |
| | | this.statusList =statusList |
| | | |
| | | this.setData(this.detailConfig.infomation) |
| | | |
| | | }) |
| | | console.log('this.detailConfig.infomation',this.detailConfig.infomation) |
| | | }, |
| | | mounted() {}, |
| | | methods: { |
| | | setData() { |
| | | /** |
| | | * 更新推进记录 |
| | | */ |
| | | updatePushData(e){ |
| | | this.sale_active = e.step - 1 |
| | | }, |
| | | async getSaleStageList() { |
| | | await getSaleStageList().then((res) => { |
| | | this.stepsList = res.data.list |
| | | res.data.list.map((item, index) => { |
| | | if (item.id === this.detailConfig.infomation.sale_stage_id) { |
| | | this.sale_active = index |
| | | } |
| | | }) |
| | | }) |
| | | }, |
| | | setData(item) { |
| | | this.basicInfoList = [ |
| | | { |
| | | leftStr: "客户名称", |
| | | leftValue: "", |
| | | leftValue: item.client_name, |
| | | rightStr: "销售机会编号", |
| | | rightValue: "" |
| | | rightValue: item.id |
| | | }, |
| | | { |
| | | leftStr: "机会名称", |
| | | leftValue: "", |
| | | leftValue: item.name, |
| | | rightStr: "联系人姓名", |
| | | rightValue: "" |
| | | rightValue: item.contact_name |
| | | }, |
| | | { |
| | | leftStr: "商机来源", |
| | | leftValue: "", |
| | | leftValue: item.sales_sources.name, |
| | | rightStr: "商机类型", |
| | | rightValue: "" |
| | | rightValue: item.sale_type.name |
| | | }, |
| | | { |
| | | leftStr: "销售阶段", |
| | | leftValue: "", |
| | | leftValue: item.sale_stage_name, |
| | | rightStr: "销售负责人", |
| | | rightValue: "" |
| | | rightValue: item.member.username |
| | | }, |
| | | { |
| | | leftStr: "老客户营销", |
| | | leftValue: "", |
| | | rightStr: "签到", |
| | | leftValue: item.regular_customers.name, |
| | | rightStr: "审批状态", |
| | | rightValue: "" |
| | | }, |
| | | { |
| | | leftStr: "审批状态", |
| | | leftValue: "", |
| | | rightStr: "竞争对手", |
| | | leftStr: "竞争对手", |
| | | leftValue: item.competitors, |
| | | rightStr: "创建人", |
| | | rightValue: "" |
| | | }, |
| | | { |
| | | leftStr: "创建人", |
| | | leftStr: "创建时间", |
| | | leftValue: "", |
| | | rightStr: "创建时间", |
| | | rightStr: "", |
| | | rightValue: "" |
| | | } |
| | | ] |
| | | this.forecastList = [ |
| | | { |
| | | leftStr: "可能性(%)", |
| | | leftValue: "", |
| | | leftValue: item.possibility.name, |
| | | rightStr: "币种", |
| | | rightValue: "" |
| | | rightValue: "人民币" |
| | | }, |
| | | { |
| | | leftStr: "预算绝对值", |
| | | leftValue: "", |
| | | leftValue: item.capital_budget, |
| | | rightStr: "预计成交日期", |
| | | rightValue: "" |
| | | rightValue: item.expected_time |
| | | }, |
| | | { |
| | | leftStr: "预计合同金额", |
| | | leftValue: "", |
| | | leftValue: item.projected_amount, |
| | | rightStr: "当前状态", |
| | | rightValue: "" |
| | | rightValue: this.statusList.find(ele=>ele.id === item.status_id)?.name ?? '' |
| | | } |
| | | ] |
| | | this.dynamicInfoList = [ |
| | |
| | | this.businessInfoList = [ |
| | | { |
| | | leftStr: "客户需求或痛点(why)", |
| | | leftValue: "" |
| | | leftValue: item.pain_points |
| | | }, |
| | | { |
| | | leftStr: "是否已经立项(plan)", |
| | | leftValue: "" |
| | | leftValue: item.whether_established |
| | | }, |
| | | { |
| | | leftStr: "资金预算是多少(plan)", |
| | | leftValue: "" |
| | | leftValue: item.capital_budget |
| | | }, |
| | | { |
| | | leftStr: "关键决策人是谁(who)", |
| | | leftValue: "" |
| | | leftValue: item.key_maker |
| | | }, |
| | | { |
| | | leftStr: "关键决策因素有哪些(what)", |
| | | leftValue: "" |
| | | leftValue: item.key_factors |
| | | }, |
| | | { |
| | | leftStr: "决策流程是怎样的(what)", |
| | | leftValue: "" |
| | | leftValue: item.process |
| | | }, |
| | | { |
| | | leftStr: "竞争对手提供的方案(what)", |
| | | leftValue: "" |
| | | leftValue: item.solutions |
| | | } |
| | | ] |
| | | this.swotInfoList = [ |
| | | { |
| | | leftStr: "优势(S)", |
| | | leftValue: "", |
| | | leftValue: item.advantages, |
| | | rightStr: "劣势(W)", |
| | | rightValue: "" |
| | | rightValue: item.disadvantages |
| | | }, |
| | | { |
| | | leftStr: "机会(O)", |
| | | leftValue: "", |
| | | leftValue: item.opportunities, |
| | | rightStr: "威胁(T)", |
| | | rightValue: "" |
| | | rightValue: item.threats |
| | | } |
| | | ] |
| | | this.addressInfoList = [ |
| | | { |
| | | leftStr: "国家", |
| | | leftValue: "", |
| | | leftValue: "中国", |
| | | rightStr: "省份", |
| | | rightValue: "" |
| | | rightValue: item.Province.name |
| | | }, |
| | | { |
| | | leftStr: "城市", |
| | | leftValue: "", |
| | | rightStr: "区域", |
| | | leftValue: item.City.name, |
| | | rightStr: "", |
| | | rightValue: "" |
| | | }, |
| | | { |
| | | leftStr: "详细地址", |
| | | leftValue: "", |
| | | leftValue: item.detail_address, |
| | | rightStr: "", |
| | | rightValue: "" |
| | | } |
| | |
| | | }, |
| | | handleClose() { |
| | | this.detailConfig.visible = false |
| | | this.$parent.getData() |
| | | }, |
| | | // tab切换 |
| | | tabsClick(tab, event) { |
| | |
| | | }, |
| | | // 推进 |
| | | advanceClick(item) { |
| | | console.log(item) |
| | | this.advanceConfig.visible = true |
| | | this.advanceConfig.active = item.title |
| | | let options = [] |
| | | for (let i = 0; i < this.stepsList.length; i++) { |
| | | options.push(this.stepsList[i]) |
| | | } |
| | | this.advanceConfig = { |
| | | visible: true, |
| | | active: item.id, |
| | | allOptions: this.stepsList, |
| | | options: options, |
| | | id: this.detailConfig.infomation.id |
| | | } |
| | | }, |
| | | |
| | | getAllData(){ |
| | | return getAllData() |
| | | .then((res) => { |
| | | return res.data.status |
| | | }) |
| | | .catch((err) => { |
| | | console.log(err) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | .step-view { |
| | | padding: 30px 60px 5px; |
| | | height: 100px; |
| | | height: 80px; |
| | | .step-title-view { |
| | | margin-top: 10px; |
| | | font-size: 12px; |