wanghuan преди 3 години
родител
ревизия
37463a5e8e

+ 4 - 0
src/api/manage.js

@@ -26,6 +26,9 @@ export function postAction(url,parameter) {
   })
 }
 
+
+
+
 //post method= {post | put}
 export function httpAction(url,parameter,method) {
   let sign = signMd5Utils.getSign(url, parameter);
@@ -40,6 +43,7 @@ export function httpAction(url,parameter,method) {
   })
 }
 
+
 //put
 export function putAction(url,parameter) {
   return axios({

+ 49 - 0
src/utils/util.js

@@ -626,4 +626,53 @@ export function aspectAroundFunction(obj, funcName, callback) {
       },
     })
   }
+}
+
+export function getAge(strBirthday) {
+  var returnAge;
+  var strBirthdayArr=strBirthday.split("-");
+  var birthYear = strBirthdayArr[0];
+  var birthMonth = strBirthdayArr[1];
+  var birthDay = strBirthdayArr[2];
+  var d = new Date();
+  var nowYear = d.getFullYear();
+  var nowMonth = d.getMonth() + 1;
+  var nowDay = d.getDate();
+  
+  if(nowYear == birthYear){
+      returnAge = 0;//同年 则为0岁
+  }
+  else{
+      var ageDiff = nowYear - birthYear ; //年之差
+      if(ageDiff > 0){
+          if(nowMonth == birthMonth) {
+              var dayDiff = nowDay - birthDay;//日之差
+              if(dayDiff < 0)
+              {
+                  returnAge = ageDiff - 1;
+              }
+              else
+              {
+                  returnAge = ageDiff ;
+              }
+          }
+          else
+          {
+              var monthDiff = nowMonth - birthMonth;//月之差
+              if(monthDiff < 0)
+              {
+                  returnAge = ageDiff - 1;
+              }
+              else
+              {
+                  returnAge = ageDiff ;
+              }
+          }
+      }
+      else
+      {
+          returnAge = -1;//返回-1 表示出生日期输入错误 晚于今天
+      }
+  }
+  return returnAge;//返回周岁年龄
 }

+ 111 - 0
src/views/mili/components/DropDownSearch.vue

@@ -0,0 +1,111 @@
+<template>
+  <a-dropdown :trigger="['click']" v-model="visible" style="margin-left: 10px;">
+    <a v-if="fontColor" class="ant-dropdown-link" href="#">
+      {{changeName}}
+      <a-icon type="down" />
+    </a>
+    <a v-else class="ant-dropdown-link" href="#" style="color: #5c6065;">
+      {{changeName}}
+      <a-icon type="down" />
+    </a>
+    <a-menu slot="overlay">
+      <a-menu-item>
+        <a-input placeholder="搜索" v-model="keyword" @change="searchQuery" ></a-input>
+      </a-menu-item>
+      <a-menu-item v-if="QueryListLoad[0].id !== 999" key="0" @click="clickList">全部</a-menu-item>
+      <a-menu-item v-for="item in QueryListLoad" :key="item.id" @click="clickList">
+        {{item.name}}
+      </a-menu-item>
+    </a-menu>
+  </a-dropdown>
+</template>
+<script>
+export default {
+  name: 'DropDownSearch',
+  data () {
+    return {
+      visible: false,
+      changeName: undefined,
+      fontColor: false,
+      keyword: null,
+      QueryListLoad: {},
+    }
+  },
+  computed: {
+    style () {
+      return {
+        left: this.left + 'px',
+        top: this.top + 'px'
+      }
+    }
+  },
+  created () {
+     
+  },
+  props: ['menuName','QueryList','QueryReset'],
+    watch: {
+      QueryList: {
+        immediate: true,
+        handler() {
+          this.changeName = this.menuName;
+          this.QueryListLoad = this.QueryList;
+        },
+      },
+      QueryReset: {
+        immediate: true,
+        handler() {
+          this.changeName = this.menuName;
+          this.QueryListLoad = this.QueryList;
+          this.keyword = null;
+          this.fontColor = false;
+          this.visible = false;
+        },
+      },
+      visible: {
+        immediate: true,
+        handler() {
+          if(this.visible) { //完美 有延迟动画不能关闭的时候刷新
+            this.keyword = null;
+            this.QueryListLoad = this.QueryList;
+          }
+        }
+      }
+    },
+  methods: {
+    clickList(e) {
+      if(String(e.key) === "999"){
+        this.visible = false;
+        this.keyword = null;
+      }
+      else if(String(e.key) === "0") {
+        this.changeName = this.menuName;
+        this.fontColor = false;
+        //向父类传值
+      } 
+      else {
+        this.fontColor = true;
+        this.changeName = this.QueryList.find(item => {return item.id == e.key }).name;
+        //向父类传值
+      }
+      this.visible = false;
+      //动画有延迟,点击无时间  服了 看来只能watch了
+      
+    },
+    searchQuery() { //模糊查询
+      let listTemp = [];
+      if(this.keyword !== null && this.keyword !== "" && this.keyword !== " " ) {
+        listTemp = this.QueryListLoad.filter((p)=>{
+          return p.name.indexOf(this.keyword) !==-1
+        })
+        if(listTemp.length === 0) {
+          this.QueryListLoad = [{"id": 999 , "name": "暂无数据"}];
+        } else {
+          this.QueryListLoad = listTemp;
+        }
+      } else {
+        this.QueryListLoad = this.QueryList;
+      }
+    }
+  }
+}
+</script>

+ 31 - 748
src/views/mili/customer/CustomerPotentialList.vue

@@ -1,766 +1,49 @@
 <template>
   <a-card :bordered="false">
-    <!-- 查询区域 -->
-    <div class="table-page-search-wrapper">
-      <a-form layout="inline" @keyup.enter.native="searchQuery">
-        <a-row :gutter="24">
-          <a-col :xl="6" :lg="7" :md="8" :sm="24">
-            <a-form-item label="校区ID">
-              <j-dict-select-tag placeholder="请选择校区ID" v-model="queryParam.schoolDistrictId" dictCode="school_organization,name,id"/>
-            </a-form-item>
-          </a-col>
-          <a-col :xl="6" :lg="7" :md="8" :sm="24">
-            <a-form-item label="姓名">
-              <a-input placeholder="请输入姓名" v-model="queryParam.name"></a-input>
-            </a-form-item>
-          </a-col>
-          <template v-if="toggleSearchStatus">
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="家长姓名">
-                <a-input placeholder="请输入家长姓名" v-model="queryParam.contactName"></a-input>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="家长电话">
-                <a-input placeholder="请输入家长电话" v-model="queryParam.contactPhone"></a-input>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="学校">
-                <j-dict-select-tag placeholder="请选择学校" v-model="queryParam.school" dictCode="school_school,name,id"/>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="年级">
-                <j-dict-select-tag placeholder="请选择年级" v-model="queryParam.grade" dictCode="grade"/>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="渠道类型">
-                <j-tree-select
-                ref="treeSelect"
-                placeholder="请选择渠道类型"
-                v-model="queryParam.channelType"
-                dict="promotion_channel,name,id"
-                pidValue="0"
-                >
-              </j-tree-select>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="顾问">
-                <j-select-user-by-dep placeholder="请选择顾问" v-model="queryParam.saleCode"/>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="推荐人">
-                <a-input placeholder="请输入推荐人" v-model="queryParam.referencesPhone"></a-input>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="采单员">
-                <j-select-user-by-dep placeholder="请选择采单员" v-model="queryParam.collectinoCode"/>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="状态">
-                <j-dict-select-tag placeholder="请选择状态" v-model="queryParam.status" dictCode="pc_status"/>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="跟进状态">
-                <j-dict-select-tag placeholder="请选择跟进状态" v-model="queryParam.followStatus" dictCode="pc_follow_status"/>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="上次跟进">
-                <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择上次跟进" v-model="queryParam.lastFollowTime"></j-date>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="下次跟进">
-                <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择下次跟进" v-model="queryParam.nextFollowTime"></j-date>
-              </a-form-item>
-            </a-col>
-          </template>
-          <a-col :xl="6" :lg="7" :md="8" :sm="24">
-            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
-              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
-              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
-              <a @click="handleToggleSearch" style="margin-left: 8px">
-                {{ toggleSearchStatus ? '收起' : '展开' }}
-                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
-              </a>
-            </span>
-          </a-col>
-        </a-row>
-      </a-form>
-    </div>
-    <!-- 查询区域-END -->
-
-    <!-- 操作按钮区域 -->
-    <div class="table-operator">
-      <!-- <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button> -->
-      <a-button type="primary" icon="download" @click="handleExportXls('潜客管理')">导出</a-button>
-      <!-- <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
-        <a-button type="primary" icon="import">导入</a-button>
-      </a-upload> -->
-      <!-- 高级查询区域 -->
-      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
-    </div>
-
-    <!-- table区域-begin -->
-    <div>
-      <a-table
-        ref="table"
-        size="middle"
-        :scroll="{x:true}"
-        bordered
-        rowKey="id"
-        :columns="columns"
-        :dataSource="dataSource"
-        :pagination="ipagination"
-        :loading="loading"
-        class="j-table-force-nowrap"
-        @change="handleTableChange">
-        <template slot="htmlSlot" slot-scope="text">
-          <div v-html="text"></div>
-        </template>
-        <template slot="imgSlot" slot-scope="text,record">
-          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
-          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
-        </template>
-        <template slot="fileSlot" slot-scope="text">
-          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
-          <a-button
-            v-else
-            :ghost="true"
-            type="primary"
-            icon="download"
-            size="small"
-            @click="downloadFile(text)">
-            下载
-          </a-button>
-        </template>
-
-        <span slot="action" slot-scope="text, record">
-          <a @click="handleEdit(record)">编辑</a>
-          <a-divider type="vertical" />
-          <a @click="handleDetail(record)">详情</a>
-          <!-- <a-divider type="vertical" />
-          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
-                  <a>删除</a>
-                </a-popconfirm> -->
-          <a-divider type="vertical" v-has="'user:appoint'"/>
-          <a @click="handleFollow(record)" v-has="'user:appoint'">跟进</a>
-          <a-divider type="vertical" v-has="'user:appoint'"/>
-          <a @click="handleVisiting(record)" v-has="'user:appoint'">预约来访</a>
-          <a-divider type="vertical" v-has="'user:appoint'"/>
-          <a @click="handleAudition(record)" v-has="'user:appoint'">试听</a>
-          <a-divider type="vertical" v-has="'user:appoint'"/>
-          <a-dropdown>
-            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
-            <a-menu slot="overlay">
-              <a-menu-item>
-                <a @click="handleSign(record)" v-has="'user:appoint'">报名</a>
-              </a-menu-item>
-              <a-menu-item>
-                <a @click="handleReject(record)" v-has="'user:appoint'">暂无意向</a>
-              </a-menu-item>
-              <a-menu-item>
-                 <a @click="handleInvalid(record)" v-has="'user:appoint'">标为无效</a>
-              </a-menu-item>
-            </a-menu>
-          </a-dropdown>
-        </span>
-
-       <!--插槽NNNN-->
-       <a slot="detail" slot-scope="text, record" @click="handleFollowDetail(record)" >{{text}}</a>
-      </a-table>
-    </div>
-    <!--弹出窗口-->
-    <a-modal
-      title="跟进信息新增"
-      ok-text="确认" 
-      cancel-text="取消"
-      :visible="followVisible"
-      :confirm-loading="followloading"
-      @ok="followOk"
-      @cancel="followCancel">
-      <a-form-item label="跟进类别">
-        <a-input placeholder="请输入跟进类别" v-model="followType"></a-input>
-      </a-form-item>
-      <a-form-item label="跟进内容">
-        <a-textarea v-model="followContent" rows="4" placeholder="请输入跟进内容" />
-      </a-form-item>
-      <a-form-item label="下次跟进">
-        <a-date-picker v-model="nextFollowTime" 
-          name = "nextFollowTime"
-          dateFormat="YYYY-MM-DD"
-          :disabledDate="disabledDate"
-          v-decorator="['nextFollowTime',rules.date]"
-          @change="onChangeTime"
-          ></a-date-picker>
-      </a-form-item>
-      <a-form-item label="图片"  style="width: 400px">
-        <j-image-upload text="上传" v-model="fileList" :isMultiple="true" ></j-image-upload>
-      </a-form-item>
-    </a-modal>
-
-     <a-modal
-      title="来访信息添加"
-      ok-text="确认" 
-      cancel-text="取消"
-      :visible="visitingVisible"
-      :confirm-loading="visitingloading"
-      @ok="visitingOk"
-      @cancel="visitingCancel">
-      <a-form-item label="客户来访日期"  style="width: 400px">
-        <a-date-picker v-model="dateStr" 
-        name = "dateStr"
-        dateFormat="YYYY-MM-DD"
-        :disabledDate="disabledDate"
-        v-decorator="['dateStr',rules.date]"
-        ></a-date-picker>
-      </a-form-item>
-    </a-modal>
-
-    <a-modal
-      title="试听信息添加"
-      ok-text="确认" 
-      cancel-text="取消"
-      :visible="auditionVisible"
-      :confirm-loading="auditionloading"
-      @ok="auditionOk"
-      @cancel="auditionCancel">
-      <a-form-item label="客户试听日期"  style="width: 400px">
-        <a-date-picker v-model="dateAudition" 
-        name = "dateAudition"
-        dateFormat="YYYY-MM-DD"
-        :disabledDate="disabledDate"
-        v-decorator="['dateAudition',rules.date]"
-        ></a-date-picker>
-      </a-form-item>
-    </a-modal>
-
-
-    <a-modal
-      title="跟进详情"
-      :visible="followDetailVisible"
-      :width=900
-      @cancel="cancelFollowDetail"
-      cancelText="关闭"
-      :body-style="{width:200}"
-      >
-      <a-list item-layout="horizontal" :data-source="dataFollowDetail">
-          <a-list-item :key="index" v-for="(item, index) in dataFollowDetail">
-              <a-list-item-meta>
-               <template #title>
-                <a-descriptions bordered>
-                  <a-descriptions-item label="潜客姓名">{{item.cpName}}</a-descriptions-item>
-                  <a-descriptions-item label="跟进人">{{item.salesName}}</a-descriptions-item>
-                  <a-descriptions-item label="跟进日期">{{item.createTime}}</a-descriptions-item>
-                  <a-descriptions-item label="校区" :span="1">{{item.schoolDistrictName}}</a-descriptions-item>
-                  <a-descriptions-item label="跟进类型" :span="2">{{item.followType}}</a-descriptions-item>
-                  <a-descriptions-item label="跟进内容" :span="3">{{item.followContent}}</a-descriptions-item>
-                  <a-descriptions-item label="图片" :span="3">
-                   <!-- 为啥不能用a-image? -->
-                   <div v-if="item.picList != null">
-                      <div v-if = "(item.picList.more)">
-                        <div v-for="(imgItem,index) in item.picList.imgPath" :key="index">
-                          <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
-                            <div
-                              style="width: 100%;height: 100%;position: relative;padding: 8px;border: 0px solid #d9d9d9;border-radius: 4px;">
-                              <img style="width: 100%;" :src="imgItem.imgUrl" :preview="item.picList.key">
-                            </div>
-                          </div>
-                        </div>
-                      </div>
-                      <div v-else>
-                         <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
-                            <div
-                              style="width: 100%;height: 100%;position: relative;padding: 8px;border: 0px solid #d9d9d9;border-radius: 4px;">
-                              <img style="width: 100%;" :src="item.picList.imgPath.imgUrl" :preview="item.picList.key">
-                            </div>
-                          </div>
-                      </div>
-                   </div>
-                   <div v-else>
-                    没图片
-                   </div>
-                      <!-- <div v-for="(fileDetail,index) in item.picList" :key="index">
-                       <div v-if="!(fileDetail.more)">
-                           <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
-                             <div
-                              style="width: 100%;height: 100%;position: relative;padding: 8px;border: 1px solid #d9d9d9;border-radius: 4px;">
-                              <img style="width: 100%;" :src="fileDetail.imgUrl" :preview="item.picList.key">
-                              111
-                            </div>
-                          </div>
-                       </div>
-                       <div v-else>
-                          more
-                       </div> -->
-
-                  </a-descriptions-item>
-                </a-descriptions>
-               </template>
-            </a-list-item-meta>
-          </a-list-item>
-      </a-list>
-
-       <template slot="footer">
-        <a-button key="back" @click="cancelFollowDetail">关闭</a-button>
-      </template>
-    </a-modal>
-
-
-    <customer-potential-modal ref="modalForm" @ok="modalFormOk"></customer-potential-modal>
+    <a-tabs @change="handleChangeTab" :tab-bar-style="{marginTop: '-20px', paddingLeft: '0px'}">
+      <a-tab-pane tab="全部潜客" key="1">
+        <PotentialListTabs :key="timer1" :tabPara = "1" />
+      </a-tab-pane>
+
+      <a-tab-pane tab="我的潜客" key="2">
+        <PotentialListTabs :key="timer2" :tabPara = "2"/>
+      </a-tab-pane>
+
+      <a-tab-pane tab="公池" key="3">
+        <PotentialListTabPublic :key="timer3" :tabPara = "3"/>
+      </a-tab-pane>
+    </a-tabs>
   </a-card>
 </template>
 
 <script>
-
-  import '@/assets/less/TableExpand.less'
-  import { mixinDevice } from '@/utils/mixin'
-  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
-  import CustomerPotentialModal from './modules/CustomerPotentialModal'
-  import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
-  import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
-  import {postAction} from '@/api/manage'
-  import moment from 'moment'
-  import JImageUpload from '@/components/jeecg/JImageUpload'
-  import { defineComponent } from 'vue';
-  import store from '@/store'
+  import PotentialListTabs from './modules/PotentialListTabs.vue'
+  import PotentialListTabPublic from './modules/PotentialListTabPublic.vue'
   export default {
     name: 'CustomerPotentialList',
-    mixins:[JeecgListMixin, mixinDevice],
-    components: {
-      CustomerPotentialModal,JSelectMultiUser,JImageUpload
-    },
-    data () {
+    components: { PotentialListTabs,PotentialListTabPublic },
+    data() {
       return {
-        description: '潜客管理管理页面',
-        followVisible: false,
-        followloading: false,
-        dataFollow:"",
-        followType:"",
-        followContent:"",
-        followDetailVisible: false,
-        nextFollowTime:"",
-        realFollowTime:"",
-        fileList:[],
-        visitingVisible: false,
-        visitingloading: false,
-        dataVisit:"",
-        dateStr:"",
-        auditionVisible: false,
-        auditionloading: false,
-        dataAudition:"",
-        dateAudition:"",
-        form: this.$form.createForm(this),
-        users: "",
-        dataFollowDetail: [],
-        // 表头
-        columns: [
-          {
-            title: '#',
-            dataIndex: '',
-            key:'rowIndex',
-            width:60,
-            align:"center",
-            customRender:function (t,r,index) {
-              return parseInt(index)+1;
-            }
-          },
-          {
-            title:'校区ID',
-            align:"center",
-            dataIndex: 'schoolDistrictId_dictText'
-          },
-          {
-            title:'姓名',
-            align:"center",
-            dataIndex: 'name',
-            scopedSlots: { customRender: 'detail' }
-          },
-          {
-            title:'性别',
-            align:"center",
-            dataIndex: 'sex_dictText'
-          },
-          {
-            title:'家长电话',
-            align:"center",
-            dataIndex: 'contactPhone'
-          },
-          {
-            title:'意向课程',
-            align:"center",
-            dataIndex: 'intendedCourse_dictText'
-          },
-          {
-            title:'顾问',
-            align:"center",
-            dataIndex: 'saleCode_dictText'
-          },
-          {
-            title:'状态',
-            align:"center",
-            dataIndex: 'status_dictText'
-          },
-          {
-            title:'跟进状态',
-            align:"center",
-            dataIndex: 'followStatus_dictText'
-          },
-          {
-            title:'上次跟进',
-            align:"center",
-            dataIndex: 'lastFollowTime'
-          },
-          {
-            title:'下次跟进',
-            align:"center",
-            dataIndex: 'nextFollowTime'
-          },
-          {
-            title: '操作',
-            dataIndex: 'action',
-            align:"center",
-            fixed:"right",
-            width:147,
-            scopedSlots: { customRender: 'action' }
-          }
-        ],
-        rules: {
-          date: [
-            { required: true, message: '请输入预约日期!', trigger: 'blur'},
-           ],
-        },
-        url: {
-          list: "/customer/customerPotential/list",
-          delete: "/customer/customerPotential/delete",
-          deleteBatch: "/customer/customerPotential/deleteBatch",
-          exportXlsUrl: "/customer/customerPotential/exportXls",
-          importExcelUrl: "customer/customerPotential/importExcel",
-          
-        },
-        dictOptions:{},
-        superFieldList:[],
-        imageSource: [{
-          key:0,
-          fileDetails:[
-            {
-              imgUrl:"https://static.jeecg.com/upload/test/3a4490d5d1cd495b826e528537a47cc1.jpg"
-            },
-            {
-              imgUrl:"https://static.jeecg.com/temp/国炬软件logo_1606575029126.png"
-            }
-          ]
-          },{
-            key:1,
-            fileDetails:[
-              {
-                imgUrl:"https://static.jeecg.com/upload/test/u27356337152749454924fm27gp0_1588149731821.jpg"
-              },
-              {
-                imgUrl:"https://static.jeecg.com/upload/test/1_1588149743473.jpg"
-              }
-            ]
-          }
-      ],
+        showCustomerLogs: 0,
+        timer1: '',
+        timer2: '',
+        timer3: ''
       }
     },
-    created() {
-      this.getSuperFieldList();
-    },
-    computed: {
-      importExcelUrl: function(){
-        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
-      },
-    },
     methods: {
-      initDictConfig(){
-      },
-      disabledDate(current) {
-        return current < moment().endOf("day"); // 当前时间之前的所有日期都禁用
-      },
-      getSuperFieldList(){
-        let fieldList=[];
-        fieldList.push({type:'int',value:'schoolDistrictId',text:'校区ID',dictCode:"school_organization,name,id"})
-        fieldList.push({type:'string',value:'name',text:'姓名',dictCode:''})
-        fieldList.push({type:'string',value:'nickname',text:'昵称',dictCode:''})
-        fieldList.push({type:'int',value:'sex',text:'性别',dictCode:'sex'})
-        fieldList.push({type:'string',value:'contactName',text:'家长姓名',dictCode:''})
-        fieldList.push({type:'string',value:'contactPhone',text:'家长电话',dictCode:''})
-        fieldList.push({type:'string',value:'contact1Name',text:'备选联系人1',dictCode:''})
-        fieldList.push({type:'string',value:'contact1Phone',text:'备选联系人1电话',dictCode:''})
-        fieldList.push({type:'string',value:'contact2Name',text:'备选联系人2',dictCode:''})
-        fieldList.push({type:'string',value:'contact2Phone',text:'备选联系人2电话',dictCode:''})
-        fieldList.push({type:'int',value:'age',text:'年龄',dictCode:''})
-        fieldList.push({type:'date',value:'birthday',text:'生日'})
-        fieldList.push({type:'string',value:'school',text:'学校',dictCode:"school_school,name,id"})
-        fieldList.push({type:'string',value:'grade',text:'年级',dictCode:'grade'})
-        fieldList.push({type:'string',value:'class',text:'班级',dictCode:''})
-        fieldList.push({type:'string',value:'idCard',text:'身份证',dictCode:''})
-        fieldList.push({type:'string',value:'address',text:'住址',dictCode:''})
-        fieldList.push({type:'string',value:'channelType',text:'渠道类型'})
-        fieldList.push({type:'string',value:'intendedCourse',text:'意向课程',dictCode:"school_curriculum,name,id"})
-        fieldList.push({type:'int',value:'intendedDegress',text:'意向度',dictCode:'intention_status'})
-        fieldList.push({type:'sel_user',value:'saleCode',text:'顾问'})
-        fieldList.push({type:'string',value:'referencesPhone',text:'推荐人',dictCode:''})
-        fieldList.push({type:'sel_user',value:'collectinoCode',text:'采单员'})
-        fieldList.push({type:'int',value:'status',text:'状态',dictCode:'pc_status'})
-        fieldList.push({type:'int',value:'followStatus',text:'跟进状态',dictCode:'pc_follow_status'})
-        fieldList.push({type:'datetime',value:'lastFollowTime',text:'上次跟进'})
-        fieldList.push({type:'datetime',value:'nextFollowTime',text:'下次跟进'})
-        fieldList.push({type:'Blob',value:'mark',text:'备注',dictCode:''})
-        this.superFieldList = fieldList
-      },
-      handleFollow(row) {
-        // addloading
-        this.followVisible = true;
-        this.dataFollow = row;
-      },
-      followOk() {
-        if (this.followType == "") {
-          this.$message.warn('请输入跟进类型');
-          return;
-        }
-        if (this.followContent == "") {
-          this.$message.warn('请输入跟进内容');
-          return;
-        }
-        if (this.nextFollowTime == "") {
-          this.$message.warn('请输入跟进日期');
-          return;
-        }
-        let params = {
-          schoolDistrictId: this.dataFollow.schoolDistrictId,
-          cpId: this.dataFollow.id,
-          followType:this.followType,
-          followContent:this.followContent,
-          followPic:this.fileList,
-          salesCode:this.dataFollow.saleCode,
-          createBy:store.getters.userInfo.username,
-          nextFollowTime:this.realFollowTime
-        }
-        console.log(params);
-        this.followloading = true;
-        postAction("/customer/customerFollow/addFollow", params).then((res) => {
-          if (res.success) {
-            this.$emit('ok');
-            this.$message.success('添加成功');
-          } else {
-            this.$message.warn('添加失败:' + res.message);
-          }
-        }).finally(() => {
-          this.followloading = false;
-          this.followVisible = false;
-          this.followType = "";
-          this.followContent = "";
-          this.fileList = "";
-          this.dataFollow = "";
-          this.nextFollowTime = "";
-          this.realFollowTime = "";
-          this.loadData();
-        });
-      },
-      followCancel() {
-        if(JSON.stringify(this.fileList) !== '[]' || Object.keys(this.fileList).length !== 0) {
-          let bizPath =[];
-          if(this.fileList.indexOf(",")!= -1) {
-            bizPath = this.fileList.split(',');
-          }else {
-            bizPath.push(this.fileList)
-          }
-          postAction("/sys/common/delUploadTemp", bizPath).then((res) => {
-          });
-        }
-        this.fileList = [];
-        this.dataFollow = "";
-        this.followVisible = false;
-        this.followType = "";
-        this.followContent = "";
-        this.nextFollowTime = "";
-        this.realFollowTime = "";
-      },
-      handleSign(row) {
-        let params = {
-          id: row.id,
-          status: 2,
-          followStatus: 8,
-          name: row.name,
-          contactPhone: row.contactPhone
-        }
-        postAction("/customer/customerPotential/sign", params).then((res) => {
-          if (res.success) {
-            this.$emit('ok');
-            this.$message.success(res.message);
-          } else {
-            this.$message.warn('报名失败:' + res.message);
-          }
-        }).finally(() => {
-          this.dialogloading = false;
-          this.dialogPvVisible = false;
-          this.loadData();
-        });
-      },
-      handleReject(row) {
-         let params = {
-          id: row.id,
-          status: 3,
-          followStatus: 1,
-          name: row.name,
-          contactPhone: row.contactPhone
-        }
-        postAction("/customer/customerPotential/statusEdit", params).then((res) => {
-          if (res.success) {
-            this.$emit('ok');
-            this.$message.success(res.message);
-          } else {
-            this.$message.warn('修改失败:' + res.message);
-          }
-        }).finally(() => {
-          this.dialogloading = false;
-          this.dialogPvVisible = false;
-          this.loadData();
-        });
-      },
-      handleInvalid(row) {
-        let params = {
-          id: row.id,
-          status: 4,
-          followStatus: 9,
-          name: row.name,
-          contactPhone: row.contactPhone
+      handleChangeTab(key) {
+        if (key == 1) {
+          this.timer1 = new Date().getTime();
+        } else if (key == 2) {
+          this.timer2 = new Date().getTime();
+        }if (key == 3) {
+          this.timer3 = new Date().getTime();
         }
-        postAction("/customer/customerPotential/statusEdit", params).then((res) => {
-          if (res.success) {
-            this.$emit('ok');
-            this.$message.success(res.message);
-          } else {
-            this.$message.warn('修改失败:' + res.message);
-          }
-        }).finally(() => {
-          this.dialogloading = false;
-          this.dialogPvVisible = false;
-          this.loadData();
-        });
-      },
-      getFormFieldValue(field){
-        return this.form.getFieldValue(field)
-      },
-      visitingOk(){
-        if (this.dateStr == "") {
-          this.$message.warn('请输入客户预约日期!');
-          return null;
-        } else {
-          this.visitingloading = true;
-          let params = {
-            schoolDistrictId: this.dataVisit.schoolDistrictId,
-            cpId: this.dataVisit.id,
-            cpName: this.dataVisit.name,
-            cpPhone: this.dataVisit.contactPhone,
-            visitingTime: this.dateStr,
-            salesCode: this.dataVisit.saleCode
-          }
-          console.log(params);
-          postAction("/customer/customerPotential/addVisit", params).then((res) => {
-            if (res.success) {
-              this.$emit('ok');
-              this.$message.success(res.message);
-            } else {
-              this.$message.warn(res.message);
-            }
-          }).finally(() => {
-            this.visitingloading = false;
-            this.visitingVisible = false;
-            this.dateStr = "";
-            this.dataVisit = "";
-            this.loadData();
-          });
-        }
-      },
-      handleVisiting(row) {
-        this.visitingVisible = true;
-        this.dataVisit = row;
-      },
-      visitingCancel(){
-        this.dateStr = "";
-        this.dataVisit = "";
-        this.visitingVisible = false;
-      },
-
-      auditionOk() {
-        if (this.dateAudition == "") {
-          this.$message.warn('请输入客户试听日期!');
-          return null;
-        } else {
-          this.auditionloading = true;
-          let params = {
-            schoolDistrictId: this.dataAudition.schoolDistrictId,
-            cpId: this.dataAudition.id,
-            cpName: this.dataAudition.name,
-            cpPhone: this.dataAudition.contactPhone,
-            auditionTime: this.dateAudition,
-            salesCode: this.dataAudition.saleCode
-          }
-          postAction("/customer/customerPotential/addAudition", params).then((res) => {
-            if (res.success) {
-              this.$emit('ok');
-              this.$message.success(res.message);
-            } else {
-              this.$message.warn(res.message);
-            }
-          }).finally(() => {
-            this.auditionVisible = false;
-            this.auditionloading = false;
-            this.dateAudition = "";
-            this.dataAudition = "";
-            this.loadData();
-          });
-        }
-      },
-      handleAudition(row) {
-        this.auditionVisible = true;
-        this.dataAudition = row;
-      },
-      auditionCancel(){
-        this.dateAudition = "";
-        this.dataAudition = "";
-        this.auditionVisible = false;
-      },
-      onChangeTime(value,dateString) {
-        this.nextFollowTime = dateString;
-        this.realFollowTime  = dateString;
-      },
-      handleFollowDetail(row) {
-        this.followDetailVisible = true;
-        let params = {
-          cp_id:row.id
-        }
-        postAction("/customer/customerFollow/followDetail", params).then((res) => {
-          if (res.length > 0) {
-            this.dataFollowDetail = res;
-          } else {
-            this.$message.success("无跟进信息");
-          }
-        });
-      },
-      cancelFollowDetail() {
-        this.followDetailVisible = false;
-        this.dataFollowDetail = [];
       }
     }
   }
 </script>
+
 <style scoped>
-  @import '~@assets/less/common.less';
-</style>
-<!-- <style lang="less" scoped>
-  /deep/ .ant-modal-content {
-    height: 400px;
-  }
-</style> -->
+
+</style>

+ 137 - 77
src/views/mili/customer/CustomerPublicList.vue

@@ -5,32 +5,48 @@
       <a-form layout="inline" @keyup.enter.native="searchQuery">
         <a-row :gutter="24">
         <a-col :xl="6" :lg="7" :md="8" :sm="24">
-            <a-form-item >
+            <a-form-item label="关键字">
               <a-input placeholder="请输入姓名、家长姓名、联系方式、备注" v-model="queryParam.keywords"></a-input>
             </a-form-item>
           </a-col>
           <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <!-- <a-form-item label="创建日期">
-                <j-date placeholder="请选择创建日期" v-model="queryParam.createTime"></j-date>
-              </a-form-item> -->
               <a-form-item label="录入日期">
                 <a-range-picker v-model="queryParam.dateQ"
-                                format="YYYY-MM-DD"
-                                :placeholder="['开始日期', '结束日期']"
-                                @change="onCreateTimeChange" />
+                  format="YYYY-MM-DD"
+                  :placeholder="['开始日期', '结束日期']"
+                  @change="onCreateTimeChange" />
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="学员类型">
+                <!-- <j-dict-select-tag placeholder="请选择类型"  v-model="queryParam.type" dictCode="customer_pc_type"/> -->
+                <a-select  v-model="selectValue" @change="handleInput">
+                  <a-select-option value= 0 >全部</a-select-option>
+                  <a-select-option v-for="(item, key) in typeOptions" :key="key" :value="item.value">
+                    <span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
+                      {{ item.text || item.label }}
+                    </span>
+                  </a-select-option>
+                </a-select>
               </a-form-item>
             </a-col>
           <template v-if="toggleSearchStatus">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="状态">
+                <j-dict-select-tag placeholder="请选择状态" v-model="queryParam.status" dictCode="customer_pc_status"/>
+              </a-form-item>
+            </a-col>
            <a-col :xl="6" :lg="7" :md="8" :sm="24">
             <a-form-item label="校区ID">
               <j-dict-select-tag placeholder="请选择校区ID" v-model="queryParam.schoolDistrictId" dictCode="school_organization,name,id"/>
             </a-form-item>
           </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="性别">
-                <j-dict-select-tag placeholder="请选择性别" v-model="queryParam.sex" dictCode="sex"/>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="采单员">
+                <j-select-user-by-dep placeholder="请选择采单员" v-model="queryParam.collectinoCode"/>
               </a-form-item>
             </a-col>
+            
             <a-col :xl="6" :lg="7" :md="8" :sm="24">
               <a-form-item label="学校">
                 <j-dict-select-tag placeholder="请选择学校" v-model="queryParam.school" dictCode="school_school,name,id"/>
@@ -38,7 +54,7 @@
             </a-col>
             <a-col :xl="6" :lg="7" :md="8" :sm="24">
               <a-form-item label="年级">
-                <j-dict-select-tag placeholder="请选择年级" v-model="queryParam.grade" dictCode="grade"/>
+                <j-dict-select-tag placeholder="请选择年级" v-model="queryParam.grade" dictCode="customer_grade"/>
               </a-form-item>
             </a-col>
             <a-col :xl="6" :lg="7" :md="8" :sm="24">
@@ -55,17 +71,12 @@
             </a-col>
             <a-col :xl="6" :lg="7" :md="8" :sm="24">
               <a-form-item label="意向课程">
-                <j-dict-select-tag placeholder="请选择意向课程" v-model="queryParam.intendedCourse" dictCode="school_curriculum,name,id"/>
-              </a-form-item>
-            </a-col>
-            <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="采单员">
-                <j-select-user-by-dep placeholder="请选择采单员" v-model="queryParam.collectinoCode"/>
+                <j-dict-select-tag placeholder="请选择意向课程" v-model="queryParam.intendedCourse" dictCode="education_course,name,id"/>
               </a-form-item>
             </a-col>
             <a-col :xl="6" :lg="7" :md="8" :sm="24">
-              <a-form-item label="状态">
-                <j-dict-select-tag placeholder="请选择状态" v-model="queryParam.status" dictCode="pc_status"/>
+              <a-form-item label="性别">
+                <j-dict-select-tag placeholder="请选择性别" v-model="queryParam.sex" dictCode="sex"/>
               </a-form-item>
             </a-col>
           </template>
@@ -86,14 +97,14 @@
 
     <!-- 操作按钮区域 -->
     <div class="table-operator">
-      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <!-- <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button> -->
       <a-button type="primary" icon="download" @click="handleExportXls('公池管理')">导出</a-button>
       <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
         <a-button type="primary" icon="import">导入</a-button>
       </a-upload>
-      <a-button type="primary" icon="plus" @click="lookTest()">组件Test</a-button>
+      <!-- <a-button type="primary" icon="plus" @click="lookTest()">组件Test</a-button> -->
       <!-- 高级查询区域 -->
-      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query> -->
       <a-dropdown v-if="selectedRowKeys.length > 0">
         <a-menu slot="overlay">
           <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
@@ -104,7 +115,6 @@
 
     <!-- table区域-begin -->
     <div>
-
       <a-table
         ref="table"
         size="middle"
@@ -143,9 +153,10 @@
           <a-divider type="vertical" />
            <a @click="handleDetail(record)">详情</a>
            <a-divider type="vertical" />
-            <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+            <!-- <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
               <a>删除</a>
-            </a-popconfirm>
+            </a-popconfirm> -->
+             <a @click="handleUserLog(record)" >操作记录</a>
            <a-divider type="vertical" v-has="'user:appoint'" />
            <a @click="handleAppoint(record)" v-has="'user:appoint'">顾问分配</a>
         </span>
@@ -167,28 +178,30 @@
       </a-modal>
     <customer-public-modal ref="modalForm" @ok="modalFormOk"></customer-public-modal>
     <!-- 自定义组件调用 -->
-    <test :show-child-dialog.sync="showDialog" />    
+    <CustomerLogs :show-child-dialog.sync="showCustomerLogs" :logInfo="logInfo" /> 
 
   </a-card>
 </template>
 
 <script>
-
+  import {getDictItemsFromCache} from '@/api/api'
   import '@/assets/less/TableExpand.less'
   import { mixinDevice } from '@/utils/mixin'
   import { JeecgListMixin } from '@/mixins/JeecgListMixin'
   import CustomerPublicModal from './modules/CustomerPublicModal'
   import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
   import {postAction} from '@/api/manage'
-  import test from '../modules/test.vue'
+  import CustomerLogs from '../modules/CustomerLogs.vue'
+  import JEllipsis from "@/components/jeecg/JEllipsis"
 
   export default {
     name: 'CustomerPublicList',
     mixins:[JeecgListMixin, mixinDevice],
     components: {
-      CustomerPublicModal,JSelectMultiUser,test
+      CustomerPublicModal,JSelectMultiUser,JEllipsis,CustomerLogs
     },
     data () {
+      let ellipsis = (v, l = 20) => (<j-ellipsis value = {v} length = {l}/>)
       return {
         description: '公池管理管理页面',
         appointShow: false,
@@ -196,10 +209,17 @@
         dialogloading: false,
         form: this.$form.createForm(this),
         appointRowID: '',
+        schoolDistrictId_dictText: "",
+        saleCode_dictText: "",
         users:"",
+        queryParam: {
+          type: "1"
+        },
+        selectValue: "1",
         userValue:"",
         userDisplay:"",
-        showDialog: false,
+        showCustomerLogs: false,
+        logInfo: {},
         // 表头
         columns: [
           // 序号
@@ -223,46 +243,54 @@
             align:"center",
             dataIndex: 'name'
           },
-          {
-            title:'性别',
-            align:"center",
-            dataIndex: 'sex_dictText'
-          },
+          // {
+          //   title:'性别',
+          //   align:"center",
+          //   dataIndex: 'sex_dictText'
+          // },
           {
             title:'家长电话',
             align:"center",
             dataIndex: 'contactPhone'
           },
-          {
-            title:'学校',
-            align:"center",
-            dataIndex: 'school_dictText'
-          },
-          {
-            title:'年级',
-            align:"center",
-            dataIndex: 'grade_dictText'
-          },
-          {
-            title:'渠道类型',
-            align:"center",
-            dataIndex: 'channelType_dictText'
-          },
-          {
-            title:'意向课程',
-            align:"center",
-            dataIndex: 'intendedCourse_dictText'
-          },
+          // {
+          //   title:'学校',
+          //   align:"center",
+          //   dataIndex: 'school_dictText'
+          // },
+          // {
+          //   title:'年级',
+          //   align:"center",
+          //   dataIndex: 'grade_dictText'
+          // },
+          // {
+          //   title:'渠道类型',
+          //   align:"center",
+          //   dataIndex: 'channelType_dictText'
+          // },
+          // {
+          //   title:'意向课程',
+          //   align:"center",
+          //   dataIndex: 'intendedCourse_dictText'
+          // },
           {
             title:'顾问',
             align:"center",
-            dataIndex: 'saleCode_dictText'
+            dataIndex: 'saleCode_dictText',
           },
           {
-            title:'推荐人',
+            title:'备注',
             align:"center",
-            dataIndex: 'referencesPhone'
+            dataIndex: 'markString',
+            customRender: (text) => {
+              return ellipsis(text);
+            }
           },
+          // {
+          //   title:'推荐人',
+          //   align:"center",
+          //   dataIndex: 'referencesPhone'
+          // },
           {
             title:'采单员',
             align:"center",
@@ -274,10 +302,15 @@
             dataIndex: 'status_dictText'
           },
           {
-            title:'录入时间',
+            title:'操作日期',
             align:"center",
-            dataIndex: 'createTime'
+            dataIndex: 'updateTime'
           },
+          // {
+          //   title:'录入时间',
+          //   align:"center",
+          //   dataIndex: 'createTime'
+          // },
           {
             title: '操作',
             dataIndex: 'action',
@@ -288,18 +321,20 @@
           }
         ],
         url: {
-          list: "/customer/customerPublic/list",
-          delete: "/customer/customerPublic/delete",
-          deleteBatch: "/customer/customerPublic/deleteBatch",
-          exportXlsUrl: "/customer/customerPublic/exportXls",
-          importExcelUrl: "customer/customerPublic/importExcel",
+          list: "/customer/customerInfo/list",
+          delete: "/customer/customerInfo/delete",
+          deleteBatch: "/customer/customerInfo/deleteBatch",
+          exportXlsUrl: "/customer/customerInfo/exportXls",
+          importExcelUrl: "customer/customerInfo/importExcel",
         },
         dictOptions:{},
         superFieldList:[],
+        typeOptions:[]
       }
     },
     created() {
       this.getSuperFieldList();
+      this.typeOptions = getDictItemsFromCache('customer_pc_type');
     },
     computed: {
       importExcelUrl: function(){
@@ -316,13 +351,13 @@
         fieldList.push({type:'int',value:'sex',text:'性别',dictCode:'sex'})
         fieldList.push({type:'string',value:'contactPhone',text:'家长电话',dictCode:''})
         fieldList.push({type:'string',value:'school',text:'学校',dictCode:"school_school,name,id"})
-        fieldList.push({type:'string',value:'grade',text:'年级',dictCode:'grade'})
+        fieldList.push({type:'string',value:'grade',text:'年级',dictCode:'customer_grade'})
         fieldList.push({type:'string',value:'channelType',text:'渠道类型'})
-        fieldList.push({type:'string',value:'intendedCourse',text:'意向课程',dictCode:"school_curriculum,name,id"})
+        fieldList.push({type:'string',value:'intendedCourse',text:'意向课程',dictCode:"education_course,name,id"})
         fieldList.push({type:'sel_user',value:'saleCode',text:'顾问'})
         fieldList.push({type:'string',value:'referencesPhone',text:'推荐人',dictCode:''})
         fieldList.push({type:'sel_user',value:'collectinoCode',text:'采单员'})
-        fieldList.push({type:'int',value:'status',text:'状态',dictCode:'pc_status'})
+        fieldList.push({type:'int',value:'status',text:'状态',dictCode:'customer_pc_status'})
         fieldList.push({type:'date',value:'createTime',text:'创建日期'})
         this.superFieldList = fieldList
       },
@@ -331,16 +366,25 @@
         this.appointShow = true;
         this.appointRowID = row.id;
         this.users = row.saleCode;
+        this.schoolDistrictId_dictText = row.schoolDistrictId_dictText;
+        this.saleCode_dictText = row.saleCode_dictText;
       },
       appointOk() {
         this.dialogloading = true;
         let params = {
-          id: this.appointRowID,
-          saleCode: this.users,
-          status: 1,
-          follow_status: 1
+          customerInfo: {
+            id: this.appointRowID,
+            saleCode: this.users,
+            status: 1,
+            follow_status: 1,
+            type: 2
+          },
+          appointInfo: {
+            saleName: this.saleCode_dictText,
+            schoolName: this.schoolDistrictId_dictText
+          }
         }
-        postAction("/customer/customerPublic/appoint", params).then((res) => {
+        postAction("/customer/customerInfo/appoint", params).then((res) => {
           if (res.success) {
             this.$emit('ok');
             this.$message.success(res.message);
@@ -355,21 +399,37 @@
       },
       appointCancel() {
         this.users = "";
-        this.appointRowID = '';
+        this.appointRowID = "";
         this.dialogPvVisible = false;
+        this.schoolDistrictId_dictText = "";
+        this.saleCode_dictText  = "";
       },
       getFormFieldValue(field){
         return this.form.getFieldValue(field)
       },
-      lookTest() {
-        this.showDialog  = true
-      },
       onCreateTimeChange: function (value, dateString) {
         this.queryParam.beginTime=dateString[0];
         this.queryParam.endTime=dateString[1];
       },
       testP() {
         console.log('子组件调用!');
+      },
+      handleUserLog(row) {
+        this.showCustomerLogs  = true;
+        this.logInfo = row;
+      },
+      searchReset() {
+        this.queryParam = {};
+        this.queryParam.type = "1";
+        this.selectValue = "1";
+        this.loadData(1);
+      },
+      handleInput(e) {
+        if (e == 0) {
+          this.queryParam.type = undefined
+        } else {
+          this.queryParam.type = e
+        }
       }
     }
   }

+ 38 - 94
src/views/mili/customer/modules/CustomerPotentialForm.vue

@@ -3,92 +3,47 @@
     <j-form-container :disabled="formDisabled">
       <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
         <a-row>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="校区ID" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="schoolDistrictId">
               <j-dict-select-tag type="list" v-model="model.schoolDistrictId" dictCode="school_organization,name,id" placeholder="请选择校区ID" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="姓名" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="name">
               <a-input v-model="model.name" placeholder="请输入姓名"  ></a-input>
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="昵称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="nickname">
-              <a-input v-model="model.nickname" placeholder="请输入昵称"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="性别" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="sex">
               <j-dict-select-tag type="list" v-model="model.sex" dictCode="sex" placeholder="请选择性别" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="家长姓名" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contactName">
-              <a-input v-model="model.contactName" placeholder="请输入家长姓名"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="家长电话" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contactPhone">
-              <a-input v-model="model.contactPhone" placeholder="请输入家长电话"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="备选联系人1" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contact1Name">
-              <a-input v-model="model.contact1Name" placeholder="请输入备选联系人1"  ></a-input>
+           <a-col :span="8">
+            <a-form-model-item label="生日" :labelCol="labelCol" :wrapperCol="wrapperCol" >
+              <j-date placeholder="请选择生日" v-model="model.birthday"  style="width: 100%" @change="handleDateChange"/>
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="备选联系人1电话" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contact1Phone">
-              <a-input v-model="model.contact1Phone" placeholder="请输入备选联系人1电话"  ></a-input>
+          <a-col :span="8">
+            <a-form-model-item label="年龄" :labelCol="labelCol" :wrapperCol="wrapperCol" >
+              {{age}}
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="备选联系人2" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contact2Name">
-              <a-input v-model="model.contact2Name" placeholder="请输入备选联系人2"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="备选联系人2电话" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contact2Phone">
-              <a-input v-model="model.contact2Phone" placeholder="请输入备选联系人2电话"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="年龄" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="age">
-              <a-input-number v-model="model.age" placeholder="请输入年龄" style="width: 100%" />
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="生日" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="birthday">
-              <j-date placeholder="请选择生日" v-model="model.birthday"  style="width: 100%" />
+          <a-col :span="8">
+            <a-form-model-item label="家长电话" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contactPhone">
+              <a-input v-model="model.contactPhone" placeholder="请输入家长电话"  ></a-input>
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="学校" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="school">
               <j-dict-select-tag type="list" v-model="model.school" dictCode="school_school,name,id" placeholder="请选择学校" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="年级" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="grade">
-              <j-dict-select-tag type="list" v-model="model.grade" dictCode="grade" placeholder="请选择年级" />
+              <j-dict-select-tag type="list" v-model="model.grade" dictCode="customer_grade" placeholder="请选择年级" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="班级" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="class">
-              <a-input v-model="model.class" placeholder="请输入班级"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="身份证" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="idCard">
-              <a-input v-model="model.idCard" placeholder="请输入身份证"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="住址" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="address">
-              <a-input v-model="model.address" placeholder="请输入住址"  ></a-input>
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="渠道类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="channelType">
   	          <j-tree-select
                 ref="treeSelect"
@@ -100,54 +55,39 @@
               </j-tree-select>
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="意向课程" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="intendedCourse">
-              <j-dict-select-tag type="list" v-model="model.intendedCourse" dictCode="school_curriculum,name,id" placeholder="请选择意向课程" />
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="意向度" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="intendedDegress">
-              <j-dict-select-tag type="list" v-model="model.intendedDegress" dictCode="intention_status" placeholder="请选择意向度" />
+              <j-dict-select-tag type="list" v-model="model.intendedCourse" dictCode="education_course,name,id" placeholder="请选择意向课程" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="顾问" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="saleCode">
               <j-select-user-by-dep v-model="model.saleCode" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="推荐人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="referencesPhone">
               <a-input v-model="model.referencesPhone" placeholder="请输入推荐人"  ></a-input>
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="采单员" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="collectinoCode">
               <j-select-user-by-dep v-model="model.collectinoCode" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
+          <a-col :span="8">
             <a-form-model-item label="状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="status">
-              <j-dict-select-tag type="list" v-model="model.status" dictCode="pc_status" placeholder="请选择状态" />
+              <j-dict-select-tag type="list" v-model="model.status" dictCode="customer_pc_status" placeholder="请选择状态" />
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="跟进状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="followStatus">
-              <j-dict-select-tag type="list" v-model="model.followStatus" dictCode="pc_follow_status" placeholder="请选择跟进状态" />
+          <a-col :span="8">
+            <a-form-model-item label="班级" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="classes">
+              <a-input v-model="model.classes" placeholder="请输入班级"  ></a-input>
             </a-form-model-item>
           </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="上次跟进" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="lastFollowTime">
-              <j-date placeholder="请选择上次跟进"  v-model="model.lastFollowTime" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="下次跟进" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="nextFollowTime">
-              <j-date placeholder="请选择下次跟进"  v-model="model.nextFollowTime" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
-            </a-form-model-item>
-          </a-col>
-          <a-col :span="12">
-            <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="markString">
-              <j-editor v-model="model.markString" />
+          <a-col :span="24" pull="8" >
+            <a-form-model-item style="margin-left: 122px;width: 133.5%" label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" :maxlength="16" prop="markString">
+              <a-textarea v-model="model.markString" rows="4" placeholder="请输入备注" />
             </a-form-model-item>
           </a-col>
         </a-row>
@@ -160,7 +100,7 @@
 
   import { httpAction, getAction } from '@/api/manage'
   import { validateDuplicateValue } from '@/utils/util'
-
+  import { getAge } from '@/utils/util';
   export default {
     name: 'CustomerPotentialForm',
     components: {
@@ -217,10 +157,11 @@
            ],
         },
         url: {
-          add: "/miliCustomer/customerPotential/add",
-          edit: "/miliCustomer/customerPotential/edit",
-          queryById: "/miliCustomer/customerPotential/queryById"
-        }
+          add: "/customer/customerInfo/add",
+          edit: "/customer/customerInfo/edit",
+          queryById: "/customer/customerInfo/queryById"
+        },
+        age: undefined,
       }
     },
     computed: {
@@ -233,6 +174,9 @@
       this.modelDefault = JSON.parse(JSON.stringify(this.model));
     },
     methods: {
+      handleDateChange() {
+        this.age = getAge(this.model.birthday);
+      },
       add () {
         this.edit(this.modelDefault);
       },

+ 38 - 8
src/views/mili/customer/modules/CustomerPublicForm.vue

@@ -18,6 +18,16 @@
               <j-dict-select-tag type="list" v-model="model.sex" dictCode="sex" placeholder="请选择性别" />
             </a-form-model-item>
           </a-col>
+           <a-col :span="8">
+            <a-form-model-item label="生日" :labelCol="labelCol" :wrapperCol="wrapperCol" >
+              <j-date placeholder="请选择生日" v-model="model.birthday"  style="width: 100%" @change="handleDateChange"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="8">
+            <a-form-model-item label="年龄" :labelCol="labelCol" :wrapperCol="wrapperCol" >
+              {{age}}
+            </a-form-model-item>
+          </a-col>
           <a-col :span="8">
             <a-form-model-item label="家长电话" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contactPhone">
               <a-input v-model="model.contactPhone" placeholder="请输入家长电话"  ></a-input>
@@ -30,7 +40,7 @@
           </a-col>
           <a-col :span="8">
             <a-form-model-item label="年级" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="grade">
-              <j-dict-select-tag type="list" v-model="model.grade" dictCode="grade" placeholder="请选择年级" />
+              <j-dict-select-tag type="list" v-model="model.grade" dictCode="customer_grade" placeholder="请选择年级" />
             </a-form-model-item>
           </a-col>
           <a-col :span="8">
@@ -47,7 +57,7 @@
           </a-col>
           <a-col :span="8">
             <a-form-model-item label="意向课程" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="intendedCourse">
-              <j-dict-select-tag type="list" v-model="model.intendedCourse" dictCode="school_curriculum,name,id" placeholder="请选择意向课程" />
+              <j-dict-select-tag type="list" v-model="model.intendedCourse" dictCode="education_course,name,id" placeholder="请选择意向课程" />
             </a-form-model-item>
           </a-col>
           <a-col :span="8">
@@ -67,7 +77,17 @@
           </a-col>
           <a-col :span="8">
             <a-form-model-item label="状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="status">
-              <j-dict-select-tag type="list" v-model="model.status" dictCode="pc_status" placeholder="请选择状态" />
+              <j-dict-select-tag type="list" v-model="model.status" dictCode="customer_pc_status" placeholder="请选择状态" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="8">
+            <a-form-model-item label="班级" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="classes">
+              <a-input v-model="model.classes" placeholder="请输入班级"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" pull="8" >
+            <a-form-model-item style="margin-left: 122px;width: 133.5%" label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" :maxlength="16" prop="markString">
+              <a-textarea v-model="model.markString" rows="4" placeholder="请输入备注" />
             </a-form-model-item>
           </a-col>
         </a-row>
@@ -79,7 +99,7 @@
 <script>
 
   import { httpAction, getAction } from '@/api/manage'
-  import { validateDuplicateValue } from '@/utils/util'
+  import { getAge } from '@/utils/util';
 
   export default {
     name: 'CustomerPublicForm',
@@ -95,6 +115,7 @@
     },
     data () {
       return {
+        age: undefined,
         model:{
             status:0,
          },
@@ -123,22 +144,29 @@
            ],
         },
         url: {
-          add: "/customer/customerPublic/add",
-          edit: "/customer/customerPublic/edit",
-          queryById: "/customer/customerPublic/queryById"
+          add: "/customer/customerInfo/add",
+          edit: "/customer/customerInfo/edit",
+          queryById: "/customer/customerInfo/queryById"
         }
       }
     },
     computed: {
       formDisabled(){
+        this.age = getAge(String(this.model.birthday));
         return this.disabled
-      },
+      }
     },
     created () {
        //备份model原始值
       this.modelDefault = JSON.parse(JSON.stringify(this.model));
+      if(this.model.birthday !== null && this.model.birthday !== undefined &&this.model.birthday !=="") {
+        this.age = getAge(this.model.birthday);
+      }
     },
     methods: {
+      handleDateChange() {
+        this.age = getAge(this.model.birthday);
+      },
       add () {
         this.edit(this.modelDefault);
       },
@@ -156,11 +184,13 @@
             let method = '';
             if(!this.model.id){
               httpurl+=this.url.add;
+              this.model.type = 1; //默认值待处理
               method = 'post';
             }else{
               httpurl+=this.url.edit;
                method = 'put';
             }
+            console.log(this.model);
             httpAction(httpurl,this.model,method).then((res)=>{
               if(res.success){
                 that.$message.success(res.message);

+ 858 - 0
src/views/mili/customer/modules/PotentialListTabPublic.vue

@@ -0,0 +1,858 @@
+<template>
+  <a-card :bordered="false" :body-style="{ padding: '0px 0px 8px' }" >
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="关键字">
+              <a-input placeholder="请输入姓名、家长姓名、联系方式、备注" v-model="queryParam.keywords"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="录入日期">
+                <a-range-picker v-model="queryParam.dateQ"
+                  format="YYYY-MM-DD"
+                  :placeholder="['开始日期', '结束日期']"
+                  @change="onCreateTimeChange" />
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="校区ID">
+                <j-dict-select-tag placeholder="请选择校区ID" v-model="queryParam.schoolDistrictId" dictCode="school_organization,name,id"/>
+              </a-form-item>
+            </a-col>
+          <template v-if="toggleSearchStatus">
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="跟进状态">
+                <j-dict-select-tag placeholder="请选择跟进状态" v-model="queryParam.followStatus" dictCode="customer_follow_status"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="学员类型">
+                <!-- <j-dict-select-tag placeholder="请选择类型"  v-model="queryParam.type" dictCode="customer_pc_type"/> -->
+                <a-select  v-model="selectValue" @change="handleInput">
+                  <a-select-option value= 0 >全部</a-select-option>
+                  <a-select-option v-for="(item, key) in typeOptions" :key="key" :value="item.value">
+                    <span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
+                      {{ item.text || item.label }}
+                    </span>
+                  </a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="意向课程">
+                <j-dict-select-tag placeholder="请选择意向课程" v-model="queryParam.intendedCourse" dictCode="education_course,name,id"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="上次跟进">
+                <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择上次跟进" v-model="queryParam.lastFollowTime"></j-date>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="顾问">
+                <j-select-user-by-dep placeholder="请选择顾问" v-model="queryParam.saleCode"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="采单员">
+                <j-select-user-by-dep placeholder="请选择采单员" v-model="queryParam.collectinoCode"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="渠道类型">
+                <j-tree-select
+                ref="treeSelect"
+                placeholder="请选择渠道类型"
+                v-model="queryParam.channelType"
+                dict="promotion_channel,name,id"
+                pidValue="0"
+                >
+              </j-tree-select>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="意向度">
+                <j-dict-select-tag placeholder="请选择意向度" v-model="queryParam.intendedDegress" dictCode="customer_intention_status"/>
+              </a-form-item>
+            </a-col>
+            <!-- 年龄 -->
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+             <a-form-item label="年龄">
+              <a-input-group >
+                <a-input type = "number" v-model:value="queryParam.ageMin" 
+                style="width: 100px; text-align: center ; border-right: 0;" placeholder="最小年龄" />
+                <a-input v-model:value="value13"
+                  style="width: 30px; border-left: 0; border-right: 0; pointer-events: none; background-color: #fff"
+                  placeholder="~" disabled />
+                <a-input type = "number" v-model:value="queryParam.ageMax"
+                  style="width: 100px; text-align: center; border-left: 0" placeholder="最大年龄" />
+              </a-input-group>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="年级">
+                <j-dict-select-tag placeholder="请选择年级" v-model="queryParam.grade" dictCode="customer_grade"/>
+              </a-form-item>
+            </a-col>
+            <!-- 标签 -->
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="学校">
+                <j-dict-select-tag placeholder="请选择学校" v-model="queryParam.school" dictCode="school_school,name,id"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="">
+                <a-checkbox :checked="checked"  @change="invalidChange(checked)">不显示无效潜客</a-checkbox>
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <!-- <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button> -->
+      <a-button type="primary" icon="download" @click="handleExportXls('潜客管理')">导出</a-button>
+      <!-- <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+          <a-divider type="vertical" />
+          <a @click="handleDetail(record)">详情</a>
+          <!-- <a-divider type="vertical" />
+          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm> -->
+          <a-divider type="vertical" v-has="'user:appoint'"/>
+          <a @click="handleFollow(record)" v-has="'user:appoint'">领取</a>
+          <a-divider type="vertical" v-has="'user:appoint'"/>
+          <a @click="handleVisiting(record)" v-has="'user:appoint'">分配</a>
+          <a-divider type="vertical" v-has="'user:appoint'"/>
+          <a @click="handleAudition(record)" v-has="'user:appoint'">删除</a>
+          <a-divider type="vertical" v-has="'user:appoint'"/>
+        </span>
+
+       <!--插槽NNNN-->
+       <a slot="detail" slot-scope="text, record" @click="handleFollowDetail(record)" >{{text}}</a>
+      </a-table>
+    </div>
+    <!--弹出窗口-->
+    <a-modal
+      title="跟进信息新增"
+      ok-text="确认" 
+      cancel-text="取消"
+      :visible="followVisible"
+      :confirm-loading="followloading"
+      @ok="followOk"
+      @cancel="followCancel">
+      <a-form-item label="跟进类别">
+        <a-input placeholder="请输入跟进类别" v-model="followType"></a-input>
+      </a-form-item>
+      <a-form-item label="跟进内容">
+        <a-textarea v-model="followContent" rows="4" placeholder="请输入跟进内容" />
+      </a-form-item>
+      <a-form-item label="下次跟进">
+        <a-date-picker v-model="nextFollowTime" 
+          name = "nextFollowTime"
+          dateFormat="YYYY-MM-DD"
+          :disabledDate="disabledDate"
+          v-decorator="['nextFollowTime',rules.date]"
+          @change="onChangeTime"
+          ></a-date-picker>
+      </a-form-item>
+      <a-form-item label="图片"  style="width: 400px">
+        <j-image-upload text="上传" v-model="fileList" :isMultiple="true" ></j-image-upload>
+      </a-form-item>
+    </a-modal>
+
+     <a-modal
+      title="来访信息添加"
+      ok-text="确认" 
+      cancel-text="取消"
+      :visible="visitingVisible"
+      :confirm-loading="visitingloading"
+      @ok="visitingOk"
+      @cancel="visitingCancel">
+      <a-form-item label="客户来访日期"  style="width: 400px">
+        <a-date-picker v-model="dateStr" 
+        name = "dateStr"
+        dateFormat="YYYY-MM-DD"
+        :disabledDate="disabledDate"
+        v-decorator="['dateStr',rules.date]"
+        ></a-date-picker>
+      </a-form-item>
+    </a-modal>
+
+    <a-modal
+      title="试听信息添加"
+      ok-text="确认" 
+      cancel-text="取消"
+      :visible="auditionVisible"
+      :confirm-loading="auditionloading"
+      @ok="auditionOk"
+      @cancel="auditionCancel">
+      <a-form-item label="客户试听日期"  style="width: 400px">
+        <a-date-picker v-model="dateAudition" 
+        name = "dateAudition"
+        dateFormat="YYYY-MM-DD"
+        :disabledDate="disabledDate"
+        v-decorator="['dateAudition',rules.date]"
+        ></a-date-picker>
+      </a-form-item>
+    </a-modal>
+
+
+    <a-modal
+      title="跟进详情"
+      :visible="followDetailVisible"
+      :width=900
+      @cancel="cancelFollowDetail"
+      cancelText="关闭"
+      :body-style="{width:200}"
+      >
+      <a-list item-layout="horizontal" :data-source="dataFollowDetail">
+          <a-list-item :key="index" v-for="(item, index) in dataFollowDetail">
+              <a-list-item-meta>
+               <template #title>
+                <a-descriptions bordered>
+                  <a-descriptions-item label="潜客姓名">{{item.cpName}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进人">{{item.salesName}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进日期">{{item.createTime}}</a-descriptions-item>
+                  <a-descriptions-item label="校区" :span="1">{{item.schoolDistrictName}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进类型" :span="2">{{item.followType}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进内容" :span="3">{{item.followContent}}</a-descriptions-item>
+                  <a-descriptions-item label="图片" :span="3">
+                   <!-- 为啥不能用a-image? -->
+                   <div v-if="item.picList != null">
+                      <div v-if = "(item.picList.more)">
+                        <div v-for="(imgItem,index) in item.picList.imgPath" :key="index">
+                          <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
+                            <div
+                              style="width: 100%;height: 100%;position: relative;padding: 8px;border: 0px solid #d9d9d9;border-radius: 4px;">
+                              <img style="width: 100%;" :src="imgItem.imgUrl" :preview="item.picList.key">
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                      <div v-else>
+                         <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
+                            <div
+                              style="width: 100%;height: 100%;position: relative;padding: 8px;border: 0px solid #d9d9d9;border-radius: 4px;">
+                              <img style="width: 100%;" :src="item.picList.imgPath.imgUrl" :preview="item.picList.key">
+                            </div>
+                          </div>
+                      </div>
+                   </div>
+                  </a-descriptions-item>
+                </a-descriptions>
+               </template>
+            </a-list-item-meta>
+          </a-list-item>
+      </a-list>
+
+       <template slot="footer">
+        <a-button key="back" @click="cancelFollowDetail">关闭</a-button>
+      </template>
+    </a-modal>
+
+
+    <customer-potential-modal ref="modalForm" @ok="modalFormOk"></customer-potential-modal>
+  </a-card>
+</template>
+
+<script>
+  import {getDictItemsFromCache} from '@/api/api'
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import CustomerPotentialModal from './CustomerPotentialModal'
+  import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
+  import {postAction} from '@/api/manage'
+  import moment from 'moment'
+  import JImageUpload from '@/components/jeecg/JImageUpload'
+  import store from '@/store'
+  import JEllipsis from "@/components/jeecg/JEllipsis"
+  export default {
+    name: 'PotentialListTabPublic',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+      CustomerPotentialModal,JSelectMultiUser,JImageUpload,JEllipsis
+    },
+    data () {
+      let ellipsis = (v, l = 20) => (<j-ellipsis value = {v} length = {l}/>)
+      return {
+        description: '潜客管理管理页面',
+        followVisible: false,
+        followloading: false,
+        checked: false,
+        dataFollow:"",
+        followType:"",
+        followContent:"",
+        followDetailVisible: false,
+        nextFollowTime:"",
+        realFollowTime:"",
+        fileList:[],
+        visitingVisible: false,
+        visitingloading: false,
+        dataVisit:"",
+        dateStr:"",
+        auditionVisible: false,
+        auditionloading: false,
+        dataAudition:"",
+        dateAudition:"",
+        form: this.$form.createForm(this),
+        users: "",
+        dataFollowDetail: [],
+        selectValue: "0",
+        key:"",
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'姓名',
+            align:"center",
+            dataIndex: 'name',
+            scopedSlots: { customRender: 'detail' }
+          },
+          {
+            title:'联系方式',
+            align:"center",
+            dataIndex: 'contactPhone'
+          },
+          {
+            title:'意向度', 
+            align:"center",
+            dataIndex: 'intendedDegress_dictText'
+          },
+          {
+            title:'意向课程',
+            align:"center",
+            dataIndex: 'intendedCourse_dictText'
+          },
+          {
+            title:'顾问',
+            align:"center",
+            dataIndex: 'saleCode_dictText'
+          },
+          {
+            title:'最近跟进时间',
+            align:"center",
+            dataIndex: 'lastFollowTime'
+          },
+          {
+            title:'最近跟进记录',
+            align:"center",
+            dataIndex: 'follow_log'
+          },
+          {
+            title:'下次跟进日期',
+            align:"center",
+            dataIndex: 'nextFollowTime'
+          },
+          {
+            title:'跟进状态',
+            align:"center",
+            dataIndex: 'followStatusDictText'
+          },
+          {
+            title:'学员类型',
+            align:"center",
+            dataIndex: 'type_dictText'
+          },
+          {
+            title:'年龄',
+            align:"center",
+            dataIndex: 'birthday'
+          },
+          {
+            title:'来源',
+            align:"center",
+            dataIndex: 'channelType_dictText'
+          },
+          {
+            title:'采单员',
+            align:"center",
+            dataIndex: 'collectinoCode_dictText'
+          },
+          {
+            title:'学校',
+            align:"center",
+            dataIndex: 'school_dictText'
+          },
+          {
+            title:'年级',
+            align:"center",
+            dataIndex: 'grade_dictText'
+          },
+          {
+            title:'备注',
+            align:"center",
+            dataIndex: 'markString',
+            customRender: (text) => {
+              return ellipsis(text);
+            }
+          },
+          {
+            title:'录入时间',
+            align:"center",
+            dataIndex: 'createTime'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        rules: {
+          date: [
+            { required: true, message: '请输入预约日期!', trigger: 'blur'},
+           ],
+        },
+        url: {
+          list: "/customer/customerInfo/list",
+          delete: "/customer/customerInfo/delete",
+          deleteBatch: "/customer/customerInfo/deleteBatch",
+          exportXlsUrl: "/customer/customerInfo/exportXls",
+          importExcelUrl: "customer/customerInfo/importExcel",
+          
+        },
+        dictOptions:{},
+        superFieldList:[],
+        imageSource: [{
+          key:0,
+          fileDetails:[
+            {
+              imgUrl:"https://static.jeecg.com/upload/test/3a4490d5d1cd495b826e528537a47cc1.jpg"
+            },
+            {
+              imgUrl:"https://static.jeecg.com/temp/国炬软件logo_1606575029126.png"
+            }
+          ]
+          },{
+            key:1,
+            fileDetails:[
+              {
+                imgUrl:"https://static.jeecg.com/upload/test/u27356337152749454924fm27gp0_1588149731821.jpg"
+              },
+              {
+                imgUrl:"https://static.jeecg.com/upload/test/1_1588149743473.jpg"
+              }
+            ]
+          }
+      ],
+      typeOptions:[],
+      ageMin: undefined,
+      ageMax: undefined,
+      value13: undefined,
+      }
+    },
+    props: ['tabPara'],
+    created() {
+      this.queryParam = {
+        type: 5
+      };
+      this.getSuperFieldList();
+      this.typeOptions = getDictItemsFromCache('customer_pc_type');
+    },
+    watch: {
+      tabPara : {
+        immediate: true,
+        handler(param){
+          if (String(param) === "2") {
+            this.queryParam = {
+              saleCode:store.getters.userInfo.username
+            }
+          } else if (String(param) === "3") {
+            this.queryParam = {
+              type: 5
+            };
+          } 
+        }
+      }
+    },
+    methods: {
+      initDictConfig(){
+      },
+      disabledDate(current) {
+        return current < moment().endOf("day"); // 当前时间之前的所有日期都禁用
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'int',value:'schoolDistrictId',text:'校区ID',dictCode:"school_organization,name,id"})
+        fieldList.push({type:'string',value:'name',text:'姓名',dictCode:''})
+        fieldList.push({type:'string',value:'nickname',text:'昵称',dictCode:''})
+        fieldList.push({type:'int',value:'sex',text:'性别',dictCode:'sex'})
+        fieldList.push({type:'string',value:'contactName',text:'家长姓名',dictCode:''})
+        fieldList.push({type:'string',value:'contactPhone',text:'家长电话',dictCode:''})
+        fieldList.push({type:'string',value:'contact1Name',text:'备选联系人1',dictCode:''})
+        fieldList.push({type:'string',value:'contact1Phone',text:'备选联系人1电话',dictCode:''})
+        fieldList.push({type:'string',value:'contact2Name',text:'备选联系人2',dictCode:''})
+        fieldList.push({type:'string',value:'contact2Phone',text:'备选联系人2电话',dictCode:''})
+        fieldList.push({type:'int',value:'age',text:'年龄',dictCode:''})
+        fieldList.push({type:'date',value:'birthday',text:'生日'})
+        fieldList.push({type:'string',value:'school',text:'学校',dictCode:"school_school,name,id"})
+        fieldList.push({type:'string',value:'grade',text:'年级',dictCode:'customer_grade'})
+        fieldList.push({type:'string',value:'class',text:'班级',dictCode:''})
+        fieldList.push({type:'string',value:'idCard',text:'身份证',dictCode:''})
+        fieldList.push({type:'string',value:'address',text:'住址',dictCode:''})
+        fieldList.push({type:'string',value:'channelType',text:'渠道类型'})
+        fieldList.push({type:'string',value:'intendedCourse',text:'意向课程',dictCode:"education_course,name,id"})
+        fieldList.push({type:'int',value:'intendedDegress',text:'意向度',dictCode:'customer_intention_status'})
+        fieldList.push({type:'sel_user',value:'saleCode',text:'顾问'})
+        fieldList.push({type:'string',value:'referencesPhone',text:'推荐人',dictCode:''})
+        fieldList.push({type:'sel_user',value:'collectinoCode',text:'采单员'})
+        fieldList.push({type:'int',value:'status',text:'状态',dictCode:'customer_pc_status'})
+        fieldList.push({type:'int',value:'followStatus',text:'跟进状态',dictCode:'customer_follow_status'})
+        fieldList.push({type:'datetime',value:'lastFollowTime',text:'上次跟进'})
+        fieldList.push({type:'datetime',value:'nextFollowTime',text:'下次跟进'})
+        fieldList.push({type:'Blob',value:'mark',text:'备注',dictCode:''})
+        this.superFieldList = fieldList
+      },
+      handleFollow(row) {
+        // addloading
+        this.followVisible = true;
+        this.dataFollow = row;
+      },
+      onCreateTimeChange: function (value, dateString) {
+        this.queryParam.beginTime=dateString[0];
+        this.queryParam.endTime=dateString[1];
+      },
+      followOk() {
+        if (this.followType == "") {
+          this.$message.warn('请输入跟进类型');
+          return;
+        }
+        if (this.followContent == "") {
+          this.$message.warn('请输入跟进内容');
+          return;
+        }
+        if (this.nextFollowTime == "") {
+          this.$message.warn('请输入跟进日期');
+          return;
+        }
+        let params = {
+          schoolDistrictId: this.dataFollow.schoolDistrictId,
+          cpId: this.dataFollow.id,
+          followType:this.followType,
+          followContent:this.followContent,
+          followPic:this.fileList,
+          salesCode:this.dataFollow.saleCode,
+          createBy:store.getters.userInfo.username,
+          nextFollowTime:this.realFollowTime
+        }
+        console.log(params);
+        this.followloading = true;
+        postAction("/customer/customerFollow/addFollow", params).then((res) => {
+          if (res.success) {
+            this.$emit('ok');
+            this.$message.success('添加成功');
+          } else {
+            this.$message.warn('添加失败:' + res.message);
+          }
+        }).finally(() => {
+          this.followloading = false;
+          this.followVisible = false;
+          this.followType = "";
+          this.followContent = "";
+          this.fileList = "";
+          this.dataFollow = "";
+          this.nextFollowTime = "";
+          this.realFollowTime = "";
+          this.loadData();
+        });
+      },
+      followCancel() {
+        if(JSON.stringify(this.fileList) !== '[]' || Object.keys(this.fileList).length !== 0) {
+          let bizPath =[];
+          if(this.fileList.indexOf(",")!= -1) {
+            bizPath = this.fileList.split(',');
+          }else {
+            bizPath.push(this.fileList)
+          }
+          postAction("/sys/common/delUploadTemp", bizPath).then((res) => {
+          });
+        }
+        this.fileList = [];
+        this.dataFollow = "";
+        this.followVisible = false;
+        this.followType = "";
+        this.followContent = "";
+        this.nextFollowTime = "";
+        this.realFollowTime = "";
+      },
+      handleSign(row) {
+        let params = {
+          id: row.id,
+          status: 2,
+          followStatus: 8,
+          name: row.name,
+          contactPhone: row.contactPhone
+        }
+        postAction("/customer/customerInfo/sign", params).then((res) => {
+          if (res.success) {
+            this.$emit('ok');
+            this.$message.success(res.message);
+          } else {
+            this.$message.warn('报名失败:' + res.message);
+          }
+        }).finally(() => {
+          this.dialogloading = false;
+          this.dialogPvVisible = false;
+          this.loadData();
+        });
+      },
+      handleReject(row) {
+         let params = {
+          id: row.id,
+          status: 3,
+          followStatus: 1,
+          name: row.name,
+          contactPhone: row.contactPhone
+        }
+        postAction("/customer/customerInfo/statusEdit", params).then((res) => {
+          if (res.success) {
+            this.$emit('ok');
+            this.$message.success(res.message);
+          } else {
+            this.$message.warn('修改失败:' + res.message);
+          }
+        }).finally(() => {
+          this.dialogloading = false;
+          this.dialogPvVisible = false;
+          this.loadData();
+        });
+      },
+      handleInvalid(row) {
+        let params = {
+          id: row.id,
+          status: 4,
+          followStatus: 9,
+          name: row.name,
+          contactPhone: row.contactPhone
+        }
+        postAction("/customer/customerInfo/statusEdit", params).then((res) => {
+          if (res.success) {
+            this.$emit('ok');
+            this.$message.success(res.message);
+          } else {
+            this.$message.warn('修改失败:' + res.message);
+          }
+        }).finally(() => {
+          this.dialogloading = false;
+          this.dialogPvVisible = false;
+          this.loadData();
+        });
+      },
+      getFormFieldValue(field){
+        return this.form.getFieldValue(field)
+      },
+      visitingOk(){
+        if (this.dateStr == "") {
+          this.$message.warn('请输入客户预约日期!');
+          return null;
+        } else {
+          this.visitingloading = true;
+          let params = {
+            schoolDistrictId: this.dataVisit.schoolDistrictId,
+            cpId: this.dataVisit.id,
+            cpName: this.dataVisit.name,
+            cpPhone: this.dataVisit.contactPhone,
+            visitingTime: this.dateStr,
+            salesCode: this.dataVisit.saleCode
+          }
+          console.log(params);
+          postAction("/customer/customerInfo/addVisit", params).then((res) => {
+            if (res.success) {
+              this.$emit('ok');
+              this.$message.success(res.message);
+            } else {
+              this.$message.warn(res.message);
+            }
+          }).finally(() => {
+            this.visitingloading = false;
+            this.visitingVisible = false;
+            this.dateStr = "";
+            this.dataVisit = "";
+            this.loadData();
+          });
+        }
+      },
+      handleVisiting(row) {
+        this.visitingVisible = true;
+        this.dataVisit = row;
+      },
+      visitingCancel(){
+        this.dateStr = "";
+        this.dataVisit = "";
+        this.visitingVisible = false;
+      },
+
+      auditionOk() {
+        if (this.dateAudition == "") {
+          this.$message.warn('请输入客户试听日期!');
+          return null;
+        } else {
+          this.auditionloading = true;
+          let params = {
+            schoolDistrictId: this.dataAudition.schoolDistrictId,
+            cpId: this.dataAudition.id,
+            cpName: this.dataAudition.name,
+            cpPhone: this.dataAudition.contactPhone,
+            auditionTime: this.dateAudition,
+            salesCode: this.dataAudition.saleCode
+          }
+          postAction("/customer/customerInfo/addAudition", params).then((res) => {
+            if (res.success) {
+              this.$emit('ok');
+              this.$message.success(res.message);
+            } else {
+              this.$message.warn(res.message);
+            }
+          }).finally(() => {
+            this.auditionVisible = false;
+            this.auditionloading = false;
+            this.dateAudition = "";
+            this.dataAudition = "";
+            this.loadData();
+          });
+        }
+      },
+      handleAudition(row) {
+        this.auditionVisible = true;
+        this.dataAudition = row;
+      },
+      auditionCancel(){
+        this.dateAudition = "";
+        this.dataAudition = "";
+        this.auditionVisible = false;
+      },
+      onChangeTime(value,dateString) {
+        this.nextFollowTime = dateString;
+        this.realFollowTime  = dateString;
+      },
+      handleFollowDetail(row) {
+        this.followDetailVisible = true;
+        let params = {
+          cp_id:row.id
+        }
+        postAction("/customer/customerFollow/followDetail", params).then((res) => {
+          if (res.length > 0) {
+            this.dataFollowDetail = res;
+          } else {
+            this.$message.success("无跟进信息");
+          }
+        });
+      },
+      cancelFollowDetail() {
+        this.followDetailVisible = false;
+        this.dataFollowDetail = [];
+      },
+      searchReset() {
+        this.queryParam = {
+          type: 5
+        };
+        this.loadData();
+        this.checked = false;
+      },
+      invalidChange(value) {
+        this.checked = !value;
+        if (this.checked) {
+          this.queryParam.noInvalid = "unShow";
+          this.loadData();
+        } else {
+          this.queryParam.noInvalid = null;
+          this.loadData();
+        }
+      },
+      handleInput(e) {
+        if (e == 0) {
+          this.queryParam.type = undefined
+        } else {
+          this.queryParam.type = e
+        }
+      },
+      // var params = this.getQueryParams();//获取查询条件
+      // searchQuery() {
+      //   console.log(this.getQueryParams());
+      //   this.queryParam = {
+      //     type: 5
+      //   };
+      //   this.loadData(this.queryParam);
+      // }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>
+<!-- <style lang="less" scoped>
+  /deep/ .ant-modal-content {
+    height: 400px;
+  }
+</style> -->

+ 835 - 0
src/views/mili/customer/modules/PotentialListTabs.vue

@@ -0,0 +1,835 @@
+<template>
+  <!-- tab区域 -->
+  <a-card :bordered="false" :body-style="{ padding: '0px 0px 8px' }" >
+   <a-radio-group v-model:value="groups" button-style="solid" @change="groupChange" style="margin-bottom: 16px">
+    <a-radio-button value="1">全部</a-radio-button>
+    <a-radio-button value="2">新分配
+      <span v-if="groups!='2'" style="color:#1890ff;">({{newAppoint}})</span>
+      <span v-else style="color:#fff;">({{newAppoint}})</span>
+      </a-radio-button>
+    <a-radio-button value="3">今日待跟进
+      <span v-if="groups!='3'" style="color: #1890ff;">({{todayAppoint}})</span>
+      <span v-else style="color: #fff;">({{todayAppoint}})</span>
+      </a-radio-button>
+    <a-radio-button value="4">过去未跟进
+      <span v-if="groups!='4'" style="color: #1890ff;">({{agoAppoint}})</span>
+      <span v-else style="color: #fff;">({{agoAppoint}})</span>
+      </a-radio-button>
+  </a-radio-group>
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="关键字">
+              <a-input placeholder="请输入姓名、家长姓名、联系方式、备注" v-model="queryParam.keywords"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="录入日期">
+                <a-range-picker v-model="queryParam.dateQ"
+                  format="YYYY-MM-DD"
+                  :placeholder="['开始日期', '结束日期']"
+                  @change="onCreateTimeChange" />
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="校区ID">
+                <j-dict-select-tag placeholder="请选择校区ID" v-model="queryParam.schoolDistrictId" dictCode="school_organization,name,id"/>
+              </a-form-item>
+            </a-col>
+          <template v-if="toggleSearchStatus">
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="跟进状态">
+                <j-dict-select-tag placeholder="请选择跟进状态" v-model="queryParam.followStatus" dictCode="customer_follow_status"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="学员类型">
+                <!-- <j-dict-select-tag placeholder="请选择类型"  v-model="queryParam.type" dictCode="customer_pc_type"/> -->
+                <a-select  v-model="selectValue" @change="handleInput">
+                  <a-select-option value= 0 >全部</a-select-option>
+                  <a-select-option v-for="(item, key) in typeOptions" :key="key" :value="item.value">
+                    <span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
+                      {{ item.text || item.label }}
+                    </span>
+                  </a-select-option>
+                </a-select>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="意向课程">
+                <j-dict-select-tag placeholder="请选择意向课程" v-model="queryParam.intendedCourse" dictCode="education_course,name,id"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="上次跟进">
+                <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择上次跟进" v-model="queryParam.lastFollowTime"></j-date>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="顾问">
+                <j-select-user-by-dep placeholder="请选择顾问" v-model="queryParam.saleCode"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="采单员">
+                <j-select-user-by-dep placeholder="请选择采单员" v-model="queryParam.collectinoCode"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="渠道类型">
+                <j-tree-select
+                ref="treeSelect"
+                placeholder="请选择渠道类型"
+                v-model="queryParam.channelType"
+                dict="promotion_channel,name,id"
+                pidValue="0"
+                >
+              </j-tree-select>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="意向度">
+                <j-dict-select-tag placeholder="请选择意向度" v-model="queryParam.intendedDegress" dictCode="customer_intention_status"/>
+              </a-form-item>
+            </a-col>
+            <!-- 年龄 -->
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+             <a-form-item label="年龄">
+              <a-input-group >
+                <a-input type = "number" v-model:value="queryParam.ageMin" 
+                style="width: 100px; text-align: center ; border-right: 0;" placeholder="最小年龄" />
+                <a-input v-model:value="value13"
+                  style="width: 30px; border-left: 0; border-right: 0; pointer-events: none; background-color: #fff"
+                  placeholder="~" disabled />
+                <a-input type = "number" v-model:value="queryParam.ageMax"
+                  style="width: 100px; text-align: center; border-left: 0" placeholder="最大年龄" />
+              </a-input-group>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="年级">
+                <j-dict-select-tag placeholder="请选择年级" v-model="queryParam.grade" dictCode="customer_grade"/>
+              </a-form-item>
+            </a-col>
+            <!-- 标签 -->
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="学校">
+                <j-dict-select-tag placeholder="请选择学校" v-model="queryParam.school" dictCode="school_school,name,id"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="">
+                <a-checkbox :checked="checked"  @change="invalidChange(checked)">不显示无效潜客</a-checkbox>
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button type="primary" icon="download" @click="handleExportXls('潜客管理')">导出</a-button>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleFollow(record)">跟进</a> 
+          <a-divider type="vertical" />
+          <a @click="handleAudition(record)">试听</a>
+          <a-divider type="vertical" />
+          <a @click="handleSign(record)">报名</a>
+          <a-divider type="vertical"/>
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleEdit(record)">编辑</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a @click="handleVisiting(record)" v-has="'user:appoint'">预约来访</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a @click="handleReject(record)" v-has="'user:appoint'">转让潜客</a>
+              </a-menu-item>
+              <a-menu-item>
+                 <a @click="handleInvalid(record)" v-has="'user:appoint'">放回公池</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+       <!--插槽NNNN-->
+       <a slot="detail" slot-scope="text, record" @click="handleFollowDetail(record)" >{{text}}</a>
+      </a-table>
+    </div>
+    
+     <a-modal
+      title="来访信息添加"
+      ok-text="确认" 
+      cancel-text="取消"
+      :visible="visitingVisible"
+      :confirm-loading="visitingloading"
+      @ok="visitingOk"
+      @cancel="visitingCancel">
+      <a-form-item label="客户来访日期"  style="width: 400px">
+        <a-date-picker v-model="dateStr" 
+        name = "dateStr"
+        dateFormat="YYYY-MM-DD"
+        :disabledDate="disabledDate"
+        v-decorator="['dateStr',rules.date]"
+        ></a-date-picker>
+      </a-form-item>
+    </a-modal>
+
+    <a-modal
+      title="试听信息添加"
+      ok-text="确认" 
+      cancel-text="取消"
+      :visible="auditionVisible"
+      :confirm-loading="auditionloading"
+      @ok="auditionOk"
+      @cancel="auditionCancel">
+      <a-form-item label="客户试听日期"  style="width: 400px">
+        <a-date-picker v-model="dateAudition" 
+        name = "dateAudition"
+        dateFormat="YYYY-MM-DD"
+        :disabledDate="disabledDate"
+        v-decorator="['dateAudition',rules.date]"
+        ></a-date-picker>
+      </a-form-item>
+    </a-modal>
+
+
+    <a-modal
+      title="跟进详情"
+      :visible="followDetailVisible"
+      :width=900
+      @cancel="cancelFollowDetail"
+      cancelText="关闭"
+      :body-style="{width:200}"
+      >
+      <a-list item-layout="horizontal" :data-source="dataFollowDetail">
+          <a-list-item :key="index" v-for="(item, index) in dataFollowDetail">
+              <a-list-item-meta>
+               <template #title>
+                <a-descriptions bordered>
+                  <a-descriptions-item label="潜客姓名">{{item.cpName}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进人">{{item.salesName}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进日期">{{item.createTime}}</a-descriptions-item>
+                  <a-descriptions-item label="校区" :span="1">{{item.schoolDistrictName}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进类型" :span="2">{{item.followType}}</a-descriptions-item>
+                  <a-descriptions-item label="跟进内容" :span="3">{{item.followContent}}</a-descriptions-item>
+                  <a-descriptions-item label="图片" :span="3">
+                   <!-- 为啥不能用a-image? -->
+                   <div v-if="item.picList != null">
+                      <div v-if = "(item.picList.more)">
+                        <div v-for="(imgItem,index) in item.picList.imgPath" :key="index">
+                          <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
+                            <div
+                              style="width: 100%;height: 100%;position: relative;padding: 8px;border: 0px solid #d9d9d9;border-radius: 4px;">
+                              <img style="width: 100%;" :src="imgItem.imgUrl" :preview="item.picList.key">
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                      <div v-else>
+                         <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
+                            <div
+                              style="width: 100%;height: 100%;position: relative;padding: 8px;border: 0px solid #d9d9d9;border-radius: 4px;">
+                              <img style="width: 100%;" :src="item.picList.imgPath.imgUrl" :preview="item.picList.key">
+                            </div>
+                          </div>
+                      </div>
+                   </div>
+                  </a-descriptions-item>
+                </a-descriptions>
+               </template>
+            </a-list-item-meta>
+          </a-list-item>
+      </a-list>
+
+       <template slot="footer">
+        <a-button key="back" @click="cancelFollowDetail">关闭</a-button>
+      </template>
+    </a-modal>
+<!-- 自定义组件调用 -->
+    <CustomerFollowAdd :follow-add-visible.sync="followAddVisible"  :addRow="addRow" /> 
+    <CustomerAuditionAdd :auditioning-add-visible.sync="auditioningAddVisible"  :addRow="addRow" /> 
+    <customer-potential-modal ref="modalForm" @ok="modalFormOk"></customer-potential-modal>
+  </a-card>
+</template>
+
+<script>
+  import {getDictItemsFromCache} from '@/api/api'
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import CustomerPotentialModal from './CustomerPotentialModal'
+  import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
+  import {postAction} from '@/api/manage'
+  import moment from 'moment'
+  import JImageUpload from '@/components/jeecg/JImageUpload'
+  import store from '@/store'
+  import JEllipsis from "@/components/jeecg/JEllipsis"
+  import CustomerFollowAdd from '../../modules/CustomerFollowAdd.vue'
+  import CustomerAuditionAdd from '../../modules/CustomerAuditionAdd.vue'
+  export default {
+    name: 'PotentialListTabs',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+      CustomerPotentialModal,JSelectMultiUser,JImageUpload,JEllipsis,CustomerFollowAdd,CustomerAuditionAdd
+    },
+    data () {
+      let ellipsis = (v, l = 20) => (<j-ellipsis value = {v} length = {l}/>)
+      return {
+        description: '潜客管理管理页面',
+        groups: "1",
+        tabQuery: null,
+        newAppoint: undefined, 
+        todayAppoint: undefined,
+        agoAppoint: undefined,
+        followAddVisible: false,//
+        auditioningAddVisible: false,
+        addRow: {},
+        dataFollow:"",
+        followDetailVisible: false,
+        visitingVisible: false,
+        visitingloading: false,
+        dataVisit:"",
+        dateStr:"",
+        auditionVisible: false,
+        auditionloading: false,
+        dataAudition:"",
+        dateAudition:"",
+        form: this.$form.createForm(this),
+        users: "",
+        dataFollowDetail: [],
+        key:"",
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'姓名',
+            align:"center",
+            dataIndex: 'name',
+            scopedSlots: { customRender: 'detail' }
+          },
+          {
+            title:'联系方式',
+            align:"center",
+            dataIndex: 'contactPhone'
+          },
+          {
+            title:'意向度', 
+            align:"center",
+            dataIndex: 'intendedDegress_dictText'
+          },
+          {
+            title:'意向课程',
+            align:"center",
+            dataIndex: 'intendedCourse_dictText'
+          },
+          {
+            title:'顾问',
+            align:"center",
+            dataIndex: 'saleCode_dictText'
+          },
+          {
+            title:'最近跟进时间',
+            align:"center",
+            dataIndex: 'lastFollowTime'
+          },
+          {
+            title:'最近跟进记录',
+            align:"center",
+            dataIndex: 'follow_log'
+          },
+          {
+            title:'下次跟进日期',
+            align:"center",
+            dataIndex: 'nextFollowTime'
+          },
+          {
+            title:'跟进状态',
+            align:"center",
+            dataIndex: 'followStatusDictText'
+          },
+          {
+            title:'学员类型',
+            align:"center",
+            dataIndex: 'type_dictText'
+          },
+          {
+            title:'年龄',
+            align:"center",
+            dataIndex: 'birthday'
+          },
+          {
+            title:'来源',
+            align:"center",
+            dataIndex: 'channelType_dictText'
+          },
+          {
+            title:'采单员',
+            align:"center",
+            dataIndex: 'collectinoCode_dictText'
+          },
+          {
+            title:'学校',
+            align:"center",
+            dataIndex: 'school_dictText'
+          },
+          {
+            title:'年级',
+            align:"center",
+            dataIndex: 'grade_dictText'
+          },
+          {
+            title:'备注',
+            align:"center",
+            dataIndex: 'markString',
+            customRender: (text) => {
+              return ellipsis(text);
+            }
+          },
+          {
+            title:'录入时间',
+            align:"center",
+            dataIndex: 'createTime'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        rules: {
+          date: [
+            { required: true, message: '请输入预约日期!', trigger: 'blur'},
+           ],
+        },
+        url: {
+          list: "/customer/customerInfo/list",
+          delete: "/customer/customerInfo/delete",
+          deleteBatch: "/customer/customerInfo/deleteBatch",
+          exportXlsUrl: "/customer/customerInfo/exportXls",
+          importExcelUrl: "customer/customerInfo/importExcel",
+          
+        },
+        dictOptions:{},
+        superFieldList:[],
+        imageSource: [{
+          key:0,
+          fileDetails:[
+            {
+              imgUrl:"https://static.jeecg.com/upload/test/3a4490d5d1cd495b826e528537a47cc1.jpg"
+            },
+            {
+              imgUrl:"https://static.jeecg.com/temp/国炬软件logo_1606575029126.png"
+            }
+          ]
+          },{
+            key:1,
+            fileDetails:[
+              {
+                imgUrl:"https://static.jeecg.com/upload/test/u27356337152749454924fm27gp0_1588149731821.jpg"
+              },
+              {
+                imgUrl:"https://static.jeecg.com/upload/test/1_1588149743473.jpg"
+              }
+            ]
+          }
+      ],
+      typeOptions:[],
+      selectValue: "0",
+      ageMin: undefined,
+      ageMax: undefined,
+      value13: undefined,
+      checked: false
+      }
+    },
+    props: ['tabPara'],
+    created() {
+      this.getSuperFieldList();
+      let params = {
+        tabs: this.tabQuery,
+        saleCode:store.getters.userInfo.username
+      };
+      postAction("/customer/customerInfo/getGroupCounts", params).then((res) => {
+        this.newAppoint = res.result.newAppoint;
+        this.todayAppoint = res.result.todayAppoint;
+        this.agoAppoint = res.result.agoAppoint;
+      }).finally(() => {
+        this.dialogloading = false;
+        this.dialogPvVisible = false;
+        this.loadData();
+      });
+      this.typeOptions = getDictItemsFromCache('customer_pc_type');
+    },
+    watch: {
+      tabPara : {
+        immediate: true,
+        handler(param){
+          if (String(param) === "2") {
+            this.tabQuery = 2;
+            this.queryParam = {
+              saleCode:store.getters.userInfo.username
+            }
+          } else if (String(param) === "3") {
+            this.tabQuery = null;
+            this.queryParam = {
+              type: 5
+            };
+          } else if (String(param) === "1") {
+            this.tabQuery = null;
+          } 
+        }
+      },
+      followAddVisible:{
+        handler(param){
+          if(!param) {
+            // 子组件回调 页面刷新,不是很优雅
+            this.loadData();
+          }
+        }
+      },
+      auditioningAddVisible:{
+        handler(param){
+          if(!param) {
+            // 子组件回调 页面刷新,不是很优雅
+            this.loadData();
+          }
+        }
+      }
+
+    },
+    methods: {
+      disabledDate(current) {
+        return current < moment().endOf("day"); // 当前时间之前的所有日期都禁用
+      },
+      disabledFollowDate(current) {
+        return current > moment().endOf("day"); // 当前时间之后的所有日期都禁用
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'int',value:'schoolDistrictId',text:'校区ID',dictCode:"school_organization,name,id"})
+        fieldList.push({type:'string',value:'name',text:'姓名',dictCode:''})
+        fieldList.push({type:'string',value:'nickname',text:'昵称',dictCode:''})
+        fieldList.push({type:'int',value:'sex',text:'性别',dictCode:'sex'})
+        fieldList.push({type:'string',value:'contactName',text:'家长姓名',dictCode:''})
+        fieldList.push({type:'string',value:'contactPhone',text:'家长电话',dictCode:''})
+        fieldList.push({type:'string',value:'contact1Name',text:'备选联系人1',dictCode:''})
+        fieldList.push({type:'string',value:'contact1Phone',text:'备选联系人1电话',dictCode:''})
+        fieldList.push({type:'string',value:'contact2Name',text:'备选联系人2',dictCode:''})
+        fieldList.push({type:'string',value:'contact2Phone',text:'备选联系人2电话',dictCode:''})
+        fieldList.push({type:'int',value:'age',text:'年龄',dictCode:''})
+        fieldList.push({type:'date',value:'birthday',text:'生日'})
+        fieldList.push({type:'string',value:'school',text:'学校',dictCode:"school_school,name,id"})
+        fieldList.push({type:'string',value:'grade',text:'年级',dictCode:'customer_grade'})
+        fieldList.push({type:'string',value:'class',text:'班级',dictCode:''})
+        fieldList.push({type:'string',value:'idCard',text:'身份证',dictCode:''})
+        fieldList.push({type:'string',value:'address',text:'住址',dictCode:''})
+        fieldList.push({type:'string',value:'channelType',text:'渠道类型'})
+        fieldList.push({type:'string',value:'intendedCourse',text:'意向课程',dictCode:"education_course,name,id"})
+        fieldList.push({type:'int',value:'intendedDegress',text:'意向度',dictCode:'customer_intention_status'})
+        fieldList.push({type:'sel_user',value:'saleCode',text:'顾问'})
+        fieldList.push({type:'string',value:'referencesPhone',text:'推荐人',dictCode:''})
+        fieldList.push({type:'sel_user',value:'collectinoCode',text:'采单员'})
+        fieldList.push({type:'int',value:'status',text:'状态',dictCode:'customer_pc_status'})
+        fieldList.push({type:'int',value:'followStatus',text:'跟进状态',dictCode:'customer_follow_status'})
+        fieldList.push({type:'datetime',value:'lastFollowTime',text:'上次跟进'})
+        fieldList.push({type:'datetime',value:'nextFollowTime',text:'下次跟进'})
+        fieldList.push({type:'Blob',value:'mark',text:'备注',dictCode:''})
+        this.superFieldList = fieldList
+      },
+      handleFollow(row) {
+        this.followAddVisible = true;
+        this.addRow = row;
+      },
+      handleAudition(row) {
+        this.auditioningAddVisible = true;
+        this.addRow = row;
+      },
+      onCreateTimeChange: function (value, dateString) {
+        this.queryParam.beginTime=dateString[0];
+        this.queryParam.endTime=dateString[1];
+      },
+      handleSign(row) {
+        let params = {
+          id: row.id,
+          status: 2,
+          followStatus: 8,
+          name: row.name,
+          contactPhone: row.contactPhone
+        }
+        postAction("/customer/customerInfo/sign", params).then((res) => {
+          if (res.success) {
+            this.$emit('ok');
+            this.$message.success(res.message);
+          } else {
+            this.$message.warn('报名失败:' + res.message);
+          }
+        }).finally(() => {
+          this.dialogloading = false;
+          this.dialogPvVisible = false;
+          this.loadData();
+        });
+      },
+      handleReject(row) {
+         let params = {
+          id: row.id,
+          status: 3,
+          followStatus: 1,
+          name: row.name,
+          contactPhone: row.contactPhone
+        }
+        postAction("/customer/customerInfo/statusEdit", params).then((res) => {
+          if (res.success) {
+            this.$emit('ok');
+            this.$message.success(res.message);
+          } else {
+            this.$message.warn('修改失败:' + res.message);
+          }
+        }).finally(() => {
+          this.dialogloading = false;
+          this.dialogPvVisible = false;
+          this.loadData();
+        });
+      },
+      handleInvalid(row) {
+        let params = {
+          id: row.id,
+          status: 4,
+          followStatus: 9,
+          name: row.name,
+          contactPhone: row.contactPhone
+        }
+        postAction("/customer/customerInfo/statusEdit", params).then((res) => {
+          if (res.success) {
+            this.$emit('ok');
+            this.$message.success(res.message);
+          } else {
+            this.$message.warn('修改失败:' + res.message);
+          }
+        }).finally(() => {
+          this.dialogloading = false;
+          this.dialogPvVisible = false;
+          this.loadData();
+        });
+      },
+      getFormFieldValue(field){
+        return this.form.getFieldValue(field)
+      },
+      visitingOk(){
+        if (this.dateStr == "") {
+          this.$message.warn('请输入客户预约日期!');
+          return null;
+        } else {
+          this.visitingloading = true;
+          let params = {
+            schoolDistrictId: this.dataVisit.schoolDistrictId,
+            cpId: this.dataVisit.id,
+            cpName: this.dataVisit.name,
+            cpPhone: this.dataVisit.contactPhone,
+            visitingTime: this.dateStr,
+            salesCode: this.dataVisit.saleCode
+          }
+          postAction("/customer/customerInfo/addVisit", params).then((res) => {
+            if (res.success) {
+              this.$emit('ok');
+              this.$message.success(res.message);
+            } else {
+              this.$message.warn(res.message);
+            }
+          }).finally(() => {
+            this.visitingloading = false;
+            this.visitingVisible = false;
+            this.dateStr = "";
+            this.dataVisit = "";
+            this.loadData();
+          });
+        }
+      },
+      handleVisiting(row) {
+        this.visitingVisible = true;
+        this.dataVisit = row;
+      },
+      visitingCancel(){
+        this.dateStr = "";
+        this.dataVisit = "";
+        this.visitingVisible = false;
+      },
+
+      auditionOk() {
+        if (this.dateAudition == "") {
+          this.$message.warn('请输入客户试听日期!');
+          return null;
+        } else {
+          this.auditionloading = true;
+          let params = {
+            schoolDistrictId: this.dataAudition.schoolDistrictId,
+            cpId: this.dataAudition.id,
+            cpName: this.dataAudition.name,
+            cpPhone: this.dataAudition.contactPhone,
+            auditionTime: this.dateAudition,
+            salesCode: this.dataAudition.saleCode
+          }
+          postAction("/customer/customerInfo/addAudition", params).then((res) => {
+            if (res.success) {
+              this.$emit('ok');
+              this.$message.success(res.message);
+            } else {
+              this.$message.warn(res.message);
+            }
+          }).finally(() => {
+            this.auditionVisible = false;
+            this.auditionloading = false;
+            this.dateAudition = "";
+            this.dataAudition = "";
+            this.loadData();
+          });
+        }
+      },
+      
+      auditionCancel(){
+        this.dateAudition = "";
+        this.dataAudition = "";
+        this.auditionVisible = false;
+      },
+      handleFollowDetail(row) {
+        this.followDetailVisible = true;
+        let params = {
+          cp_id:row.id
+        }
+        postAction("/customer/customerFollow/followDetail", params).then((res) => {
+          if (res.length > 0) {
+            this.dataFollowDetail = res;
+          } else {
+            this.$message.success("无跟进信息");
+          }
+        });
+      },
+      cancelFollowDetail() {
+        this.followDetailVisible = false;
+        this.dataFollowDetail = [];
+      },
+      groupChange(value) {
+        if (this.tabQuery === 2 ) {
+          this.queryParam = {
+            groups: value.target.value,
+            tabs: this.tabQuery,
+            saleCode: store.getters.userInfo.username
+          }
+        } else {
+          this.queryParam = {
+            groups: value.target.value
+          }
+        }
+        this.loadData(this.queryParam);
+      },
+      searchReset() {
+        this.groups = "1";
+        this.checked = false;
+        if(this.tabQuery == '2') {
+          this.queryParam = {
+            tabs: this.tabQuery,
+            saleCode:store.getters.userInfo.username 
+          };
+        } else {
+          this.tabQuery = null;
+          this.queryParam = {};
+        }
+        this.selectValue = "0";
+        this.loadData();
+      },
+      handleInput(e) {
+        if (e == 0) {
+          this.queryParam.type = undefined
+        } else {
+          this.queryParam.type = e
+        }
+      },
+      invalidChange(value) {
+        this.checked = !value;
+        if (this.checked) {
+          this.queryParam.noInvalid = "unShow";
+          this.loadData();
+        } else {
+          this.queryParam.noInvalid = null;
+          this.loadData();
+        }
+      },
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>
+<!-- <style lang="less" scoped>
+  /deep/ .ant-modal-content {
+    height: 400px;
+  }
+</style> -->

+ 156 - 0
src/views/mili/modules/CustomerAuditionAdd.vue

@@ -0,0 +1,156 @@
+<template>
+  <a-modal title="选择课程" ok-text="确认" cancel-text="取消" :width="1000" :visible="auditionVisible" @ok="auditionOk"
+    @cancel="auditionCancel">
+    <a-tabs @change="handleChangeTab" :tab-bar-style="{marginTop: '-20px', paddingLeft: '0px'}">
+      <a-tab-pane tab="试听课" key="1">
+        <!-- 查询条件Audition -->
+        <a-range-picker v-model="auditionQuery.date" format="YYYY-MM-DD" :placeholder="['开始日期', '结束日期']"
+          @change="handleQueryTimeChange" :style="{width: '222px'}" />
+        <DropDownSearch menuName='选择课程' :QueryList='courseList' :QueryReset='reset'></DropDownSearch>
+        <DropDownSearch menuName='选择老师' :QueryList='lecturerList' :QueryReset='reset'></DropDownSearch>
+        <DropDownSearch menuName='星期' :QueryList='weekList' :QueryReset='reset'></DropDownSearch>
+        <a style="margin-left: 10px;" href="javascript:;" @click="handleReset()">重置</a>
+        <!-- 选择区域 -->
+      </a-tab-pane>
+
+      <a-tab-pane tab="正式课" key="2">
+        34formal
+      </a-tab-pane>
+    </a-tabs>
+    <!-- <a-form-item label="客户来访日期"  style="width: 400px">
+        <j-date v-decorator="['dateStr',rules.date]" :show-time="false" date-format="YYYY-MM-DD" :disabledDate="disabledDate" v-model="dateStr">
+        </j-date>
+      </a-form-item> -->
+  </a-modal>
+</template>
+<script>
+import { getAction, postAction } from '@/api/manage'
+import { getDictItemsFromCache} from '@/api/api'
+import { initDictOptions } from '@/components/dict/JDictSelectUtil'
+import DropDownSearch from '../components/DropDownSearch'
+import moment from 'moment'
+export default {
+    name: 'CustomerAuditionAdd',
+    components: {
+      DropDownSearch
+    },
+    data() {
+        return {
+            auditionVisible: false,
+            auditionQuery: {},
+            courseList: undefined,
+            lecturerList: undefined,
+            weekList: undefined,
+            dateStr: "",
+            reset: "",
+            rules: {
+                date: [
+                    { required: true, message: '请输入预约日期!', trigger: 'blur'},
+                ],
+            },
+        }
+    },
+    props: ['auditioningAddVisible', 'addRow'],
+    watch: {
+        auditioningAddVisible: {
+          handler() {
+              this.auditionVisible = this.auditioningAddVisible
+              initDictOptions('customer_follow_type').then((res) => {
+                  if (res.success) {
+                      this.followTypeList = res.result;
+                  }
+              });
+              this.followDate = moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
+          },
+        }
+    },
+    created () {
+      //给子组件传递数据 课程信息
+      getAction("/education/educationCourse/queryList").then((res) => {
+        this.courseList = res;
+      });
+      //给子组件传递数据 老师信息
+      getAction("/sys/user/getMultiUser").then((res) => {
+        let listTemp = [];
+        for(let item of res) {
+          let temp = {
+            "id": item.id,
+            "name":item.realname
+          }
+          listTemp.push(temp)
+        }
+        this.lecturerList = listTemp;
+      });
+      //给子组件传递数据 星期
+      this.weekList = [ {"id": 1 , "name": "星期一"}, {"id": 2 , "name": "星期二"}, 
+      {"id": 3 , "name": "星期三"}, {"id": 4 , "name": "星期四"}, {"id": 5 , "name": "星期五"}, 
+      {"id": 6 , "name": "星期六"}, {"id": 7 , "name": "星期日"} ];
+    },
+    methods: {
+        handleChangeTab(key) {
+            if (key == 1) {
+                this.timer1 = new Date().getTime();
+            } else if (key == 2) {
+                this.timer2 = new Date().getTime();
+            }
+        },
+        disabledDate(current) {
+            return current < moment().endOf("day"); // 当前时间之前的所有日期都禁用
+        },
+        disabledFollowDate(current) {
+            return current > moment().endOf("day"); // 当前时间之后的所有日期都禁用
+        },
+        auditionOk(){
+        if (this.dateStr == "") {
+          this.$message.warn('请输入客户预约日期!');
+          return null;
+        } else {
+          this.visitingloading = true;
+          let params = {
+            schoolDistrictId: this.dataVisit.schoolDistrictId,
+            cpId: this.dataVisit.id,
+            cpName: this.dataVisit.name,
+            cpPhone: this.dataVisit.contactPhone,
+            visitingTime: this.dateStr,
+            salesCode: this.dataVisit.saleCode
+          }
+          postAction("/customer/customerInfo/addVisit", params).then((res) => {
+            if (res.success) {
+              this.$emit('ok');
+              this.$message.success(res.message);
+            } else {
+              this.$message.warn(res.message);
+            }
+            }).finally(() => {
+                this.visitingloading = false;
+                this.visitingVisible = false;
+                this.dateStr = "";
+                this.dataVisit = "";
+                this.$emit('update:visitingAddVisible', false);
+            });
+          }
+        },
+        auditionCancel(){
+            this.dateStr = "";
+            this.dataVisit = "";
+            this.auditionQuery = "";
+            this.reset = true;
+            this.$emit('update:auditioningAddVisible', false);
+        },
+        onAuditionTimeChange: function (value, dateString) {
+            this.queryAudition.beginTime=dateString[0];
+            this.queryAudition.endTime=dateString[1];
+        },
+        handleQueryTimeChange() {
+
+        },
+        handleCourseChange(){
+
+        },
+        handleReset() {
+          this.auditionQuery = "";
+          this.reset = new Date().getTime();
+        }
+    }
+}
+</script>

+ 171 - 0
src/views/mili/modules/CustomerFollowAdd.vue

@@ -0,0 +1,171 @@
+<template>
+    <a-modal title="跟进信息新增" ok-text="确认" cancel-text="取消" :visible="childShow" :confirm-loading="followloading"
+        @ok="followOk" @cancel="followCancel">
+
+        <a-row >
+          <a-col :md="24" :xs="24">
+            <a-form-item label="跟进日期" :labelCol="{md: 3,xs:22}" :wrapperCol="{md: 1,xs:22}" style="width: 110%;">
+                <j-date :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" :disabledDate="disabledFollowDate"
+                    v-model="followDate" ></j-date>
+            </a-form-item>
+          </a-col>
+        </a-row> 
+
+        <a-row >
+          <a-col :md="24" :xs="24">
+            <a-form-item label="跟进状态" :labelCol="{md: 3,xs:22}" :wrapperCol="{md: 1,xs:22}" style="width: 110%;">
+                <j-dict-select-tag type="list"   style="width: 195px" v-model="followStatus" dictCode="customer_follow_status" />
+            </a-form-item>
+          </a-col>
+        </a-row> 
+
+        <a-row >
+          <a-col :md="24" :xs="24">
+            <a-form-item label="跟进类别" :labelCol="{md: 3,xs:22}" :wrapperCol="{md: 1,xs:22}" style="width: 110%;">
+                <a-radio-group v-model="followType" style="width: 395px">
+                 <a-radio v-for="(item, key) in followTypeList" :key="key" :value="item.value">{{ item.text }}</a-radio>
+                </a-radio-group>
+            </a-form-item>
+          </a-col>
+        </a-row> 
+
+        <a-row >
+          <a-col :md="24" :xs="24">
+            <a-form-item label="下次跟进" :labelCol="{md: 3,xs:22}" :wrapperCol="{md: 1,xs:22}" style="width: 110%;">
+                 <j-date :show-time="false" style="width: 195px" date-format="YYYY-MM-DD" :disabledDate="disabledDate" v-model="nextFollowTime">
+            </j-date>
+            </a-form-item>
+          </a-col>
+        </a-row> 
+
+        <a-form-item label="跟进内容">
+            <a-textarea v-model="followContent" rows="4" placeholder="请输入跟进内容" />
+        </a-form-item>
+        <a-form-item label="图片" style="width: 400px">
+            <j-image-upload text="上传" v-model="fileList" :isMultiple="true"></j-image-upload>
+        </a-form-item>
+    </a-modal>
+</template>
+<script>
+import { postAction } from '@/api/manage'
+import { initDictOptions } from '@/components/dict/JDictSelectUtil'
+import JImageUpload from '@/components/jeecg/JImageUpload'
+import moment from 'moment'
+import store from '@/store'
+export default {
+    name: 'CustomerFollowAdd',
+    components: {
+        JImageUpload
+    },
+    data() {
+        return {
+            childShow: false,
+            followloading: false,
+            followDate: undefined,
+            followStatus: 0,
+            followType: "",
+            followContent: "",
+            followDetailVisible: false,
+            nextFollowTime: "",
+            followTypeList: "",
+            followStatusList:"",
+            fileList: [],
+        }
+    },
+    props: ['followAddVisible', 'addRow'],
+    watch: {
+        followAddVisible: {
+            handler() {
+                this.childShow = this.followAddVisible
+                initDictOptions('customer_follow_type').then((res) => {
+                    if (res.success) {
+                        this.followTypeList = res.result;
+                    }
+                });
+                initDictOptions('customer_follow_status').then((res) => {
+                    if (res.success) {
+                        this.followStatusList = res.result;
+                    }
+                });
+                this.followDate = moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
+                this.followStatus = this.addRow.followStatus;
+            },
+        }
+    },
+    methods: {
+        disabledDate(current) {
+            return current < moment().endOf("day"); // 当前时间之前的所有日期都禁用
+        },
+        disabledFollowDate(current) {
+            return current > moment().endOf("day"); // 当前时间之后的所有日期都禁用
+        },
+        followOk() {
+            if (this.followDate == "") {
+                this.$message.warn('请输入跟进内容');
+                return;
+            }
+            if (this.followType == "") {
+                this.$message.warn('请输入跟进类型');
+                return;
+            }
+            if (this.followContent == "") {
+                this.$message.warn('请输入跟进内容');
+                return;
+            }
+            if (this.nextFollowTime == "") {
+                this.$message.warn('请输入跟进日期');
+                return;
+            }
+            let params = {
+                schoolDistrictId: Number(this.addRow.schoolDistrictId),
+                cpId: this.addRow.id,
+                followType: this.followType,
+                followContent: this.followContent,
+                followPic: String(this.fileList),
+                salesCode: this.addRow.saleCode,
+                createBy: store.getters.userInfo.username,
+                nextFollowTime: this.nextFollowTime,
+                followDate: this.followDate,
+                followStatus: this.followStatus
+            }
+            this.followloading = true;
+            postAction("/customer/customerFollow/addFollow", params).then((res) => {
+                if (res.success) {
+                    this.$emit('ok');
+                    this.$message.success('添加成功');
+                } else {
+                    this.$message.warn('添加失败:' + res.message);
+                }
+            }).finally(() => {
+                this.followloading = false;
+                this.followVisible = false;
+                this.followType = "";
+                this.followContent = "";
+                this.fileList = [];
+                this.dataFollow = "";
+                this.nextFollowTime = "";
+                this.$emit('update:followAddVisible', false);
+            });
+        },
+        followCancel() {
+            this.$emit('update:followAddVisible', false);
+            if(JSON.stringify(this.fileList) !== '[]' || Object.keys(this.fileList).length !== 0) {
+            let bizPath =[];
+            if(this.fileList.indexOf(",")!= -1) {
+                bizPath = this.fileList.split(',');
+            }else {
+                bizPath.push(this.fileList)
+            }
+            postAction("/sys/common/delUploadTemp", bizPath).then((res) => {
+            });
+            }
+            this.fileList = [];
+            this.dataFollow = "";
+            this.childShow = false;
+            this.followType = "";
+            this.followContent = "";
+            this.nextFollowTime = "";
+        },
+    }
+}
+</script>

+ 102 - 0
src/views/mili/modules/CustomerLogs.vue

@@ -0,0 +1,102 @@
+<template>
+    <a-modal
+        title="操作记录"
+        :visible="showCustomerLogs"
+        :confirm-loading="dialogloading"
+        :footer="null"
+        @cancel="logsCancel"
+        :width=900
+        :body-style="{width:200}">
+         <a-descriptions bordered>
+            <a-descriptions-item label="姓名" :span="3">{{customerName}}</a-descriptions-item>
+            <a-descriptions-item label="年龄">{{age}}</a-descriptions-item>
+            <a-descriptions-item label="电话">{{contactPhone}}</a-descriptions-item>
+            <a-descriptions-item label="家长" >{{contactName}}</a-descriptions-item>
+            <a-descriptions-item label="备注" :span="3">
+                {{mark}}
+            </a-descriptions-item>
+        </a-descriptions>
+        <br>
+         <a-timeline>
+            <a-timeline-item v-for="(log,index) of logs" :key="index"> 
+                <a-row>
+                    <a-col :span="6">时间: {{log.createTime}}</a-col>
+                    <a-col :span="6">事项: {{log.typeDes}}</a-col>
+                    <a-col :span="6">操作人: {{log.createBy_dictText}}</a-col>
+                    <a-col :span="6">校区: {{log.schoolDistrictId_dictText}}</a-col>
+                </a-row>
+                <a-row>
+                    <a-col :span="24">
+                        {{log.descType1}}&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #397fd4;">{{log.descComm1}}</span>
+                        &nbsp;&nbsp;&nbsp;&nbsp;{{log.descType2}}&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #397fd4;">{{log.descComm2}}</span>
+                        &nbsp;&nbsp;&nbsp;&nbsp;{{log.descType3}}&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #397fd4;">{{log.descComm3}}</span>
+                    </a-col>
+                </a-row>
+            </a-timeline-item>
+        </a-timeline>
+    </a-modal>
+</template>
+<script>
+import { getAge } from '@/utils/util';
+import {postAction} from '@/api/manage'
+
+export default {
+    data () {
+      return {
+        dialogloading: false,
+        customerName: undefined,
+        age: undefined,
+        contactPhone: undefined,
+        contactName: undefined,
+        mark: undefined,
+        birthday: undefined,
+        logs:[]
+      }
+    },
+    props: {
+        showChildDialog: {
+            type: Boolean,
+            default: false
+        },
+        logInfo: {
+            type: Object,
+            default: null
+        }
+    },
+    computed: {
+        showCustomerLogs: { 
+            get: function(para) {
+                this.customerName = para.logInfo.name;
+                this.contactPhone = para.logInfo.contactPhone;
+                this.contactName = para.logInfo.contactName;
+                this.mark = para.logInfo.markString;
+                this.birthday = para.logInfo.birthday;
+                this.age = para.logInfo.age;
+                if(para.showChildDialog) {
+                    if(para.logInfo.birthday !== null && para.logInfo.birthday !=="" && para.logInfo.birthday !== undefined) {
+                    this.age = getAge(para.logInfo.birthday);
+                    }
+                    if(para.logInfo.id !== null && para.logInfo.id !=="" && para.logInfo.id !== undefined) {
+                        let params = {
+                            customer_id: para.logInfo.id
+                        }
+                        postAction("/customer/customerLogs/queryByCustomerId", params).then((res) => {
+                            console.log(res.result.records);
+                            this.logs = res.result.records;
+                        });
+                    }
+                }
+                return this.showChildDialog
+            },
+            set: function() {
+                return
+            }
+        }
+    },
+     methods: {
+        logsCancel() {
+            this.$emit('update:showChildDialog', false) // 触发更新事件,父组件的showDialog会自动更新
+        }
+    }
+}
+</script>

+ 0 - 50
src/views/mili/modules/test.vue

@@ -1,50 +0,0 @@
-<template>
-    <a-modal
-        title="分配顾问"
-        ok-text="确认" 
-        cancel-text="取消"
-        :visible="showDialog"
-        :confirm-loading="dialogloading"
-        @ok="appointOk"
-        @cancel="appointCancel">
-        <a-form-item label="顾问选择" style="width: 300px">
-           66666
-        </a-form-item>
-    </a-modal>
-</template>
-<script>
-export default {
-    data () {
-      return {
-        dialogloading: false,
-      }
-    },
-    props: {
-        showChildDialog: {
-            type: Boolean,
-            default: false
-        }
-    },
-    computed: {
-        showDialog: {
-            get: function() {
-                return this.showChildDialog
-            },
-            set: function(newValue) {
-                this.$emit('update:showChildDialog', newValue) // 触发更新事件,父组件的showDialog会自动更新
-            }
-        }
-    },
-     methods: {
-        appointOk() {
-            console.log('appointOk!');
-            this.$parent.$parent.loadData();
-            this.showDialog =  false;
-        },
-        appointCancel() {
-           console.log('appointCancel!');
-            this.showDialog =  false;
-        }
-    }
-}
-</script>