跟进记录完善

pull/371/head
wuyibo 2 years ago
parent b3519d6782
commit e4339a1e13

@ -77,7 +77,15 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-swagger</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis-flex -->
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>

@ -7,3 +7,26 @@ spring:
application:
# 应用名称
name: ruoyi-gen
# Mybatis开启驼峰映射
mybatis:
configuration:
mapUnderscoreToCamelCase: true
# MyBatis配置
mybatis-flex:
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件
mapper-locations: classpath*:mapper/**/*Mapper.xml
cacheEnabled: true
useGeneratedKeys: true
defaultExecutorType: SIMPLE
configuration:
# 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql

@ -49,6 +49,18 @@ public class CustomerController extends BaseController
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("system:customer:makerList")
@GetMapping("/makerList")
public TableDataInfo makerList(CustomerVo customer)
{
startPage();
List<CustomerVo> list = customerService.selectCustomerMakerList(customer);
return getDataTable(list);
}
/**
*
*/

@ -0,0 +1,121 @@
package com.ruoyi.system.controller;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.system.domain.Customer;
import com.ruoyi.system.domain.vo.CustomerOrderVo;
import com.ruoyi.system.service.ICustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.system.domain.CustomerOrder;
import com.ruoyi.system.service.ICustomerOrderService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.page.TableDataInfo;
/**
* -Controller
*
* @author ruoyi
* @date 2023-08-01
*/
@RestController
@RequestMapping("/customerOrder")
public class CustomerOrderController extends BaseController
{
@Autowired
private ICustomerOrderService customerOrderService;
@Autowired
private ICustomerService customerService;
/**
* -
*/
@RequiresPermissions("system:customerOrder:list")
@GetMapping("/list")
public TableDataInfo list(CustomerOrder customerOrder)
{
startPage();
List<CustomerOrder> list = customerOrderService.selectCustomerOrderList(customerOrder);
return getDataTable(list);
}
@GetMapping("/getCustomerOrderPage")
public TableDataInfo getCustomerOrderPage(CustomerOrderVo customerOrder)
{
startPage();
List<CustomerOrderVo> list = customerOrderService.getCustomerOrderPage(customerOrder);
return getDataTable(list);
}
/**
* -
*/
@RequiresPermissions("system:customerOrder:export")
@Log(title = "客户-订车", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, CustomerOrder customerOrder)
{
List<CustomerOrder> list = customerOrderService.selectCustomerOrderList(customerOrder);
ExcelUtil<CustomerOrder> util = new ExcelUtil<CustomerOrder>(CustomerOrder.class);
util.exportExcel(response, list, "客户-订车数据");
}
/**
* -
*/
@RequiresPermissions("system:customerOrder:query")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return AjaxResult.success(customerOrderService.selectCustomerOrderById(id));
}
/**
* -
*/
@Log(title = "客户-订车", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody CustomerOrder customerOrder)
{
Customer customer = new Customer();
customer.setId(customerOrder.getCustomerId());
customer.setStatus("order");
customerService.updateCustomer(customer);
return toAjax(customerOrderService.insertCustomerOrder(customerOrder));
}
/**
* -
*/
@RequiresPermissions("system:customerOrder:edit")
@Log(title = "客户-订车", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody CustomerOrder customerOrder)
{
return toAjax(customerOrderService.updateCustomerOrder(customerOrder));
}
/**
* -
*/
@RequiresPermissions("system:customerOrder:remove")
@Log(title = "客户-订车", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(customerOrderService.deleteCustomerOrderByIds(ids));
}
}

@ -0,0 +1,49 @@
package com.ruoyi.system.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.web.domain.BaseEntity;
/**
* - f_customer_order
*
* @author ruoyi
* @date 2023-08-01
*/
@Data
public class CustomerOrder extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** id */
private Long id;
/** 客户id */
@Excel(name = "客户id")
private Long customerId;
/** 订车时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "订车时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date orderDate;
/** 车辆详细 */
@Excel(name = "车辆详细")
private String carInfo;
/** 车辆VIN */
@Excel(name = "车辆VIN")
private String carVin;
/** 车辆状态 */
@Excel(name = "车辆状态")
private String carStatus;
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "出库日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date outDate;
}

@ -36,21 +36,47 @@ public class FollowUp extends BaseEntity
@Excel(name = "跟进日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date followUpDate;
/** 跟进记录 */
@Excel(name = "跟进记录")
private String followUpRecord;
/** 再次预约到店日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "再次预约到店日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date preToStoreDate;
/** 跟进方式 */
@Excel(name = "跟进方式")
private String followUpMethod;
/** 级别 */
@Excel(name = "级别")
private String followLevel;
/** 跟进结果 */
@Excel(name = "跟进结果")
private String followResult;
@Excel(name = "跟进方式")
private String followUpMethod;
/** 意向级别 */
@Excel(name = "意向级别")
private String intentionLevel;
/** 本次跟进记录 */
@Excel(name = "本次跟进记录")
private String followUpRecord;
/** 下次跟进备注 */
@Excel(name = "下次跟进备注")
private String nextFollowUpRecord;
/** 下次跟进时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "下次跟进时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date nextFollowUpTime;
/** 预约时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "预约时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date appointmentTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "到店时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date arrivalTime;
/** 战败原因 */
@Excel(name = "战败原因")
private String defeatReasons;
@Excel(name = "预约状态")
private String makerStatus;
@Excel(name = "跟进类型(销售回访,潜客跟进)")
private String followType;
@Excel(name = "跟进目的")
private String objective;
}

@ -0,0 +1,48 @@
package com.ruoyi.system.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.annotation.Excel;
import lombok.Data;
import java.util.Date;
/**
* @author
* @date 20230803 8:36
* @Description
*/
@Data
public class CustomerOrderVo extends CustomerVo{
/** 客户id */
@Excel(name = "客户id")
private Long customerId;
/** 订车时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "订车时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date orderDate;
/** 车辆详细 */
@Excel(name = "车辆详细")
private String carInfo;
/** 车辆VIN */
@Excel(name = "车辆VIN")
private String carVin;
/** 车辆状态 */
@Excel(name = "车辆状态")
private String carStatus;
/** 车辆状态 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "出库日期", width = 30, dateFormat = "yyyy-MM-dd")
private String outDate;
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "计划跟进日期", width = 30, dateFormat = "yyyy-MM-dd")
private String planFollowUpDate;
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "实际跟进日期", width = 30, dateFormat = "yyyy-MM-dd")
private String actualFollowUpDate;
}

@ -27,4 +27,18 @@ public class CustomerVo extends Customer {
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "跟进超期", width = 30, dateFormat = "yyyy-MM-dd")
private String followUpOverdueDate;
/** 意向级别 */
@Excel(name = "意向级别")
private String intentionLevel;
@Excel(name = "跟进方式")
private String followUpMethod;
/** 预约时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "预约时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date appointmentTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "到店时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date arrivalTime;
@Excel(name = "预约状态")
private String makerStatus;
}

@ -85,4 +85,6 @@ public interface CustomerMapper
* @return
*/
public int deleteFollowUpByCustomerId(Long id);
//预约记录列表
List<CustomerVo> selectCustomerMakerList(CustomerVo customer);
}

@ -0,0 +1,66 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.mybatisflex.core.BaseMapper;
import com.ruoyi.system.domain.CustomerOrder;
import com.ruoyi.system.domain.vo.CustomerOrderVo;
/**
* -Mapper
*
* @author ruoyi
* @date 2023-08-01
*/
public interface CustomerOrderMapper extends BaseMapper<CustomerOrder>
{
/**
* -
*
* @param id -
* @return -
*/
public CustomerOrder selectCustomerOrderById(Long id);
/**
* -
*
* @param customerOrder -
* @return -
*/
public List<CustomerOrder> selectCustomerOrderList(CustomerOrder customerOrder);
/**
* -
*
* @param customerOrder -
* @return
*/
public int insertCustomerOrder(CustomerOrder customerOrder);
/**
* -
*
* @param customerOrder -
* @return
*/
public int updateCustomerOrder(CustomerOrder customerOrder);
/**
* -
*
* @param id -
* @return
*/
public int deleteCustomerOrderById(Long id);
/**
* -
*
* @param ids
* @return
*/
public int deleteCustomerOrderByIds(Long[] ids);
List<CustomerOrderVo> getCustomerOrderPage(CustomerOrderVo customerOrder);
}

@ -0,0 +1,66 @@
package com.ruoyi.system.service;
import java.util.List;
import com.mybatisflex.core.service.IService;
import com.ruoyi.system.domain.CustomerOrder;
import com.ruoyi.system.domain.vo.CustomerOrderVo;
/**
* -Service
*
* @author ruoyi
* @date 2023-08-01
*/
public interface ICustomerOrderService extends IService<CustomerOrder>
{
/**
* -
*
* @param id -
* @return -
*/
public CustomerOrder selectCustomerOrderById(Long id);
/**
* -
*
* @param customerOrder -
* @return -
*/
public List<CustomerOrder> selectCustomerOrderList(CustomerOrder customerOrder);
/**
* -
*
* @param customerOrder -
* @return
*/
public int insertCustomerOrder(CustomerOrder customerOrder);
/**
* -
*
* @param customerOrder -
* @return
*/
public int updateCustomerOrder(CustomerOrder customerOrder);
/**
* -
*
* @param ids -
* @return
*/
public int deleteCustomerOrderByIds(Long[] ids);
/**
* -
*
* @param id -
* @return
*/
public int deleteCustomerOrderById(Long id);
List<CustomerOrderVo> getCustomerOrderPage(CustomerOrderVo customerOrder);
}

@ -59,4 +59,6 @@ public interface ICustomerService
* @return
*/
public int deleteCustomerById(Long id);
List<CustomerVo> selectCustomerMakerList(CustomerVo customer);
}

@ -0,0 +1,104 @@
package com.ruoyi.system.service.impl;
import java.util.List;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.system.domain.vo.CustomerOrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.CustomerOrderMapper;
import com.ruoyi.system.domain.CustomerOrder;
import com.ruoyi.system.service.ICustomerOrderService;
/**
* -Service
*
* @author ruoyi
* @date 2023-08-01
*/
@Service
public class CustomerOrderServiceImpl extends ServiceImpl<CustomerOrderMapper, CustomerOrder> implements ICustomerOrderService
{
@Autowired
private CustomerOrderMapper customerOrderMapper;
/**
* -
*
* @param id -
* @return -
*/
@Override
public CustomerOrder selectCustomerOrderById(Long id)
{
return customerOrderMapper.selectCustomerOrderById(id);
}
/**
* -
*
* @param customerOrder -
* @return -
*/
@Override
public List<CustomerOrder> selectCustomerOrderList(CustomerOrder customerOrder)
{
return customerOrderMapper.selectCustomerOrderList(customerOrder);
}
/**
* -
*
* @param customerOrder -
* @return
*/
@Override
public int insertCustomerOrder(CustomerOrder customerOrder)
{
customerOrder.setCreateTime(DateUtils.getNowDate());
return customerOrderMapper.insertCustomerOrder(customerOrder);
}
/**
* -
*
* @param customerOrder -
* @return
*/
@Override
public int updateCustomerOrder(CustomerOrder customerOrder)
{
customerOrder.setUpdateTime(DateUtils.getNowDate());
return customerOrderMapper.updateCustomerOrder(customerOrder);
}
/**
* -
*
* @param ids -
* @return
*/
@Override
public int deleteCustomerOrderByIds(Long[] ids)
{
return customerOrderMapper.deleteCustomerOrderByIds(ids);
}
/**
* -
*
* @param id -
* @return
*/
@Override
public int deleteCustomerOrderById(Long id)
{
return customerOrderMapper.deleteCustomerOrderById(id);
}
@Override
public List<CustomerOrderVo> getCustomerOrderPage(CustomerOrderVo customerOrder) {
return customerOrderMapper.getCustomerOrderPage(customerOrder);
}
}

@ -109,6 +109,11 @@ public class CustomerServiceImpl implements ICustomerService
return customerMapper.deleteCustomerById(id);
}
@Override
public List<CustomerVo> selectCustomerMakerList(CustomerVo customer) {
return customerMapper.selectCustomerMakerList(customer);
}
/**
* -
*

@ -63,12 +63,9 @@ public class FollowUpServiceImpl extends ServiceImpl<FollowUpMapper, FollowUp> i
Customer customer = new Customer();
customer.setId(followUp.getCustomerId());
//如果跟进记录的跟进级别选择
if("战败".equals(followUp.getFollowLevel())){
if("fail".equals(followUp.getFollowResult())){
customer.setStatus("defeat");
customerMapper.updateCustomer(customer);
}else if("订车".equals(followUp.getFollowLevel())||"成交".equals(followUp.getFollowLevel())){
customer.setStatus("order");
customerMapper.updateCustomer(customer);
}
return followUpMapper.insertFollowUp(followUp);
}

@ -65,8 +65,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</sql>
<select id="selectCustomerList" resultType="com.ruoyi.system.domain.vo.CustomerVo">
SELECT t.*,f.follow_up_date as followUpLastDate,f.follow_level as followUpLastLevel,
(CASE f.follow_level
SELECT t.*,f.follow_up_date as followUpLastDate,f.intention_level as followUpLastLevel,
(CASE f.intention_level
WHEN 'H' THEN
date_add(f.follow_up_date,interval 1 day)
WHEN 'A' THEN
@ -76,10 +76,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
WHEN 'C' THEN
date_add(f.follow_up_date,interval 13 day)
ELSE
IF(ISNULL(f.follow_level),f.follow_level,'暂不回访')
IF(ISNULL(f.intention_level),f.intention_level,'暂不回访')
END
) as followUpOverdueDate,
(case f.follow_level
(case f.intention_level
WHEN 'H' THEN '24小时内回访'
WHEN 'A' THEN
date_add(f.follow_up_date,interval 3 day)
@ -87,10 +87,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
date_add(f.follow_up_date,interval 5 day)
WHEN 'C' THEN
date_add(f.follow_up_date,interval 7 day)
when '成交' then '成交'
when '战败' then '战败'
when '休眠' then '休眠'
when '订车' then '订车'
ELSE ''
end
) as proposalNextFollowDate,f1.followUpTimes FROM f_customer t
@ -130,19 +126,62 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="storeName != null and storeName != ''"> and t.store_name like concat('%', #{storeName}, '%')</if>
<if test="orderDate != null "> and t.order_date = #{orderDate}</if>
<if test="followUpLastDate != null "> and f.follow_up_date = #{followUpLastDate}</if>
<if test="followUpLastLevel != null "> and f.follow_level = #{followUpLastLevel}</if>
<if test="proposalNextFollowDate != null "> and f.pre_to_store_date = #{proposalNextFollowDate}</if>
<if test="followUpLastLevel != null "> and f.intention_level = #{followUpLastLevel}</if>
<if test="proposalNextFollowDate != null "> and f.next_follow_up_time = #{proposalNextFollowDate}</if>
</where>
</select>
<select id="selectCustomerById" parameterType="Long" resultMap="CustomerFollowUpResult">
select a.id, a.user_name,a.store_status, a.nick_name, a.user_type, a.email, a.phonenumber, a.sex, a.avatar, a.clue_channel, a.data_source, a.live_address, a.status, a.del_flag, a.login_ip, a.login_date, a.create_by, a.create_time, a.update_by, a.update_time, a.remark, a.wechat, a.buy_car_type, a.exist_models, a.is_assessment, a.intention_car_models, a.contrast_car_models, a.is_test_drive, a.is_offer, a.is_finance, a.un_booking_car_reason, a.pre_to_store_date, a.last_to_store_date, a.store_name, a.order_date,
b.id as sub_id, b.customer_id as sub_customer_id, b.follow_up_date as sub_follow_up_date, b.follow_up_record as sub_follow_up_record, b.pre_to_store_date as sub_pre_to_store_date, b.create_by as sub_create_by, b.create_time as sub_create_time, b.update_by as sub_update_by, b.update_time as sub_update_time, b.remark as sub_remark, b.follow_level as sub_follow_level
from f_customer a
left join f_follow_up b on b.customer_id = a.id
SELECT
a.id,
a.user_name,
a.store_status,
a.nick_name,
a.user_type,
a.email,
a.phonenumber,
a.sex,
a.avatar,
a.clue_channel,
a.data_source,
a.live_address,
a.STATUS,
a.del_flag,
a.login_ip,
a.login_date,
a.create_by,
a.create_time,
a.update_by,
a.update_time,
a.remark,
a.wechat,
a.buy_car_type,
a.exist_models,
a.is_assessment,
a.intention_car_models,
a.contrast_car_models,
a.is_test_drive,
a.is_offer,
a.is_finance,
a.un_booking_car_reason,
a.pre_to_store_date,
a.last_to_store_date,
a.store_name,
a.order_date,
b.id as sub_id, b.customer_id as sub_customer_id, b.follow_up_date as sub_follow_up_date, b.follow_up_record, b.appointment_time, b.create_by as sub_create_by, b.create_time as sub_create_time, b.update_by as sub_update_by, b.update_time as sub_update_time, b.remark as sub_remark, b.intention_level
from f_customer a left join f_follow_up b on b.customer_id = a.id
where a.id = #{id}
</select>
<select id="selectCustomerMakerList" resultType="com.ruoyi.system.domain.vo.CustomerVo">
SELECT * from f_follow_up t LEFT JOIN f_customer c on c.id = t.customer_id
where t.follow_result = 'maker' and c.status = 'potential'
<if test="phoneNumber != null and phoneNumber != ''"> and c.phone_number like concat('%', #{phoneNumber}, '%')</if>
<if test="userName != null and userName != ''"> and c.user_name like concat('%', #{userName}, '%')</if>
<if test="makerStatus != null and makerStatus != ''"> and t.maker_status =#{makerStatus}</if>
<if test="intentionLevel != null and intentionLevel != ''"> and t.intention_level =#{intentionLevel}</if>
</select>
<insert id="insertCustomer" parameterType="Customer" useGeneratedKeys="true" keyProperty="id">
insert into f_customer

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.CustomerOrderMapper">
<resultMap type="CustomerOrder" id="CustomerOrderResult">
<result property="id" column="id" />
<result property="customerId" column="customer_id" />
<result property="orderDate" column="order_date" />
<result property="carInfo" column="car_info" />
<result property="carVin" column="car_vin" />
<result property="carStatus" column="car_status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="outDate" column="out_date"/>
<result property="carStatus" column="car_status"/>
</resultMap>
<sql id="selectCustomerOrderVo">
select id, customer_id, order_date, car_info, car_vin,out_date, car_status, create_by, create_time, update_by, update_time, remark from f_customer_order
</sql>
<select id="selectCustomerOrderList" parameterType="CustomerOrder" resultMap="CustomerOrderResult">
<include refid="selectCustomerOrderVo"/>
<where>
<if test="customerId != null "> and customer_id = #{customerId}</if>
<if test="outDate != null "> and out_date = #{outDate}</if>
<if test="orderDate != null "> and order_date = #{orderDate}</if>
<if test="carInfo != null and carInfo != ''"> and car_info = #{carInfo}</if>
<if test="carVin != null and carVin != ''"> and car_vin = #{carVin}</if>
<if test="carStatus != null and carStatus != ''"> and car_status = #{carStatus}</if>
</where>
</select>
<select id="selectCustomerOrderById" parameterType="Long" resultMap="CustomerOrderResult">
<include refid="selectCustomerOrderVo"/>
where id = #{id}
</select>
<select id="getCustomerOrderPage" resultType="com.ruoyi.system.domain.vo.CustomerOrderVo">
SELECT *,DATE_ADD(t.order_date, INTERVAL 7 DAY) as planFollowUpDate,f.create_time as actualFollowUpDate FROM f_customer_order t
LEFT JOIN f_customer c ON c.id = t.customer_id
LEFT JOIN (
SELECT a.* FROM f_follow_up AS a
LEFT JOIN (
SELECT MAX(create_time) AS create_time, customer_id FROM f_follow_up GROUP BY customer_id
) AS b ON a.customer_id = b.customer_id where a.create_time = b.create_time
) f on f.customer_id = c.id
<where>
<if test="phoneNumber != null and phoneNumber != ''"> and c.phone_number like concat('%', #{phoneNumber}, '%')</if>
<if test="userName != null and userName != ''"> and c.user_name like concat('%', #{userName}, '%')</if>
<if test="status != null "> and c.status = #{status}</if>
<if test="customerId != null "> and t.customer_id = #{customerId}</if>
<if test="orderDate != null "> and t.order_date = #{orderDate}</if>
<if test="outDate != null "> and t.out_date = #{outDate}</if>
<if test="carInfo != null and carInfo != ''"> and t.car_info like concat('%', #{carInfo}, '%')</if>
<if test="carVin != null and carVin != ''"> and t.car_vin like concat('%', #{carVin}, '%')</if>
<if test="carStatus != null and carStatus != ''"> and t.car_status like concat('%', #{carStatus}, '%') </if>
</where>
</select>
<insert id="insertCustomerOrder" parameterType="CustomerOrder" useGeneratedKeys="true" keyProperty="id">
insert into f_customer_order
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="customerId != null">customer_id,</if>
<if test="orderDate != null">order_date,</if>
<if test="outDate != null">out_date,</if>
<if test="carInfo != null">car_info,</if>
<if test="carVin != null">car_vin,</if>
<if test="carStatus != null">car_status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="customerId != null">#{customerId},</if>
<if test="orderDate != null">#{orderDate},</if>
<if test="outDate != null">#{outDate},</if>
<if test="carInfo != null">#{carInfo},</if>
<if test="carVin != null">#{carVin},</if>
<if test="carStatus != null">#{carStatus},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateCustomerOrder" parameterType="CustomerOrder">
update f_customer_order
<trim prefix="SET" suffixOverrides=",">
<if test="customerId != null">customer_id = #{customerId},</if>
<if test="orderDate != null">order_date = #{orderDate},</if>
<if test="outDate != null">out_date = #{outDate},</if>
<if test="carInfo != null">car_info = #{carInfo},</if>
<if test="carVin != null">car_vin = #{carVin},</if>
<if test="carStatus != null">car_status = #{carStatus},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteCustomerOrderById" parameterType="Long">
delete from f_customer_order where id = #{id}
</delete>
<delete id="deleteCustomerOrderByIds" parameterType="String">
delete from f_customer_order where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

@ -8,36 +8,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="id" column="id" />
<result property="customerId" column="customer_id" />
<result property="followUpDate" column="follow_up_date" />
<result property="followUpMethod" column="follow_up_method" />
<result property="followResult" column="follow_result" />
<result property="intentionLevel" column="intention_level" />
<result property="followUpRecord" column="follow_up_record" />
<result property="preToStoreDate" column="pre_to_store_date" />
<result property="nextFollowUpRecord" column="next_follow_up_record" />
<result property="nextFollowUpTime" column="next_follow_up_time" />
<result property="appointmentTime" column="appointment_time" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="followLevel" column="follow_level" />
<result property="followResult" column="follow_result" />
<result property="followUpMethod" column="follow_up_method" />
<result property="defeatReasons" column="defeat_reasons" />
<result property="arrivalTime" column="arrival_time"/>
<result column="maker_status" property="makerStatus"/>
<result column="follow_type" property="followType"/>
<result column="objective" property="objective"/>
</resultMap>
<sql id="selectFollowUpVo">
select id, customer_id, follow_up_date, follow_up_record, pre_to_store_date, create_by, create_time, update_by, update_time, remark, follow_level,follow_result,follow_up_method from f_follow_up
select id, customer_id,objective,follow_type,maker_status,arrival_time, follow_up_date, follow_up_method, follow_result, intention_level, follow_up_record, next_follow_up_record, next_follow_up_time, appointment_time, create_by, create_time, update_by, update_time, remark, defeat_reasons from f_follow_up
</sql>
<select id="selectFollowUpList" parameterType="FollowUp" resultMap="FollowUpResult">
<include refid="selectFollowUpVo"/>
<where>
<if test="customerId != null and customerId != ''"> and customer_id = #{customerId}</if>
<if test="followResult != null and followResult != ''"> and follow_result = #{followResult}</if>
<if test="followUpMethod != null and followUpMethod != ''"> and follow_up_method = #{followUpMethod}</if>
<if test="customerId != null "> and customer_id = #{customerId}</if>
<if test="followUpDate != null "> and follow_up_date = #{followUpDate}</if>
<if test="followType != null "> and follow_type = #{followType}</if>
<if test="followUpMethod != null and followUpMethod != ''"> and follow_up_method = #{followUpMethod}</if>
<if test="followResult != null and followResult != ''"> and follow_result = #{followResult}</if>
<if test="intentionLevel != null and intentionLevel != ''"> and intention_level = #{intentionLevel}</if>
<if test="followUpRecord != null and followUpRecord != ''"> and follow_up_record = #{followUpRecord}</if>
<if test="preToStoreDate != null "> and pre_to_store_date = #{preToStoreDate}</if>
<if test="followLevel != null and followLevel != ''"> and follow_level = #{followLevel}</if>
<if test="nextFollowUpRecord != null and nextFollowUpRecord != ''"> and next_follow_up_record = #{nextFollowUpRecord}</if>
<if test="nextFollowUpTime != null "> and next_follow_up_time = #{nextFollowUpTime}</if>
<if test="appointmentTime != null "> and appointment_time = #{appointmentTime}</if>
<if test="defeatReasons != null and defeatReasons != ''"> and defeat_reasons = #{defeatReasons}</if>
</where>
</select>
<select id="selectFollowUpById" parameterType="Integer" resultMap="FollowUpResult">
<select id="selectFollowUpById" parameterType="Long" resultMap="FollowUpResult">
<include refid="selectFollowUpVo"/>
where id = #{id}
</select>
@ -46,31 +57,45 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
insert into f_follow_up
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="customerId != null">customer_id,</if>
<if test="makerStatus != null">maker_status,</if>
<if test="followType != null">follow_type,</if>
<if test="arrivalTime != null">arrival_time,</if>
<if test="followUpDate != null">follow_up_date,</if>
<if test="followUpMethod != null">follow_up_method,</if>
<if test="followResult != null">follow_result,</if>
<if test="intentionLevel != null">intention_level,</if>
<if test="followUpRecord != null">follow_up_record,</if>
<if test="preToStoreDate != null">pre_to_store_date,</if>
<if test="nextFollowUpRecord != null">next_follow_up_record,</if>
<if test="nextFollowUpTime != null">next_follow_up_time,</if>
<if test="appointmentTime != null">appointment_time,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
<if test="followLevel != null">follow_level,</if>
<if test="followResult != null ">follow_result ,</if>
<if test="followUpMethod != null">follow_up_method ,</if>
<if test="defeatReasons != null">defeat_reasons,</if>
<if test="objective != null">objective,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="customerId != null">#{customerId},</if>
<if test="makerStatus != null">#{makerStatus},</if>
<if test="followType != null">#{followType},</if>
<if test="arrivalTime != null">#{arrivalTime},</if>
<if test="followUpDate != null">#{followUpDate},</if>
<if test="followUpMethod != null">#{followUpMethod},</if>
<if test="followResult != null">#{followResult},</if>
<if test="intentionLevel != null">#{intentionLevel},</if>
<if test="followUpRecord != null">#{followUpRecord},</if>
<if test="preToStoreDate != null">#{preToStoreDate},</if>
<if test="nextFollowUpRecord != null">#{nextFollowUpRecord},</if>
<if test="nextFollowUpTime != null">#{nextFollowUpTime},</if>
<if test="appointmentTime != null">#{appointmentTime},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
<if test="followLevel != null">#{followLevel},</if>
<if test="followResult != null ">#{followResult},</if>
<if test="followUpMethod != null">#{followUpMethod},</if>
<if test="defeatReasons != null">#{defeatReasons},</if>
<if test="objective != null">#{objective},</if>
</trim>
</insert>
@ -78,22 +103,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update f_follow_up
<trim prefix="SET" suffixOverrides=",">
<if test="customerId != null">customer_id = #{customerId},</if>
<if test="makerStatus != null">maker_status = #{makerStatus},</if>
<if test="followType != null">follow_type = #{followType},</if>
<if test="arrivalTime != null">arrival_time = #{arrivalTime},</if>
<if test="followUpDate != null">follow_up_date = #{followUpDate},</if>
<if test="followUpMethod != null">follow_up_method = #{followUpMethod},</if>
<if test="followResult != null">follow_result = #{followResult},</if>
<if test="intentionLevel != null">intention_level = #{intentionLevel},</if>
<if test="followUpRecord != null">follow_up_record = #{followUpRecord},</if>
<if test="preToStoreDate != null">pre_to_store_date = #{preToStoreDate},</if>
<if test="nextFollowUpRecord != null">next_follow_up_record = #{nextFollowUpRecord},</if>
<if test="nextFollowUpTime != null">next_follow_up_time = #{nextFollowUpTime},</if>
<if test="appointmentTime != null">appointment_time = #{appointmentTime},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="followLevel != null">follow_level = #{followLevel},</if>
<if test="followResult != null "> follow_result = #{followResult},</if>
<if test="followUpMethod != null "> follow_up_method = #{followUpMethod},</if>
<if test="defeatReasons != null">defeat_reasons = #{defeatReasons},</if>
<if test="objective != null">objective = #{objective},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteFollowUpById" parameterType="Integer">
<delete id="deleteFollowUpById" parameterType="Long">
delete from f_follow_up where id = #{id}
</delete>

@ -8,6 +8,14 @@ export function listCustomer(query) {
params: query
})
}
// 查询客户预约信息列表
export function listCustomerMaker(query) {
return request({
url: '/system/customer/makerList',
method: 'get',
params: query
})
}
// 查询客户信息列表
export function listCustomerFollow(query) {
return request({
@ -49,7 +57,13 @@ export function addCustomerFollowRecerd(data) {
data: data
})
}
export function addCustomerOrderRecerd(data){
return request({
url: '/system/customerOrder',
method: 'post',
data: data
})
}
export function updateCustomerFollowRecerd(data) {
return request({
url: '/system/up',
@ -57,6 +71,14 @@ export function updateCustomerFollowRecerd(data) {
data: data
})
}
//确认到店
export function confirmToStore(data) {
return request({
url: '/system/up',
method: 'put',
data: data
})
}
// 删除客户信息
export function delCustomer(id) {
return request({

@ -0,0 +1,58 @@
import request from '@/utils/request'
// 查询客户-订车列表
export function listCustomerOrder(query) {
return request({
url: '/system/customerOrder/list',
method: 'get',
params: query
})
}
// 查询客户-订车列表
export function getCustomerOrderPage(query) {
return request({
url: '/system/customerOrder/getCustomerOrderPage',
method: 'get',
params: query
})
}
export function confirmToOut(data){
return request({
url: '/system/customerOrder',
method: 'put',
data: data
})
}
// 查询客户-订车详细
export function getCustomerOrder(id) {
return request({
url: '/system/customerOrder/' + id,
method: 'get'
})
}
// 新增客户-订车
export function addCustomerOrder(data) {
return request({
url: '/system/customerOrder',
method: 'post',
data: data
})
}
// 修改客户-订车
export function updateCustomerOrder(data) {
return request({
url: '/system/customerOrder',
method: 'put',
data: data
})
}
// 删除客户-订车
export function delCustomerOrder(id) {
return request({
url: '/system/customerOrder/' + id,
method: 'delete'
})
}

@ -6,7 +6,16 @@ import DictData from './DictData'
const DEFAULT_DICT_OPTIONS = {
types: [],
}
//字典翻译
export function translateDict(list, e){
var value = ''
list.map(i =>{
if (i.code ==e) {
value =i.value
}
})
return value
}
/**
* @classdesc 字典
* @property {Object} label 标签对象内部属性名为字典类型名称

@ -27,75 +27,23 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="线索渠道" prop="clueChannel">
<el-select v-model="queryParams.clueChannel" placeholder="请选择线索渠道" clearable>
<el-option
v-for="dict in dict.type.clue_channels"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="信息来源" prop="dataSource">
<el-select v-model="queryParams.dataSource" placeholder="请选择信息来源" clearable>
<el-option
v-for="dict in dict.type.customer_source"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="到店状态" prop="status">
<el-select v-model="queryParams.storeStatus" placeholder="请选择到店状态" clearable>
<el-form-item label="预约状态" prop="status">
<el-select v-model="queryParams.makerStatus" placeholder="请选择到店状态" clearable>
<el-option
v-for="dict in dict.type.to_store_status"
v-for="dict in dict.type.maker_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="微信号" prop="wechat">
<el-input
v-model="queryParams.wechat"
placeholder="请输入微信号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="意向车型" prop="intentionCarModels">
<el-input
v-model="queryParams.intentionCarModels"
placeholder="请输入意向车型"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="预计到店" prop="preToStoreDate">
<el-date-picker clearable
v-model="queryParams.preToStoreDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择预计到店">
</el-date-picker>
</el-form-item>
<el-form-item label="下单日期" prop="orderDate">
<el-date-picker clearable
v-model="queryParams.orderDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择下单日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<!-- <el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
@ -139,22 +87,17 @@
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns" :pageName="$options.name" ></right-toolbar>
</el-row>
</el-row>-->
<el-table v-loading="loading" :data="customerList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="客户姓名" align="center" prop="userName" width="120" v-if="columns[1].visible" show-overflow-tooltip />
<el-table-column label="客户状态" align="center" prop="status" width="120" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.customer_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="客户级别" align="center" prop="userType" v-if="columns[3].visible" show-overflow-tooltip >
<el-table-column label="手机号码" align="center" prop="phoneNumber" width="110" v-if="columns[5].visible" show-overflow-tooltip />
<el-table-column label="客户性别" align="center" prop="sex" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.customer_level" :value="scope.row.userType"/>
<dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex"/>
</template>
</el-table-column>
<el-table-column label="手机号码" align="center" prop="phoneNumber" width="110" v-if="columns[5].visible" show-overflow-tooltip />
<el-table-column label="线索渠道" align="center" prop="clueChannel" v-if="columns[8].visible" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.clue_channels" :value="scope.row.clueChannel"/>
@ -166,52 +109,33 @@
</template>
</el-table-column>
<el-table-column label="客户居住" align="center" prop="liveAddress" width="100" v-if="columns[10].visible" show-overflow-tooltip />
<el-table-column label="到店状态" align="center" prop="status" width="100" v-if="columns[11].visible" show-overflow-tooltip >
<el-table-column label="意向级别" align="center" prop="intentionLevel" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.to_store_status" :value="scope.row.storeStatus"/>
<dict-tag :options="dict.type.customer_level" :value="scope.row.intentionLevel"/>
</template>
</el-table-column>
<el-table-column label="微信号" align="center" prop="wechat" width="110" v-if="columns[20].visible" show-overflow-tooltip />
<el-table-column label="下单日期" align="center" prop="orderDate" width="120" v-if="columns[33].visible" show-overflow-tooltip >
<el-table-column label="预约状态" align="center" prop="status" width="100" v-if="columns[11].visible" show-overflow-tooltip >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}</span>
<dict-tag :options="dict.type.maker_status" :value="scope.row.makerStatus"/>
</template>
</el-table-column>
<!-- <el-table-column label="是否评估" align="center" prop="isAssessment" />-->
<el-table-column label="意向车型" align="center" prop="intentionCarModels" width="120" v-if="columns[24].visible" show-overflow-tooltip />
<!-- <el-table-column label="对比车型" align="center" prop="contrastCarModels" />
<el-table-column label="是否试驾" align="center" prop="isTestDrive" />
<el-table-column label="是否报价" align="center" prop="isOffer" />
<el-table-column label="是否金融" align="center" prop="isFinance" />-->
<!-- <el-table-column label="最后到店" align="center" prop="lastToStoreDate" width="120">
<el-table-column label="预约时间" class-name="specialColor" align="center" prop="appointmentTime" width="180" v-if="columns[30].visible" show-overflow-tooltip >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastToStoreDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.appointmentTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>-->
<el-table-column label="已有车辆" align="center" prop="existModels" v-if="columns[22].visible" show-overflow-tooltip />
<el-table-column label="预计到店" class-name="specialColor" align="center" prop="preToStoreDate" width="120" v-if="columns[30].visible" show-overflow-tooltip >
</el-table-column>
<el-table-column label="到店时间" class-name="specialColor" align="center" prop="arrivalTime" show-overflow-tooltip width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.preToStoreDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.arrivalTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="跟进次数" class-name="specialColor" align="center" prop="followUpTimes" v-if="columns[34].visible" show-overflow-tooltip />
<el-table-column label="最新跟进日" class-name="specialColor" align="center" prop="followUpLastDate" width="100" v-if="columns[35].visible" show-overflow-tooltip />
<el-table-column label="最新跟进级别" class-name="specialColor" align="center" prop="followUpLastLevel" width="100" v-if="columns[36].visible" show-overflow-tooltip />
<el-table-column label="建议下次跟进日" class-name="specialColor" align="center" prop="proposalNextFollowDate" width="120" v-if="columns[37].visible" show-overflow-tooltip />
<el-table-column label="跟进超期" class-name="specialColor" align="center" prop="followUpOverdueDate" width="120" v-if="columns[38].visible" show-overflow-tooltip />
<el-table-column label="未订车原因" align="center" prop="unBookingCarReason" width="110" show-overflow-tooltip v-if="columns[29].visible" show-overflow-tooltip />
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip v-if="columns[19].visible" />
<el-table-column label="操作" width="160" align="center" fixed="right" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleFollow(scope.row)"
v-hasPermi="['system:customer:edit']"
>跟进</el-button>
<el-button
<el-popconfirm title="是否确认到店?" @confirm="popConfirm(scope.row)" @cancel="popCancel" >
<el-button v-if="scope.row.makerStatus =='waitStore'" size="mini" type="text" icon="el-icon-edit" slot="reference"></el-button>
</el-popconfirm>
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
@ -224,7 +148,7 @@
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:customer:remove']"
>删除</el-button>
>取消</el-button>-->
</template>
</el-table-column>
</el-table>
@ -348,14 +272,6 @@
placeholder="请选择预计到店">
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="最后到店" prop="lastToStoreDate">
<el-date-picker clearable
v-model="form.lastToStoreDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择最后到店">
</el-date-picker>
</el-form-item>-->
<el-form-item label="4S店" prop="storeName">
<el-input v-model="form.storeName" placeholder="请输入4S店" />
</el-form-item>
@ -457,9 +373,10 @@
<script>
import {
listCustomer,
listCustomerMaker,
getCustomer,
delCustomer,
confirmToStore,
addCustomer,
updateCustomer,
addCustomerFollowRecerd, updateCustomerFollowRecerd, listCustomerFollow
@ -468,7 +385,7 @@ import Data from "@/views/system/dict/data";
export default {
name: "bookManagerCustomer",
dicts: ['to_store_status', 'customer_source','customer_status', 'sys_user_sex', 'customer_level', 'clue_channels','follow_result','follow_up_method'],
dicts: ['maker_status', 'customer_source','customer_status', 'sys_user_sex', 'customer_level', 'clue_channels','follow_result','follow_up_method'],
data() {
return {
drawer:false,
@ -512,7 +429,9 @@ export default {
wechat: null,
intentionCarModels: null,
preToStoreDate: null,
orderDate: null
orderDate: null,
orderByColumn:'appointment_time',
isAsc:'desc'
},
//
form: {
@ -616,7 +535,7 @@ export default {
getList() {
this.loading = true;
this.queryParams.status = 'potential';
listCustomer(this.queryParams).then(response => {
listCustomerMaker(this.queryParams).then(response => {
this.customerList = response.rows;
this.total = response.total;
this.loading = false;
@ -704,6 +623,30 @@ export default {
this.form.status = 'potential';
this.open = true;
this.title = "添加客户信息";
},
popConfirm(row){
let param = {
id : row.id,
makerStatus:'alreadyStore',
arrivalTime:this.getDateYYYYMMddHHMMSS()
}
confirmToStore(param).then(response => {
this.$modal.msgSuccess("操作成功");
this.open = false;
this.getList();
});
},
popCancel(){
console.log('取消')
},
getDateYYYYMMddHHMMSS(){
const date = new Date();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const strDate = date.getDate().toString().padStart(2, '0');
const starHours = date.getHours().toString().padStart(2, '0');
const starMinutes = date.getMinutes().toString().padStart(2, '0');
const starSeconds = date.getSeconds().toString().padStart(2, '0');
return `${date.getFullYear()}-${month}-${strDate} ${starHours}:${starMinutes}:${starSeconds}`;
},
/** 修改按钮操作 */
handleUpdate(row) {

@ -83,9 +83,9 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="预计到店" prop="preToStoreDate">
<el-form-item label="预计到店" prop="appointmentTime">
<el-date-picker clearable
v-model="queryParams.preToStoreDate"
v-model="queryParams.appointmentTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择预计到店">
@ -154,6 +154,11 @@
<el-table v-loading="loading" :data="customerList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="客户姓名" align="center" prop="userName" width="120" v-if="columns[1].visible" show-overflow-tooltip />
<el-table-column label="客户性别" align="center" prop="sex" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex"/>
</template>
</el-table-column>
<el-table-column label="客户状态" align="center" prop="status" width="120" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.customer_status" :value="scope.row.status"/>
@ -199,11 +204,11 @@
</template>
</el-table-column>-->
<el-table-column label="已有车辆" align="center" prop="existModels" v-if="columns[22].visible" show-overflow-tooltip />
<el-table-column label="预计到店" class-name="specialColor" align="center" prop="preToStoreDate" width="120" v-if="columns[30].visible" show-overflow-tooltip >
<!-- <el-table-column label="预计到店" class-name="specialColor" align="center" prop="appointmentTime" width="120" v-if="columns[30].visible" show-overflow-tooltip >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.preToStoreDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.appointmentTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
</el-table-column>-->
<el-table-column label="跟进次数" class-name="specialColor" align="center" prop="followUpTimes" v-if="columns[34].visible" show-overflow-tooltip />
<el-table-column label="最新跟进日" class-name="specialColor" align="center" prop="followUpLastDate" width="100" v-if="columns[35].visible" show-overflow-tooltip />
<el-table-column label="最新跟进级别" class-name="specialColor" align="center" prop="followUpLastLevel" width="100" v-if="columns[36].visible" show-overflow-tooltip />
@ -214,13 +219,13 @@
<el-table-column label="操作" width="160" align="center" fixed="right" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleFollow(scope.row)"
v-hasPermi="['system:customer:edit']"
>跟进</el-button>
>跟进</el-button>-->
<el-button
size="mini"
type="text"
@ -350,9 +355,9 @@
<el-input v-model="form.isFinance" placeholder="请输入是否金融" />
</el-form-item>
-->
<el-form-item label="预计到店" prop="preToStoreDate">
<el-form-item label="预计到店" prop="appointmentTime">
<el-date-picker clearable
v-model="form.preToStoreDate"
v-model="form.appointmentTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择预计到店">
@ -393,19 +398,14 @@
<el-timeline :reverse="reverse">
<el-timeline-item placement="top" v-for="(follow, index) in followUpList" :key="index" :timestamp="follow.followUpDate">
<el-card shadow="hover">
<p><el-tag>跟进方式</el-tag>
<el-select v-model="follow.followUpMethod" disabled>
<el-option
v-for="dict in dict.type.follow_up_method"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</p>
<p><el-tag>级别</el-tag> {{follow.followLevel}} </p>
<h4><el-tag>记录</el-tag> {{follow.followUpRecord}}</h4>
<p> <el-tag>再次预约到店日期</el-tag> {{follow.preToStoreDate}} </p>
<p><el-tag>跟进方式:</el-tag> {{follow.followUpMethod}} </p>
<p><el-tag>跟进结果:</el-tag> {{follow.followResultDesc}} </p>
<p v-show="follow.followResult!='fail'" ><el-tag>意向级别:</el-tag> {{follow.intentionLevel}} </p>
<p><el-tag>跟进记录:</el-tag> {{follow.followUpRecord}}</p>
<p v-show="follow.followResult == 'maker'" > <el-tag>预约时间:</el-tag> {{follow.appointmentTime}} </p>
<p v-show="follow.followResult !='fail' && follow.nextFollowUpTime " > <el-tag>下次跟进时间:</el-tag> {{follow.nextFollowUpTime}} </p>
<p v-show="follow.followResult !='fail' && follow.nextFollowUpRecord" > <el-tag>下次跟进记录:</el-tag> {{follow.nextFollowUpRecord}} </p>
<p v-show="follow.followResult=='fail'"><el-tag>战败原因:</el-tag> {{follow.defeatReasons}}</p>
<p>提交于 {{follow.createTime}}</p>
</el-card>
</el-timeline-item>
@ -430,11 +430,39 @@
/>
</el-select>
</el-form-item>
<el-form-item label="跟进记录" prop="followUpRecord">
<el-form-item label="本次跟进记录" prop="followUpRecord">
<el-input v-model="followForm.followUpRecord" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="级别" prop="followLevel">
<el-select v-model="followForm.followLevel" placeholder="请选择级别" clearable>
<el-form-item label="跟进结果" prop="followResult">
<el-radio-group v-model="followForm.followResult" @input="selctRadion">
<el-radio-button v-for="dict in dict.type.follow_result"
:key="dict.value"
:label="dict.value"
:name="dict.value">{{ dict.label }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-show="followFormShow.appointmentTimeShow" label="预约时间" prop="appointmentTime" :rules="followForm.followResult=='maker' ? [{ required:true, message: '预约时间不能为空', trigger: 'blur'}]:[{ required:false}]">
<el-date-picker clearable
v-model="followForm.appointmentTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择预约时间">
</el-date-picker>
</el-form-item>
<el-form-item v-show="followFormShow.nextFollowUpTimeShow" label="下次跟进时间" prop="nextFollowUpTime" :rules="followForm.followResult == 'fail' ?[{ required:false}] : [{ required:true, message: '下次跟进时间不能为空', trigger: 'blur'}]">
<el-date-picker clearable
v-model="followForm.nextFollowUpTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择下次跟进时间">
</el-date-picker>
</el-form-item>
<el-form-item v-show="followFormShow.nextFollowUpRecordShow" label="下次跟进记录" prop="nextFollowUpRecord">
<el-input v-model="followForm.nextFollowUpRecord" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item v-show="followFormShow.intentionLevelShow" label="意向级别" prop="intentionLevel" :rules="followForm.followResult=='fail' ? [{ required:false}] : [{ required:true, message: '意向级别不能为空', trigger: 'blur'}]">
<el-select v-model="followForm.intentionLevel" placeholder="请选择级别" clearable>
<el-option
v-for="dict in dict.type.customer_level"
:key="dict.value"
@ -443,16 +471,8 @@
/>
</el-select>
</el-form-item>
<el-form-item label="再次预约到店日期" prop="preToStoreDate">
<el-date-picker clearable
v-model="followForm.preToStoreDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择再次预约到店日期">
</el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="followForm.remark" type="textarea" placeholder="请输入内容" />
<el-form-item v-show="followFormShow.defeatReasonsShow" label="战败原因" prop="defeatReasons" :rules="followForm.followResult!='fail' ? followForm.defeatReasons : [{ required:true, message: '战败原因不能为空', trigger: 'blur'}]">
<el-input v-model="followForm.defeatReasons" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div style="text-align: center">
@ -460,7 +480,6 @@
<el-button @click="cancel"> </el-button>
</div>
</el-drawer>
</el-drawer>
</div>
</template>
@ -474,7 +493,6 @@ import {
updateCustomer,
addCustomerFollowRecerd, updateCustomerFollowRecerd, listCustomerFollow
} from "@/api/system/customer";
import Data from "@/views/system/dict/data";
export default {
name: "Customer",
@ -521,7 +539,7 @@ export default {
status: null,
wechat: null,
intentionCarModels: null,
preToStoreDate: null,
appointmentTime: null,
orderDate: null
},
//
@ -532,6 +550,13 @@ export default {
followUpDate:null,
customerId:null,
},
followFormShow:{
appointmentTimeShow:false,
intentionLevelShow:false,
nextFollowUpTimeShow:false,
nextFollowUpRecordShow:false,
defeatReasonsShow:false,
},
//
rules: {
userName: [
@ -558,7 +583,7 @@ export default {
followUpRecord:[
{ required: true, message: "跟进记录不能为空", trigger: "blur" }
],
followLevel: [
intentionLevel: [
{ required: true, message: "级别不能为空", trigger: "blur" }
],
followUpMethod:[
@ -633,18 +658,39 @@ export default {
},
/** 查询客户跟进信息列表 */
getFollowList(customerId) {
let that = this;
this.loading = true;
let queryParams = {
customerId:customerId,
pageNum:1,
pageSize:1000,
}
let dictType = that.dict.type;
listCustomerFollow(queryParams).then(response => {
this.followUpList = response.rows;
//
for (let follow of this.followUpList) {
let followUpMethod = this.getDictLableByVal(dictType.follow_up_method,follow.followUpMethod);
let followResult = this.getDictLableByVal(dictType.follow_result,follow.followResult);
let intentionLevel = this.getDictLableByVal(dictType.customer_level,follow.intentionLevel);
follow.followUpMethod = followUpMethod;
follow.followResultDesc = followResult;
follow.intentionLevel = intentionLevel;
}
this.total = response.total;
this.loading = false;
});
},
//val
getDictLableByVal(dictData,val){
let lable = '';
dictData.map(i =>{
if (i.value == val) {
lable = i.label
}
})
return lable
},
//
cancel() {
this.open = false;
@ -683,7 +729,7 @@ export default {
isOffer: null,
isFinance: null,
unBookingCarReason: null,
preToStoreDate: null,
appointmentTime: null,
lastToStoreDate: null,
storeName: null,
orderDate: null
@ -729,7 +775,7 @@ export default {
handleFollow(row){
this.drawer = true;
this.customerId = row.id;
this.followTitle = row.userName + " 跟进记录";
this.followTitle = row.userName +" "+ row.phoneNumber+" 跟进记录";
this.getFollowList(this.customerId);
},
handleDrawerAddFollowUp(){
@ -798,9 +844,9 @@ export default {
let obj = {};
obj.followUpDate = "";
obj.followUpRecord = "";
obj.preToStoreDate = "";
obj.appointmentTime = "";
obj.remark = "";
obj.followLevel = "";
obj.intentionLevel = "";
this.followUpList.push(obj);
},
/** 跟进模块-客户跟进记录删除按钮操作 */
@ -815,6 +861,34 @@ export default {
});
}
},
//
selctRadion(e){
if(e=='fail'){
// this.followRules.defeatReasons = [{required: true, message: "", trigger: "blur"}]
this.followRules.intentionLevel = [];
this.followRules.nextFollowUpTime = [];
this.followFormShow.defeatReasonsShow = true;
this.followFormShow.appointmentTimeShow=false;
this.followFormShow.intentionLevelShow=false;
this.followFormShow.nextFollowUpTimeShow=false;
this.followFormShow.nextFollowUpRecordShow=false;
}else if(e=='going'){
this.followRules.defeatReasons = [];
this.followRules.appointmentTime = [];
this.followFormShow.defeatReasonsShow = false;
this.followFormShow.appointmentTimeShow=false;
this.followFormShow.intentionLevelShow=true;
this.followFormShow.nextFollowUpTimeShow=true;
this.followFormShow.nextFollowUpRecordShow=true;
}else if(e=='maker'){
this.followRules.defeatReasons = [];
this.followFormShow.defeatReasonsShow = false;
this.followFormShow.appointmentTimeShow=true;
this.followFormShow.intentionLevelShow=true;
this.followFormShow.nextFollowUpTimeShow=true;
this.followFormShow.nextFollowUpRecordShow=true;
}
},
/** 复选框选中数据 */
handleFollowUpSelectionChange(selection) {
this.checkedFollowUp = selection.map(item => item.index)

@ -0,0 +1,385 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="客户" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入客户"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="客户手机" prop="phoneNumber">
<el-input
v-model="queryParams.phoneNumber"
placeholder="请输入客户手机号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="订车时间" prop="orderDate">
<el-date-picker clearable
v-model="queryParams.orderDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择订车时间">
</el-date-picker>
</el-form-item>
<el-form-item label="车辆详细" prop="carInfo">
<el-input
v-model="queryParams.carInfo"
placeholder="请输入车辆详细"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="车辆VIN" prop="carVin">
<el-input
v-model="queryParams.carVin"
placeholder="请输入车辆VIN"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @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="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:customerOrder:add']"
>新增</el-button>
</el-col>-->
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:customerOrder:edit']"
>修改</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:customerOrder:remove']"
>删除</el-button>
</el-col>-->
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:customerOrder:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="customerOrderList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="客户" align="center" prop="userName" />
<el-table-column label="客户手机" align="center" prop="phoneNumber" />
<el-table-column label="客户性别" align="center" prop="sex" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex"/>
</template>
</el-table-column>
<el-table-column label="线索渠道" align="center" prop="clueChannel" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.clue_channels" :value="scope.row.clueChannel"/>
</template>
</el-table-column>
<el-table-column label="信息来源" align="center" prop="dataSource" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.customer_source" :value="scope.row.dataSource"/>
</template>
</el-table-column>
<el-table-column label="订车时间" align="center" prop="orderDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="车辆详细" align="center" prop="carInfo" width="280"/>
<el-table-column label="车辆VIN" align="center" prop="carVin" width="220" />
<el-table-column label="车辆状态" align="center" prop="carStatus" >
<template slot-scope="scope">
<dict-tag :options="dict.type.car_status" :value="scope.row.carStatus"/>
</template>
</el-table-column>
<el-table-column label="出库日期" align="center" prop="outDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.outDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<!-- <el-table-column label="创建者" align="center" prop="createBy" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="更新者" align="center" prop="updateBy" />
<el-table-column label="更新时间" align="center" prop="updateTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>-->
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:customerOrder:edit']"
>修改</el-button>
<el-popconfirm title="是否确认出库?" @confirm="popConfirm(scope.row)" @cancel="popCancel" >
<el-button v-if="scope.row.carStatus =='notOut'" size="mini" type="text" icon="el-icon-check" slot="reference"></el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改客户-订车对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- <el-form-item label="客户id" prop="customerId">
<el-input v-model="form.customerId" placeholder="请输入客户id" />
</el-form-item>-->
<el-form-item label="订车时间" prop="orderDate">
<el-date-picker clearable
v-model="form.orderDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择订车时间">
</el-date-picker>
</el-form-item>
<el-form-item label="车辆详细" prop="carInfo">
<el-input v-model="form.carInfo" placeholder="请输入车辆详细" />
</el-form-item>
<el-form-item label="车辆VIN" prop="carVin">
<el-input v-model="form.carVin" placeholder="请输入车辆VIN" />
</el-form-item>
<el-form-item label="车辆状态" prop="carStatus">
<el-select v-model="form.carStatus" placeholder="请选择车辆状态">
<el-option
v-for="dict in dict.type.car_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { confirmToOut,getCustomerOrderPage, getCustomerOrder, delCustomerOrder, addCustomerOrder, updateCustomerOrder } from "@/api/system/customerOrder";
export default {
name: "CustomerOrder",
dicts: ['to_store_status', 'customer_source','customer_status', 'sys_user_sex', 'customer_level', 'clue_channels','follow_result','car_status'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
// -
customerOrderList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
customerId: null,
orderDate: null,
carInfo: null,
carVin: null,
carStatus: null,
orderByColumn:'t.order_date',
isAsc:'desc'
},
//
form: {},
//
rules: {
}
};
},
created() {
this.getList();
},
methods: {
/** 查询客户-订车列表 */
getList() {
this.loading = true;
getCustomerOrderPage(this.queryParams).then(response => {
this.customerOrderList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
customerId: null,
orderDate: null,
carInfo: null,
carVin: null,
carStatus: "0",
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
};
this.resetForm("form");
},
popConfirm(row){
let param = {
id : row.id,
carStatus:'outbound',
outDate:this.getDateYYYYMMddHHMMSS()
}
confirmToOut(param).then(response => {
this.$modal.msgSuccess("出库成功");
this.open = false;
this.getList();
});
},
popCancel(){
console.log('取消')
},
getDateYYYYMMddHHMMSS(){
const date = new Date();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const strDate = date.getDate().toString().padStart(2, '0');
const starHours = date.getHours().toString().padStart(2, '0');
const starMinutes = date.getMinutes().toString().padStart(2, '0');
const starSeconds = date.getSeconds().toString().padStart(2, '0');
return `${date.getFullYear()}-${month}-${strDate} ${starHours}:${starMinutes}:${starSeconds}`;
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加客户-订车";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getCustomerOrder(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改客户-订车";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateCustomerOrder(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addCustomerOrder(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除客户-订车编号为"' + ids + '"的数据项?').then(function() {
return delCustomerOrder(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/customerOrder/export', {
...this.queryParams
}, `customerOrder_${new Date().getTime()}.xlsx`)
}
}
};
</script>

@ -9,7 +9,6 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="客户级别" prop="userType">
<el-select v-model="queryParams.userType" placeholder="请选择客户级别" clearable>
<el-option
@ -48,16 +47,6 @@
/>
</el-select>
</el-form-item>
<el-form-item label="到店状态" prop="status">
<el-select v-model="queryParams.storeStatus" placeholder="请选择到店状态" clearable>
<el-option
v-for="dict in dict.type.to_store_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="微信号" prop="wechat">
<el-input
v-model="queryParams.wechat"
@ -74,14 +63,6 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="预计到店" prop="preToStoreDate">
<el-date-picker clearable
v-model="queryParams.preToStoreDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择预计到店">
</el-date-picker>
</el-form-item>
<el-form-item label="下单日期" prop="orderDate">
<el-date-picker clearable
v-model="queryParams.orderDate"
@ -145,6 +126,11 @@
<el-table v-loading="loading" :data="customerList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="客户姓名" align="center" prop="userName" width="120" v-if="columns[1].visible" show-overflow-tooltip />
<el-table-column label="客户性别" align="center" prop="sex" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex"/>
</template>
</el-table-column>
<el-table-column label="客户级别" align="center" prop="userType" v-if="columns[3].visible" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.customer_level" :value="scope.row.userType"/>
@ -162,11 +148,6 @@
</template>
</el-table-column>
<el-table-column label="客户居住" align="center" prop="liveAddress" width="100" v-if="columns[10].visible" show-overflow-tooltip />
<el-table-column label="到店状态" align="center" prop="status" width="100" v-if="columns[11].visible" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.to_store_status" :value="scope.row.storeStatus"/>
</template>
</el-table-column>
<el-table-column label="微信号" align="center" prop="wechat" width="110" v-if="columns[20].visible" show-overflow-tooltip />
<el-table-column label="下单日期" align="center" prop="orderDate" width="120" v-if="columns[33].visible" show-overflow-tooltip >
<template slot-scope="scope">
@ -185,9 +166,9 @@
</template>
</el-table-column>-->
<el-table-column label="已有车辆" align="center" prop="existModels" v-if="columns[22].visible" show-overflow-tooltip />
<el-table-column label="预计到店" class-name="specialColor" align="center" prop="preToStoreDate" width="120" v-if="columns[30].visible" show-overflow-tooltip >
<el-table-column label="预计到店" class-name="specialColor" align="center" prop="appointmentTime" width="120" v-if="columns[30].visible" show-overflow-tooltip >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.preToStoreDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.appointmentTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="跟进次数" class-name="specialColor" align="center" prop="followUpTimes" v-if="columns[34].visible" show-overflow-tooltip />
@ -207,6 +188,13 @@
@click="handleFollow(scope.row)"
v-hasPermi="['system:customer:edit']"
>跟进</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleToOrder(scope.row)"
v-hasPermi="['system:customer:toOrder']"
>下订单</el-button>
<el-button
size="mini"
type="text"
@ -336,9 +324,9 @@
<el-input v-model="form.isFinance" placeholder="请输入是否金融" />
</el-form-item>
-->
<el-form-item label="预计到店" prop="preToStoreDate">
<el-form-item label="预计到店" prop="appointmentTime">
<el-date-picker clearable
v-model="form.preToStoreDate"
v-model="form.appointmentTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择预计到店">
@ -379,19 +367,14 @@
<el-timeline :reverse="reverse">
<el-timeline-item placement="top" v-for="(follow, index) in followUpList" :key="index" :timestamp="follow.followUpDate">
<el-card shadow="hover">
<p><el-tag>跟进方式</el-tag>
<el-select v-model="follow.followUpMethod" disabled>
<el-option
v-for="dict in dict.type.follow_up_method"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</p>
<p><el-tag>级别</el-tag> {{follow.followLevel}} </p>
<h4><el-tag>记录</el-tag> {{follow.followUpRecord}}</h4>
<p> <el-tag>再次预约到店日期</el-tag> {{follow.preToStoreDate}} </p>
<p><el-tag>跟进方式:</el-tag> {{follow.followUpMethod}} </p>
<p><el-tag>跟进结果:</el-tag> {{follow.followResultDesc}} </p>
<p v-show="follow.followResult!='fail'" ><el-tag>意向级别:</el-tag> {{follow.intentionLevel}} </p>
<p><el-tag>跟进记录:</el-tag> {{follow.followUpRecord}}</p>
<p v-show="follow.followResult == 'maker'" > <el-tag>预约时间:</el-tag> {{follow.appointmentTime}} </p>
<p v-show="follow.followResult !='fail' && follow.nextFollowUpTime " > <el-tag>下次跟进时间:</el-tag> {{follow.nextFollowUpTime}} </p>
<p v-show="follow.followResult !='fail' && follow.nextFollowUpRecord" > <el-tag>下次跟进记录:</el-tag> {{follow.nextFollowUpRecord}} </p>
<p v-show="follow.followResult=='fail'"><el-tag>战败原因:</el-tag> {{follow.defeatReasons}}</p>
<p>提交于 {{follow.createTime}}</p>
</el-card>
</el-timeline-item>
@ -416,11 +399,39 @@
/>
</el-select>
</el-form-item>
<el-form-item label="跟进记录" prop="followUpRecord">
<el-form-item label="本次跟进记录" prop="followUpRecord">
<el-input v-model="followForm.followUpRecord" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="级别" prop="followLevel">
<el-select v-model="followForm.followLevel" placeholder="请选择级别" clearable>
<el-form-item label="跟进结果" prop="followResult">
<el-radio-group v-model="followForm.followResult" @input="selctRadion">
<el-radio-button v-for="dict in dict.type.follow_result"
:key="dict.value"
:label="dict.value"
:name="dict.value">{{ dict.label }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-show="followFormShow.appointmentTimeShow" label="预约时间" prop="appointmentTime" :rules="followForm.followResult=='maker' ? [{ required:true, message: '预约时间不能为空', trigger: 'blur'}]:[{ required:false}]">
<el-date-picker clearable
v-model="followForm.appointmentTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择预约时间">
</el-date-picker>
</el-form-item>
<el-form-item v-show="followFormShow.nextFollowUpTimeShow" label="下次跟进时间" prop="nextFollowUpTime" :rules="followForm.followResult == 'fail' ?[{ required:false}] : [{ required:true, message: '下次跟进时间不能为空', trigger: 'blur'}]">
<el-date-picker clearable
v-model="followForm.nextFollowUpTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择下次跟进时间">
</el-date-picker>
</el-form-item>
<el-form-item v-show="followFormShow.nextFollowUpRecordShow" label="下次跟进记录" prop="nextFollowUpRecord">
<el-input v-model="followForm.nextFollowUpRecord" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item v-show="followFormShow.intentionLevelShow" label="意向级别" prop="intentionLevel" :rules="followForm.followResult=='fail' ? [{ required:false}] : [{ required:true, message: '意向级别不能为空', trigger: 'blur'}]">
<el-select v-model="followForm.intentionLevel" placeholder="请选择级别" clearable>
<el-option
v-for="dict in dict.type.customer_level"
:key="dict.value"
@ -429,25 +440,63 @@
/>
</el-select>
</el-form-item>
<el-form-item label="再次预约到店日期" prop="preToStoreDate">
<el-form-item v-show="followFormShow.defeatReasonsShow" label="战败原因" prop="defeatReasons" :rules="followForm.followResult!='fail' ? followForm.defeatReasons : [{ required:true, message: '战败原因不能为空', trigger: 'blur'}]">
<el-input v-model="followForm.defeatReasons" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div style="text-align: center">
<el-button type="primary" @click="submitFollowForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-drawer>
</el-drawer>
<el-dialog :title="orderTitle" :visible.sync="orderOpen" width="500px" append-to-body>
<el-form ref="orderForm" :model="orderForm" :rules="orderRules" label-width="80px">
<el-form-item label="客户" prop="customerName">
{{orderForm.customerName}}
</el-form-item>
<el-form-item label="订车时间" prop="orderDate">
<el-date-picker clearable
v-model="orderForm.orderDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择订车时间">
</el-date-picker>
</el-form-item>
<el-form-item label="车辆详细" prop="carInfo">
<el-input v-model="orderForm.carInfo" type="textarea" placeholder="请输入车辆详细" />
</el-form-item>
<el-form-item label="车辆VIN" prop="carVin">
<el-input v-model="orderForm.carVin" placeholder="请输入车辆VIN" />
</el-form-item>
<el-form-item label="车辆状态" prop="carStatus">
<el-select v-model="orderForm.carStatus" placeholder="请选择车辆状态">
<el-option
v-for="dict in dict.type.car_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="出库日期" prop="outDate">
<el-date-picker clearable
v-model="followForm.preToStoreDate"
v-model="orderForm.outDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择再次预约到店日期">
placeholder="请选择出库日期">
</el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="followForm.remark" type="textarea" placeholder="请输入内容" />
<el-input v-model="orderForm.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div style="text-align: center">
<el-button type="primary" @click="submitFollowForm"> </el-button>
<el-button @click="cancel"> </el-button>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="orderSubmitForm"> </el-button>
<el-button @click="orderCancel"> </el-button>
</div>
</el-drawer>
</el-drawer>
</el-dialog>
</div>
</template>
@ -458,13 +507,12 @@ import {
delCustomer,
addCustomer,
updateCustomer,
addCustomerFollowRecerd, updateCustomerFollowRecerd, listCustomerFollow
addCustomerFollowRecerd, updateCustomerFollowRecerd, listCustomerFollow, addCustomerOrderRecerd
} from "@/api/system/customer";
import Data from "@/views/system/dict/data";
export default {
name: "potentialCustomer",
dicts: ['to_store_status', 'customer_source','customer_status', 'sys_user_sex', 'customer_level', 'clue_channels','follow_result','follow_up_method'],
dicts: ['to_store_status','car_status' ,'customer_source','customer_status', 'sys_user_sex', 'customer_level', 'clue_channels','follow_result','follow_up_method'],
data() {
return {
drawer:false,
@ -472,6 +520,7 @@ export default {
innerDrawer:false,
dafaultValue:null,
customerId:null,
customerStatus:null,
//
loading: true,
followTitle:null,
@ -495,6 +544,23 @@ export default {
title: "",
//
open: false,
orderOpen:false,
orderTitle:null,
orderForm:{},
orderRules:{
orderDate: [
{ required: true, message: "订单日期不能为空", trigger: "blur" }
],
carInfo: [
{ required: true, message: "车辆信息不能为空", trigger: "blur" }
],
carVin: [
{ required: true, message: "车辆VIN不能为空", trigger: "blur" }
],
carStatus:[
{ required: true, message: "车辆状态不能为空", trigger: "change" }
],
},
//
queryParams: {
pageNum: 1,
@ -507,7 +573,7 @@ export default {
status: null,
wechat: null,
intentionCarModels: null,
preToStoreDate: null,
appointmentTime: null,
orderDate: null
},
//
@ -518,6 +584,13 @@ export default {
followUpDate:null,
customerId:null,
},
followFormShow:{
appointmentTimeShow:false,
intentionLevelShow:false,
nextFollowUpTimeShow:false,
nextFollowUpRecordShow:false,
defeatReasonsShow:false,
},
//
rules: {
userName: [
@ -544,7 +617,7 @@ export default {
followUpRecord:[
{ required: true, message: "跟进记录不能为空", trigger: "blur" }
],
followLevel: [
intentionLevel: [
{ required: true, message: "级别不能为空", trigger: "blur" }
],
followUpMethod:[
@ -556,39 +629,39 @@ export default {
},
//
columns:[
{ key: 0, label: `客户ID`, visible: true },
{ key: 0, label: `客户ID`, visible: false },
{ key: 1, label: `客户名`, visible: true },
{ key: 2, label: `客户昵称`, visible: true },
{ key: 2, label: `客户昵称`, visible: false },
{ key: 3, label: `客户级别`, visible: true },
{ key: 4, label: `用户邮箱`, visible: true },
{ key: 5, label: `手机号码`, visible: true },
{ key: 6, label: `客户性别`, visible: true },
{ key: 7, label: `头像地址`, visible: true },
{ key: 8, label: `线索渠道`, visible: true },
{ key: 9, label: `信息来源`, visible: true },
{ key: 7, label: `头像地址`, visible: false },
{ key: 8, label: `线索渠道`, visible: false },
{ key: 9, label: `信息来源`, visible: false },
{ key: 10, label: `客户居住`, visible: true },
{ key: 11, label: `到店状态`, visible: true },
{ key: 12, label: `删除标志`, visible: true },
{ key: 13, label: `最后登录IP`, visible: true },
{ key: 14, label: `最后登录时间`, visible: true },
{ key: 15, label: `创建者`, visible: true },
{ key: 12, label: `删除标志`, visible: false },
{ key: 13, label: `最后登录IP`, visible: false },
{ key: 14, label: `最后登录时间`, visible: false },
{ key: 15, label: `创建者`, visible: false },
{ key: 16, label: `创建时间`, visible: true },
{ key: 17, label: `更新者`, visible: true },
{ key: 17, label: `更新者`, visible: false },
{ key: 18, label: `更新时间`, visible: true },
{ key: 19, label: `备注`, visible: true },
{ key: 19, label: `备注`, visible: false },
{ key: 20, label: `微信号`, visible: true },
{ key: 21, label: `购车类型`, visible: true },
{ key: 22, label: `已有车辆`, visible: true },
{ key: 23, label: `是否评估`, visible: true },
{ key: 21, label: `购车类型`, visible: false },
{ key: 22, label: `已有车辆`, visible: false },
{ key: 23, label: `是否评估`, visible: false },
{ key: 24, label: `意向车型`, visible: true },
{ key: 25, label: `对比车型`, visible: true },
{ key: 26, label: `是否试驾`, visible: true },
{ key: 27, label: `是否报价`, visible: true },
{ key: 28, label: `是否金融`, visible: true },
{ key: 29, label: `未订车原因`, visible: true },
{ key: 30, label: `预计到店`, visible: true },
{ key: 31, label: `最后到店`, visible: true },
{ key: 32, label: `4S店`, visible: true },
{ key: 25, label: `对比车型`, visible: false },
{ key: 26, label: `是否试驾`, visible: false },
{ key: 27, label: `是否报价`, visible: false },
{ key: 28, label: `是否金融`, visible: false },
{ key: 29, label: `未订车原因`, visible: false },
{ key: 30, label: `预计到店`, visible: false },
{ key: 31, label: `最后到店`, visible: false },
{ key: 32, label: `4S店`, visible: false },
{ key: 33, label: `下单日期`, visible: true },
{ key: 34, label: `跟进次数`, visible: true },
{ key: 35, label: `最新跟进日`, visible: true },
@ -620,18 +693,40 @@ export default {
},
/** 查询客户跟进信息列表 */
getFollowList(customerId) {
let that = this;
this.loading = true;
let queryParams = {
customerId:customerId,
pageNum:1,
pageSize:1000,
followType:'potential'
}
let dictType = that.dict.type;
listCustomerFollow(queryParams).then(response => {
this.followUpList = response.rows;
//
for (let follow of this.followUpList) {
let followUpMethod = this.getDictLableByVal(dictType.follow_up_method,follow.followUpMethod);
let followResult = this.getDictLableByVal(dictType.follow_result,follow.followResult);
let intentionLevel = this.getDictLableByVal(dictType.customer_level,follow.intentionLevel);
follow.followUpMethod = followUpMethod;
follow.followResultDesc = followResult;
follow.intentionLevel = intentionLevel;
}
this.total = response.total;
this.loading = false;
});
},
//val
getDictLableByVal(dictData,val){
let lable = '';
dictData.map(i =>{
if (i.value == val) {
lable = i.label
}
})
return lable
},
//
cancel() {
this.open = false;
@ -670,7 +765,7 @@ export default {
isOffer: null,
isFinance: null,
unBookingCarReason: null,
preToStoreDate: null,
appointmentTime: null,
lastToStoreDate: null,
storeName: null,
orderDate: null
@ -716,14 +811,39 @@ export default {
handleFollow(row){
this.drawer = true;
this.customerId = row.id;
this.followTitle = row.userName + " 跟进记录";
this.customerStatus = row.status;
this.followTitle = row.userName +" "+ row.phoneNumber+" 跟进记录";
this.getFollowList(this.customerId);
},
//
handleToOrder(row){
this.orderForm.customerId = row.id;
this.orderForm.customerName = row.userName;
this.orderForm.carStatus = 'notOut';
this.orderOpen = true;
this.orderTitle = "新增订单";
},
orderSubmitForm(){
this.$refs["orderForm"].validate(valid => {
if (valid) {
addCustomerOrderRecerd(this.orderForm).then(response => {
this.$modal.msgSuccess("订单新增成功");
this.orderOpen = false;
this.getList(this.customerId);
});
}
});
},
orderCancel(){
this.orderOpen = false;
this.orderForm = { };
},
handleDrawerAddFollowUp(){
this.innerDrawer = true;
this.followForm = {};
this.followForm.followUpDate = new Date();
this.followForm.customerId = this.customerId;
this.followForm.followType = this.customerStatus;
},
/** 提交按钮 */
submitForm() {
@ -785,9 +905,9 @@ export default {
let obj = {};
obj.followUpDate = "";
obj.followUpRecord = "";
obj.preToStoreDate = "";
obj.appointmentTime = "";
obj.remark = "";
obj.followLevel = "";
obj.intentionLevel = "";
this.followUpList.push(obj);
},
/** 跟进模块-客户跟进记录删除按钮操作 */
@ -802,6 +922,35 @@ export default {
});
}
},
//
selctRadion(e){
if(e=='fail'){
// this.followRules.defeatReasons = [{required: true, message: "", trigger: "blur"}]
this.followRules.intentionLevel = [];
this.followRules.nextFollowUpTime = [];
this.followFormShow.defeatReasonsShow = true;
this.followFormShow.appointmentTimeShow=false;
this.followFormShow.intentionLevelShow=false;
this.followFormShow.nextFollowUpTimeShow=false;
this.followFormShow.nextFollowUpRecordShow=false;
}else if(e=='going'){
this.followRules.defeatReasons = [];
this.followRules.appointmentTime = [];
this.followFormShow.defeatReasonsShow = false;
this.followFormShow.appointmentTimeShow=false;
this.followFormShow.intentionLevelShow=true;
this.followFormShow.nextFollowUpTimeShow=true;
this.followFormShow.nextFollowUpRecordShow=true;
}else if(e=='maker'){
this.followRules.defeatReasons = [];
this.followFormShow.defeatReasonsShow = false;
this.followFormShow.appointmentTimeShow=true;
this.followFormShow.intentionLevelShow=true;
this.followFormShow.nextFollowUpTimeShow=true;
this.followFormShow.nextFollowUpRecordShow=true;
this.followForm.makerStatus ="waitStore";
}
},
/** 复选框选中数据 */
handleFollowUpSelectionChange(selection) {
this.checkedFollowUp = selection.map(item => item.index)

@ -1,95 +1,46 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="客户" prop="userName">
<el-form-item label="客户" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入客户"
placeholder="请输入客户"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="客户级别" prop="userType">
<el-select v-model="queryParams.userType" placeholder="请选择客户级别" clearable>
<el-option
v-for="dict in dict.type.customer_level"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="手机号码" prop="phoneNumber">
<el-form-item label="客户手机" prop="phoneNumber">
<el-input
v-model="queryParams.phoneNumber"
placeholder="请输入手机号"
placeholder="请输入客户手机号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="线索渠道" prop="clueChannel">
<el-select v-model="queryParams.clueChannel" placeholder="请选择线索渠道" clearable>
<el-option
v-for="dict in dict.type.clue_channels"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="信息来源" prop="dataSource">
<el-select v-model="queryParams.dataSource" placeholder="请选择信息来源" clearable>
<el-option
v-for="dict in dict.type.customer_source"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="到店状态" prop="status">
<el-select v-model="queryParams.storeStatus" placeholder="请选择到店状态" clearable>
<el-option
v-for="dict in dict.type.to_store_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
<el-form-item label="订车时间" prop="orderDate">
<el-date-picker clearable
v-model="queryParams.orderDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择订车时间">
</el-date-picker>
</el-form-item>
<el-form-item label="微信号" prop="wechat">
<el-form-item label="车辆详细" prop="carInfo">
<el-input
v-model="queryParams.wechat"
placeholder="请输入微信号"
v-model="queryParams.carInfo"
placeholder="请输入车辆详细"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="意向车型" prop="intentionCarModels">
<el-form-item label="车辆VIN" prop="carVin">
<el-input
v-model="queryParams.intentionCarModels"
placeholder="请输入意向车型"
v-model="queryParams.carVin"
placeholder="请输入车辆VIN"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="预计到店" prop="preToStoreDate">
<el-date-picker clearable
v-model="queryParams.preToStoreDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择预计到店">
</el-date-picker>
</el-form-item>
<el-form-item label="下单日期" prop="orderDate">
<el-date-picker clearable
v-model="queryParams.orderDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择下单日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button>
@ -97,7 +48,7 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button
type="primary"
plain
@ -128,7 +79,7 @@
@click="handleDelete"
v-hasPermi="['system:customer:remove']"
>删除</el-button>
</el-col>
</el-col>-->
<el-col :span="1.5">
<el-button
type="warning"
@ -145,6 +96,11 @@
<el-table v-loading="loading" :data="customerList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="客户姓名" align="center" prop="userName" width="120" v-if="columns[1].visible" show-overflow-tooltip />
<el-table-column label="客户性别" align="center" prop="sex" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex"/>
</template>
</el-table-column>
<el-table-column label="客户级别" align="center" prop="userType" v-if="columns[3].visible" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.customer_level" :value="scope.row.userType"/>
@ -161,43 +117,39 @@
<dict-tag :options="dict.type.customer_source" :value="scope.row.dataSource"/>
</template>
</el-table-column>
<el-table-column label="客户居住" align="center" prop="liveAddress" width="100" v-if="columns[10].visible" show-overflow-tooltip />
<el-table-column label="到店状态" align="center" prop="status" width="100" v-if="columns[11].visible" show-overflow-tooltip >
<el-table-column label="订单日期" align="center" prop="orderDate" width="120" v-if="columns[33].visible" show-overflow-tooltip >
<template slot-scope="scope">
<dict-tag :options="dict.type.to_store_status" :value="scope.row.storeStatus"/>
<span>{{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="微信号" align="center" prop="wechat" width="110" v-if="columns[20].visible" show-overflow-tooltip />
<el-table-column label="下单日期" align="center" prop="orderDate" width="120" v-if="columns[33].visible" show-overflow-tooltip >
<el-table-column label="车辆详细" align="center" prop="carInfo" width="280"/>
<el-table-column label="车辆VIN" align="center" prop="carVin" width="220" />
<el-table-column label="车辆状态" align="center" prop="carStatus" >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.orderDate, '{y}-{m}-{d}') }}</span>
<dict-tag :options="dict.type.car_status" :value="scope.row.carStatus"/>
</template>
</el-table-column>
<el-table-column label="出库日期" align="center" prop="outDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.outDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<!-- <el-table-column label="是否评估" align="center" prop="isAssessment" />-->
<el-table-column label="意向车型" align="center" prop="intentionCarModels" width="120" v-if="columns[24].visible" show-overflow-tooltip />
<!-- <el-table-column label="对比车型" align="center" prop="contrastCarModels" />
<el-table-column label="是否试驾" align="center" prop="isTestDrive" />
<el-table-column label="是否报价" align="center" prop="isOffer" />
<el-table-column label="是否金融" align="center" prop="isFinance" />-->
<!-- <el-table-column label="最后到店" align="center" prop="lastToStoreDate" width="120">
<el-table-column label="跟进备注" align="center" prop="remark" width="120" />
<el-table-column label="计划跟进日期" align="center" prop="planFollowUpDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastToStoreDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.planFollowUpDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>-->
<el-table-column label="已有车辆" align="center" prop="existModels" v-if="columns[22].visible" show-overflow-tooltip />
<el-table-column label="预计到店" class-name="specialColor" align="center" prop="preToStoreDate" width="120" v-if="columns[30].visible" show-overflow-tooltip >
</el-table-column>
<el-table-column label="实际跟进日期" align="center" prop="actualFollowUpDate" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.preToStoreDate, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.actualFollowUpDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="跟进方式" align="center" prop="followUpMethod" >
<template slot-scope="scope">
<dict-tag :options="dict.type.follow_up_method" :value="scope.row.followUpMethod"/>
</template>
</el-table-column>
<el-table-column label="跟进次数" class-name="specialColor" align="center" prop="followUpTimes" v-if="columns[34].visible" show-overflow-tooltip />
<el-table-column label="最新跟进日" class-name="specialColor" align="center" prop="followUpLastDate" width="100" v-if="columns[35].visible" show-overflow-tooltip />
<el-table-column label="最新跟进级别" class-name="specialColor" align="center" prop="followUpLastLevel" width="100" v-if="columns[36].visible" show-overflow-tooltip />
<el-table-column label="建议下次跟进日" class-name="specialColor" align="center" prop="proposalNextFollowDate" width="120" v-if="columns[37].visible" show-overflow-tooltip />
<el-table-column label="跟进超期" class-name="specialColor" align="center" prop="followUpOverdueDate" width="120" v-if="columns[38].visible" show-overflow-tooltip />
<el-table-column label="未订车原因" align="center" prop="unBookingCarReason" width="110" show-overflow-tooltip v-if="columns[29].visible" show-overflow-tooltip />
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip v-if="columns[19].visible" />
<el-table-column label="操作" width="160" align="center" fixed="right" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
@ -206,8 +158,8 @@
icon="el-icon-edit"
@click="handleFollow(scope.row)"
v-hasPermi="['system:customer:edit']"
>跟进</el-button>
<el-button
>回访</el-button>
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
@ -220,7 +172,7 @@
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:customer:remove']"
>删除</el-button>
>删除</el-button>-->
</template>
</el-table-column>
</el-table>
@ -297,7 +249,7 @@
></el-option>
</el-select>
</el-form-item>
<el-form-item label="信息来源" prop="dataSource">
<!-- <el-form-item label="信息来源" prop="dataSource">
<el-select v-model="form.dataSource" placeholder="请选择信息来源">
<el-option
v-for="dict in dict.type.customer_source"
@ -309,8 +261,8 @@
</el-form-item>
<el-form-item label="客户居住" prop="liveAddress">
<el-input v-model="form.liveAddress" placeholder="请输入客户居住" />
</el-form-item>
<el-form-item label="到店状态" prop="status">
</el-form-item>-->
<!-- <el-form-item label="到店状态" prop="status">
<el-select v-model="form.storeStatus" placeholder="请选择到店状态">
<el-option
v-for="dict in dict.type.to_store_status"
@ -319,7 +271,7 @@
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-form-item>-->
<el-form-item label="已有车型" prop="existModels">
<el-input v-model="form.existModels" placeholder="请输入已有车型" />
</el-form-item>
@ -379,33 +331,43 @@
<el-timeline :reverse="reverse">
<el-timeline-item placement="top" v-for="(follow, index) in followUpList" :key="index" :timestamp="follow.followUpDate">
<el-card shadow="hover">
<p><el-tag>跟进方式</el-tag>
<el-select v-model="follow.followUpMethod" disabled>
<el-option
v-for="dict in dict.type.follow_up_method"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</p>
<p><el-tag>级别</el-tag> {{follow.followLevel}} </p>
<h4><el-tag>记录</el-tag> {{follow.followUpRecord}}</h4>
<p> <el-tag>再次预约到店日期</el-tag> {{follow.preToStoreDate}} </p>
<p><el-tag>跟进方式:</el-tag> {{follow.followUpMethod}} </p>
<p> <el-tag>跟进目的:</el-tag> {{follow.objective}} </p>
<p><el-tag>跟进记录:</el-tag> {{follow.followUpRecord}}</p>
<p>提交于 {{follow.createTime}}</p>
</el-card>
</el-timeline-item>
</el-timeline>
<el-drawer title="新增跟进日志" :append-to-body="true" :visible.sync="innerDrawer">
<el-form ref="followForm" :model="followForm" :rules="followRules" label-width="140px">
<el-form-item label="跟进日期" prop="followUpDate">
<el-date-picker clearable
<el-form-item label="计划跟进日期" prop="followUpDate">
<el-date-picker clearable disabled
v-model="followForm.followUpDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择跟进日期">
</el-date-picker>
</el-form-item>
<el-form-item label="跟进备注" prop="followUpRecord">
<el-input v-model="followForm.remark" disabled placeholder="请输入内容" />
</el-form-item>
<el-divider content-position="left">订单车型</el-divider>
<el-descriptions direction="vertical" :column="6" border size="mini">
<!-- <el-descriptions-item label="状态">正常</el-descriptions-item>-->
<el-descriptions-item label="VIN" show-overflow-tooltip>{{followForm.carVin}}</el-descriptions-item>
<el-descriptions-item label="车辆信息" show-overflow-tooltip>{{followForm.carInfo}}</el-descriptions-item>
</el-descriptions>
<el-divider></el-divider>
<el-form-item label="跟进目的" prop="objectiveList">
<el-select v-model="followForm.objectiveList" multiple placeholder="请选择">
<el-option
v-for="item in objectiveList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="跟进方式" prop="followUpMethod">
<el-select v-model="followForm.followUpMethod" placeholder="请选择跟进方式" clearable>
<el-option
@ -419,27 +381,6 @@
<el-form-item label="跟进记录" prop="followUpRecord">
<el-input v-model="followForm.followUpRecord" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="级别" prop="followLevel">
<el-select v-model="followForm.followLevel" placeholder="请选择级别" clearable>
<el-option
v-for="dict in dict.type.customer_level"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="再次预约到店日期" prop="preToStoreDate">
<el-date-picker clearable
v-model="followForm.preToStoreDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择再次预约到店日期">
</el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="followForm.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div style="text-align: center">
<el-button type="primary" @click="submitFollowForm"> </el-button>
@ -452,19 +393,17 @@
</template>
<script>
import { getCustomerOrderPage, getCustomerOrder, delCustomerOrder, addCustomerOrder, updateCustomerOrder } from "@/api/system/customerOrder";
import {
listCustomer,
getCustomer,
delCustomer,
addCustomer,
updateCustomer,
addCustomerFollowRecerd, updateCustomerFollowRecerd, listCustomerFollow
} from "@/api/system/customer";
import Data from "@/views/system/dict/data";
export default {
name: "salesFollowCustomer",
dicts: ['to_store_status', 'customer_source','customer_status', 'sys_user_sex', 'customer_level', 'clue_channels','follow_result','follow_up_method'],
dicts: ['to_store_status', 'customer_source','customer_status', 'sys_user_sex', 'customer_level', 'clue_channels','follow_result','car_status','follow_up_method'],
data() {
return {
drawer:false,
@ -472,6 +411,7 @@ export default {
innerDrawer:false,
dafaultValue:null,
customerId:null,
customerRow:null,
//
loading: true,
followTitle:null,
@ -508,15 +448,24 @@ export default {
wechat: null,
intentionCarModels: null,
preToStoreDate: null,
orderDate: null
orderDate: null,
orderByColumn:'out_date',
isAsc:'desc'
},
//
form: {
},
objectiveList:[
{label:"三包政策",value:"三包政策"},
{label:"操作说明",value:"操作说明"},
{label:"7日电访说明",value:"7日电访说明"},
{label:"首保关怀提醒",value:"首保关怀提醒"},
],
followForm:{
followUpDate:null,
customerId:null,
objectiveList:[]
},
//
rules: {
@ -538,20 +487,11 @@ export default {
},
//
followRules: {
followUpDate: [
{ required: true, message: "跟进日期不能为空", trigger: "blur" }
],
followUpRecord:[
{ required: true, message: "跟进记录不能为空", trigger: "blur" }
],
followLevel: [
{ required: true, message: "级别不能为空", trigger: "blur" }
],
followUpMethod:[
{ required: true, message: "跟进方式不能为空", trigger: "blur" }
],
followResult:[
{ required: true, message: "跟进结果不能为空", trigger: "blur" }
objectiveList:[
{ type: 'array', required: true, message: '请至少选择一个跟进目的', trigger: 'change' }
]
},
//
@ -612,7 +552,7 @@ export default {
getList() {
this.loading = true;
this.queryParams.status = 'order';
listCustomer(this.queryParams).then(response => {
getCustomerOrderPage(this.queryParams).then(response => {
this.customerList = response.rows;
this.total = response.total;
this.loading = false;
@ -625,13 +565,30 @@ export default {
customerId:customerId,
pageNum:1,
pageSize:1000,
followType:'order'
}
let dictType = this.dict.type;
listCustomerFollow(queryParams).then(response => {
this.followUpList = response.rows;
//
for (let follow of this.followUpList) {
let followUpMethod = this.getDictLableByVal(dictType.follow_up_method,follow.followUpMethod);
follow.followUpMethod = followUpMethod;
}
this.total = response.total;
this.loading = false;
});
},
//val
getDictLableByVal(dictData,val){
let lable = '';
dictData.map(i =>{
if (i.value == val) {
lable = i.label
}
})
return lable
},
//
cancel() {
this.open = false;
@ -715,6 +672,7 @@ export default {
/**跟进按钮**/
handleFollow(row){
this.drawer = true;
this.customerRow = row;
this.customerId = row.id;
this.followTitle = row.userName + " 跟进记录";
this.getFollowList(this.customerId);
@ -724,6 +682,10 @@ export default {
this.followForm = {};
this.followForm.followUpDate = new Date();
this.followForm.customerId = this.customerId;
this.followForm.remark = "回访任务-7日回访";
this.followForm.carVin = this.customerRow.carVin;
this.followForm.carInfo = this.customerRow.carInfo;
this.followForm.planFollowUpDate = this.customerRow.planFollowUpDate;
},
/** 提交按钮 */
submitForm() {
@ -756,6 +718,9 @@ export default {
this.getFollowList(this.customerId);
});
} else {
this.followForm.objective = this.followForm.objectiveList.join(",");
this.followForm.followType=this.customerRow.status;
this.followForm.customerId=this.customerId;
addCustomerFollowRecerd(this.followForm).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;

Loading…
Cancel
Save