index.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  4. <el-form-item label="客户编码" prop="customerCode">
  5. <el-input
  6. style="width:220px"
  7. v-model="queryParams.customerCode"
  8. placeholder="请输入客户编码"
  9. clearable
  10. size="small"
  11. @keyup.enter.native="handleQuery"
  12. />
  13. </el-form-item>
  14. <el-form-item label="客户名称" prop="customerName">
  15. <el-input
  16. style="width:220px"
  17. v-model="queryParams.customerName"
  18. placeholder="请输入客户名称"
  19. clearable
  20. size="small"
  21. @keyup.enter.native="handleQuery"
  22. />
  23. </el-form-item>
  24. <el-form-item label="手机" prop="mobile">
  25. <el-input
  26. style="width:220px"
  27. v-model="queryParams.mobile"
  28. placeholder="请输入手机"
  29. clearable
  30. size="small"
  31. @keyup.enter.native="handleQuery"
  32. />
  33. </el-form-item>
  34. <el-form-item label="所属部门" prop="deptId">
  35. <treeselect style="width:220px" v-model="queryParams.deptId" :options="deptOptions" :show-count="true" placeholder="请选择所属部门" />
  36. </el-form-item>
  37. <el-form-item label="客户状态" prop="status">
  38. <el-select style="width:220px" v-model="queryParams.status" placeholder="请选择客户状态" clearable size="small">
  39. <el-option
  40. v-for="item in statusOptions"
  41. :key="item.dictValue"
  42. :label="item.dictLabel"
  43. :value="item.dictValue"
  44. />
  45. </el-select>
  46. </el-form-item>
  47. <el-form-item label="跟进阶段" prop="visitStatus">
  48. <el-select style="width:220px" multiple filterable v-model="visitStatusArr" placeholder="请选择跟进阶段" clearable size="small">
  49. <el-option
  50. v-for="item in visitStatusOptions"
  51. :key="item.dictValue"
  52. :label="item.dictLabel"
  53. :value="item.dictValue"
  54. />
  55. </el-select>
  56. </el-form-item>
  57. <el-form-item label="客户类型" prop="customerLevel">
  58. <el-select style="width:220px" filterable v-model="queryParams.customerLevel" placeholder="请选择客户类型" clearable size="small">
  59. <el-option
  60. v-for="item in customerLevelOptions"
  61. :key="item.dictValue"
  62. :label="item.dictLabel"
  63. :value="item.dictValue"
  64. />
  65. </el-select>
  66. </el-form-item>
  67. <el-form-item label="客户标签" prop="tags">
  68. <el-select style="width:220px" multiple filterable v-model="tagIds" placeholder="请选择客户标签" clearable size="small">
  69. <el-option
  70. v-for="item in tagsOptions"
  71. :key="item.dictLabel"
  72. :label="item.dictLabel"
  73. :value="item.dictLabel"
  74. />
  75. </el-select>
  76. </el-form-item>
  77. <!-- <el-form-item label="是否认领" prop="isReceive">
  78. <el-select v-model="queryParams.isReceive" placeholder="请选择是否认领" clearable size="small">
  79. <el-option
  80. v-for="item in receiveOptions"
  81. :key="item.dictValue"
  82. :label="item.dictLabel"
  83. :value="item.dictValue"
  84. />
  85. </el-select>
  86. </el-form-item> -->
  87. <el-form-item label="员工姓名" prop="companyUserNickName">
  88. <el-input
  89. style="width:220px"
  90. v-model="queryParams.companyUserNickName"
  91. placeholder="请输入员工姓名"
  92. clearable
  93. size="small"
  94. @keyup.enter.native="handleQuery"
  95. />
  96. </el-form-item>
  97. <el-form-item label="创建时间" prop="createTime">
  98. <el-date-picker
  99. style="width:220px"
  100. clearable size="small"
  101. v-model="dateRange"
  102. type="daterange"
  103. value-format="yyyy-MM-dd"
  104. start-placeholder="开始日期"
  105. end-placeholder="结束日期">
  106. </el-date-picker>
  107. </el-form-item>
  108. <el-form-item label="客户来源" prop="source">
  109. <el-select style="width:220px" filterable multiple v-model="sourceArr" placeholder="请选择客户来源" clearable size="small">
  110. <el-option
  111. v-for="item in sourceOptions"
  112. :key="item.dictValue"
  113. :label="item.dictLabel"
  114. :value="item.dictValue"
  115. />
  116. </el-select>
  117. </el-form-item>
  118. <el-form-item label="是否下单" prop="isBuy">
  119. <el-select style="width:220px" filterable v-model="queryParams.isBuy" placeholder="请选择是否下单" clearable size="small">
  120. <el-option key="1" label="是" value="1" />
  121. <el-option key="0" label="否" value="0" />
  122. </el-select>
  123. </el-form-item>
  124. <el-form-item label="历史订单" prop="isHisOrder">
  125. <el-select style="width:220px" filterable v-model="queryParams.isHisOrder" placeholder="请选择历史订单" clearable size="small">
  126. <el-option key="1" label="是" value="1" />
  127. <el-option key="0" label="否" value="0" />
  128. </el-select>
  129. </el-form-item>
  130. <el-form-item>
  131. <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  132. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  133. </el-form-item>
  134. </el-form>
  135. <el-row :gutter="10" class="mb8">
  136. <el-col :span="1.5">
  137. <el-button
  138. type="success"
  139. icon="el-icon-edit"
  140. size="mini"
  141. :disabled="multiple"
  142. @click="handleAssign"
  143. v-hasPermi="['crm:customer:assignToUser']"
  144. >客户分配</el-button>
  145. </el-col>
  146. <el-col :span="1.5">
  147. <el-button
  148. type="success"
  149. size="mini"
  150. @click="handleAssignList"
  151. v-hasPermi="['crm:customerAssign:list']"
  152. >分配历史记录</el-button>
  153. </el-col>
  154. <el-col :span="1.5">
  155. <el-button
  156. type="success"
  157. size="mini"
  158. :disabled="multiple"
  159. @click="handleEditScource"
  160. v-hasPermi="['crm:customer:editScource']"
  161. >修改客户来源</el-button>
  162. </el-col>
  163. <el-col :span="1.5">
  164. <el-button
  165. type="success"
  166. size="mini"
  167. :disabled="multiple"
  168. @click="handleSendBatchSms"
  169. v-hasPermi="['crm:customer:sendBatchSms']"
  170. >批量发送短信</el-button>
  171. </el-col>
  172. <el-col :span="1.5">
  173. <el-button
  174. type="success"
  175. icon="el-icon-edit"
  176. size="mini"
  177. @click="handleAddScource"
  178. v-hasPermi="['crm:customer:source']"
  179. >客户来源</el-button>
  180. </el-col>
  181. <el-col :span="1.5">
  182. <el-button
  183. type="warning"
  184. icon="el-icon-download"
  185. size="mini"
  186. @click="handleExport"
  187. v-hasPermi="['crm:customer:export']"
  188. >导出</el-button>
  189. </el-col>
  190. <el-col :span="1.5">
  191. <el-button
  192. type="warning"
  193. icon="el-icon-upload2"
  194. size="mini"
  195. @click="handleImport"
  196. v-hasPermi="['crm:customer:importVisit']"
  197. >导入跟进阶段</el-button>
  198. </el-col>
  199. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  200. </el-row>
  201. <el-tabs type="card" v-model="queryParams.isReceive" @tab-click="handleClick">
  202. <el-tab-pane label="未领取" name="0"></el-tab-pane>
  203. <el-tab-pane label="已领取" name="1"></el-tab-pane>
  204. </el-tabs>
  205. <el-table height="500" border v-loading="loading" :data="customerList" @selection-change="handleSelectionChange">
  206. <el-table-column type="selection" width="55" align="center" />
  207. <el-table-column label="客户编码" align="center" prop="customerCode" />
  208. <el-table-column label="客户名称" align="center" prop="customerName" :show-overflow-tooltip="true">
  209. <template slot-scope="scope">
  210. <el-link @click="handleShow(scope.row)" :underline="false" type="primary" >{{scope.row.customerName}}</el-link>
  211. </template>
  212. </el-table-column>
  213. <el-table-column label="手机" width="120px" align="center" prop="mobile" >
  214. <template slot-scope="scope">
  215. {{scope.row.mobile}}
  216. </template>
  217. </el-table-column>
  218. <el-table-column label="客户来源" align="center" prop="source">
  219. <template slot-scope="scope">
  220. <el-tag prop="status" v-for="(item, index) in sourceOptions" v-if="scope.row.source==item.dictValue">{{item.dictLabel}}</el-tag>
  221. </template>
  222. </el-table-column>
  223. <el-table-column label="客户类型" width="200" align="center" prop="customerLevel">
  224. <template slot-scope="scope">
  225. <el-tag v-for="(item, index) in customerLevelOptions" v-if="scope.row.customerLevel===item.dictValue">{{item.dictLabel}}</el-tag>
  226. </template>
  227. </el-table-column>
  228. <el-table-column label="标签" align="center" prop="tags" />
  229. <el-table-column label="备注" align="center" prop="remark" />
  230. <el-table-column label="进线客户详情" align="center" :show-overflow-tooltip="true" prop="registerDesc" />
  231. <el-table-column label="领取时间" align="center" prop="receiveTime" />
  232. <el-table-column label="进线客户提交日期" align="center" prop="registerSubmitTime" />
  233. <el-table-column label="创建时间" align="center" prop="createTime" width="180">
  234. </el-table-column>
  235. <el-table-column label="认领人" align="center" prop="companyUserNickName" :show-overflow-tooltip="true">
  236. </el-table-column>
  237. <!-- <el-table-column label="最后一次跟进时间" align="center" prop="receiveTime" width="180"> -->
  238. <!-- </el-table-column> -->
  239. <el-table-column label="入公海时间" align="center" prop="poolTime" width="180">
  240. </el-table-column>
  241. <el-table-column label="成交总价" align="center" prop="payMoney"/>
  242. <el-table-column label="成交类型" align="center" prop="orderType">
  243. <template slot-scope="scope">
  244. <el-tag v-for="item in orderTypeOptions" v-if="scope.row.orderType === item.dictValue">{{item.dictLabel}}</el-tag>
  245. </template>
  246. </el-table-column>
  247. <el-table-column label="最新下单时间" align="center" prop="orderTime" width="180"></el-table-column>
  248. <el-table-column label="跟进阶段" width="200" align="center" prop="visitStatus">
  249. <template slot-scope="scope">
  250. <el-tag prop="visitStatus" v-for="(item, index) in visitStatusOptions" v-if="scope.row.visitStatus==item.dictValue">{{item.dictLabel}}</el-tag>
  251. </template>
  252. </el-table-column>
  253. <el-table-column label="跟进类型" align="center" prop="visitType">
  254. <template slot-scope="scope">
  255. <el-tag v-for="item in visitTypeOptions" v-if="scope.row.visitType === item.dictValue">{{item.dictLabel}}</el-tag>
  256. </template>
  257. </el-table-column>
  258. <el-table-column label="跟进内容" align="center" prop="visitContent"/>
  259. <el-table-column label="最新跟进时间" align="center" prop="visitTime" width="180"></el-table-column>
  260. <el-table-column label="操作" align="center" fixed="right" width="120px" class-name="small-padding fixed-width">
  261. <template slot-scope="scope">
  262. <!-- <el-button
  263. size="mini"
  264. type="text"
  265. icon="el-icon-edit"
  266. @click="handleUpdate(scope.row)"
  267. v-hasPermi="['crm:customer:edit']"
  268. >修改</el-button> -->
  269. <el-button
  270. size="mini"
  271. type="text"
  272. @click="handleShow(scope.row)"
  273. v-hasPermi="['crm:customer:query']"
  274. >查看</el-button>
  275. <el-button
  276. v-if="scope.row.isReceive==1"
  277. size="mini"
  278. type="text"
  279. @click="handleRecover(scope.row)"
  280. v-hasPermi="['crm:customer:recover']"
  281. >回收公海</el-button>
  282. <!-- <el-button
  283. size="mini"
  284. type="text"
  285. @click="handleAssign(scope.row)"
  286. v-hasPermi="['crm:customer:assign']"
  287. >分配客户</el-button> -->
  288. <el-button
  289. size="mini"
  290. type="text"
  291. icon="el-icon-mouse"
  292. @click="handleSwitchToTop(scope.row)"
  293. v-hasPermi="['crm:customer:switchToTop']"
  294. >{{ scope.row.isTop === 1 ? '取消置顶' : '置顶' }}</el-button>
  295. </template>
  296. </el-table-column>
  297. </el-table>
  298. <pagination
  299. v-show="total>0"
  300. :total="total"
  301. :page.sync="queryParams.pageNum"
  302. :limit.sync="queryParams.pageSize"
  303. @pagination="getList"
  304. />
  305. <el-drawer
  306. size="75%"
  307. :title="show.title" :visible.sync="show.open"
  308. >
  309. <customer-details ref="customerDetails" />
  310. </el-drawer>
  311. <el-dialog :title="addSms.title" :visible.sync="addSms.open" width="1000px" append-to-body>
  312. <add-batch-sms ref="sms" @close="closeSms()"></add-batch-sms>
  313. </el-dialog>
  314. <el-dialog :title="source.title" :visible.sync="source.open" width="1000px" append-to-body>
  315. <edit-source ref="editSource" @close="closeSource()"></edit-source>
  316. </el-dialog>
  317. <el-dialog :title="customerSource.title" :visible.sync="customerSource.open" width="1000px" append-to-body>
  318. <customer-source ref="customerSource" @close="closeSource()"></customer-source>
  319. </el-dialog>
  320. <el-dialog :title="assignList.title" :visible.sync="assignList.open" width="1000px" append-to-body>
  321. <customer-assign-list ref="assignList" @close="closeAssignList"></customer-assign-list>
  322. </el-dialog>
  323. <el-dialog :title="assign.title" :visible.sync="assign.open" width="800px" append-to-body>
  324. <assign-user ref="assignUser" @close="closeAssign" />
  325. </el-dialog>
  326. <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
  327. <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
  328. <i class="el-icon-upload"></i>
  329. <div class="el-upload__text">
  330. 将文件拖到此处,或
  331. <em>点击上传</em>
  332. </div>
  333. <div class="el-upload__tip" slot="tip">
  334. <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
  335. </div>
  336. <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
  337. </el-upload>
  338. <div slot="footer" class="dialog-footer">
  339. <el-button type="primary" @click="submitFileForm">确 定</el-button>
  340. <el-button @click="upload.open = false">取 消</el-button>
  341. </div>
  342. </el-dialog>
  343. <el-dialog title="导入结果" :close-on-press-escape="false" :close-on-click-modal="false" :visible.sync="importMsgOpen" width="500px" append-to-body>
  344. <div class="import-msg" v-html="importMsg">
  345. </div>
  346. </el-dialog>
  347. </div>
  348. </template>
  349. <script>
  350. import {
  351. assignToUser,
  352. recover,
  353. receive,
  354. getCustomerList,
  355. addCustomer,
  356. updateCustomer,
  357. getCustomerDetails,
  358. exportCustomer,
  359. importVisitTemplate,
  360. switchToTop
  361. } from "@/api/crm/customer";
  362. import { getToken } from "@/utils/auth";
  363. import customerDetails from '../components/customerDetails.vue';
  364. import {getCitys} from "@/api/store/city";
  365. import { treeselect } from "@/api/company/companyDept";
  366. import Treeselect from "@riophae/vue-treeselect";
  367. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  368. import addBatchSms from '../components/addBatchSms.vue';
  369. import editSource from '../components/editSource.vue';
  370. import customerSource from '../components/customerSource.vue';
  371. import customerAssignList from '../components/customerAssignList.vue';
  372. import assignUser from '../components/assignUser.vue';
  373. import {customerLevelOptions} from "@/api/crm/customerLevel";
  374. export default {
  375. name: "Customer",
  376. components: {assignUser,customerAssignList,addBatchSms,editSource, customerDetails,Treeselect,customerSource },
  377. data() {
  378. return {
  379. upload: {
  380. // 是否显示弹出层(用户导入)
  381. open: false,
  382. // 弹出层标题(用户导入)
  383. title: "",
  384. // 是否禁用上传
  385. isUploading: false,
  386. // 设置上传的请求头部
  387. headers: { Authorization: "Bearer " + getToken() },
  388. // 上传的地址
  389. url: process.env.VUE_APP_BASE_API + "/crm/customer/importVisitData",
  390. },
  391. importMsgOpen:false,
  392. importMsg:"",
  393. tagIds:[],
  394. tagsOptions:[],
  395. assignList:{
  396. title:"分配历史记录",
  397. open:false,
  398. },
  399. orderTypeOptions: [],
  400. visitTypeOptions:[],
  401. visitStatusOptions:[],
  402. customerSource:{
  403. open:false,
  404. title:"客户来源"
  405. },
  406. source:{
  407. open:false,
  408. title:"修改客户来源"
  409. },
  410. dateRange:[],
  411. addSms:{
  412. open:false,
  413. title:"批量发短信"
  414. },
  415. assign:{
  416. title:"分配客户",
  417. open:false,
  418. },
  419. defaultProps: {
  420. children: "children",
  421. label: "label",
  422. },
  423. // 部门树选项
  424. deptOptions: undefined,
  425. // 部门名称
  426. deptName: undefined,
  427. cityIds:[],
  428. citys:[],
  429. tags:[],
  430. visitStatusArr:[],
  431. ctsTypeArr:[],
  432. sourceArr:[],
  433. inputVisible: false,
  434. inputValue: '',
  435. receiveOptions:[],
  436. statusOptions:[],
  437. typeOptions:[],
  438. sourceOptions:[],
  439. sexOptions:[],
  440. show:{
  441. title:"客户详情",
  442. open:false,
  443. },
  444. // 遮罩层
  445. loading: true,
  446. // 选中数组
  447. ids: [],
  448. // 非单个禁用
  449. single: true,
  450. // 非多个禁用
  451. multiple: true,
  452. // 显示搜索条件
  453. showSearch: true,
  454. // 总条数
  455. total: 0,
  456. // 客户表格数据
  457. customerList: [],
  458. // 弹出层标题
  459. title: "",
  460. // 是否显示弹出层
  461. open: false,
  462. // 查询参数
  463. queryParams: {
  464. pageNum: 1,
  465. pageSize: 10,
  466. customerCode: null,
  467. customerName: null,
  468. mobile: null,
  469. sex: null,
  470. weixin: null,
  471. userId: null,
  472. createUserId: null,
  473. receiveUserId: null,
  474. customerUserId: null,
  475. address: null,
  476. location: null,
  477. detailAddress: null,
  478. lng: null,
  479. lat: null,
  480. status: null,
  481. isReceive: null,
  482. deptId: null,
  483. isDel: null,
  484. customerType: null,
  485. receiveTime: null,
  486. poolTime: null,
  487. companyId: null,
  488. isLine: null,
  489. source: null,
  490. tags: null,
  491. tagList:[],
  492. visitStatus:null,
  493. customerLevel: null,
  494. },
  495. // 表单参数
  496. form: {
  497. province:null,
  498. city:null,
  499. district:null,
  500. },
  501. // 表单校验
  502. rules: {
  503. customerName: [
  504. { required: true, message: "客户名称不能为空", trigger: "blur" }
  505. ],
  506. mobile: [
  507. { required: true, message: "手机号不能为空", trigger: "blur" }
  508. ],
  509. sex: [
  510. { required: true, message: "性别不能为空", trigger: "blur" }
  511. ],
  512. source: [
  513. { required: true, message: "客户来源不能为空", trigger: "blur" }
  514. ],
  515. },
  516. customerLevelOptions: []
  517. };
  518. },
  519. watch: {
  520. // 根据名称筛选部门树
  521. deptName(val) {
  522. this.$refs.tree.filter(val);
  523. },
  524. },
  525. created() {
  526. this.getDicts("store_order_type").then((response) => {
  527. this.orderTypeOptions = response.data;
  528. });
  529. this.getDicts("crm_customer_visit_type").then((response) => {
  530. this.visitTypeOptions = response.data;
  531. });
  532. this.getDicts("crm_customer_user_status").then((response) => {
  533. this.visitStatusOptions = response.data;
  534. });
  535. this.getDicts("crm_customer_source").then((response) => {
  536. this.sourceOptions = response.data;
  537. });
  538. this.getDicts("common_sex").then((response) => {
  539. this.sexOptions = response.data;
  540. });
  541. this.getDicts("crm_customer_source").then((response) => {
  542. this.sourceOptions = response.data;
  543. });
  544. this.getDicts("common_sex").then((response) => {
  545. this.sexOptions = response.data;
  546. });
  547. this.getDicts("crm_customer_status").then((response) => {
  548. this.statusOptions = response.data;
  549. });
  550. this.getDicts("crm_customer_type").then((response) => {
  551. this.typeOptions = response.data;
  552. });
  553. this.getDicts("crm_customer_is_receive").then((response) => {
  554. this.receiveOptions = response.data;
  555. });
  556. this.getDicts("crm_customer_tag").then((response) => {
  557. this.tagsOptions = response.data;
  558. });
  559. this.getTreeselect();
  560. this.getCitys();
  561. this.getList();
  562. this.getCustomerLevelOptions()
  563. },
  564. methods: {
  565. getCustomerLevelOptions(){
  566. customerLevelOptions().then((response) => {
  567. this.customerLevelOptions = response.data;
  568. });
  569. },
  570. handleShow(row){
  571. this.show.open=true;
  572. var that=this;
  573. setTimeout(() => {
  574. that.$refs.customerDetails.getDetails(row.customerId);
  575. }, 200);
  576. },
  577. handleAssignList(){
  578. this.assignList.open=true;
  579. var that=this;
  580. setTimeout(() => {
  581. that.$refs.assignList.getData();
  582. }, 200);
  583. },
  584. closeAssignList(){
  585. this.assignList.open=false;
  586. this.getList();
  587. },
  588. handleAddScource(){
  589. this.customerSource.open=true;
  590. var that=this;
  591. setTimeout(() => {
  592. that.$refs.customerSource.getData();
  593. }, 200);
  594. },
  595. closeCustomerSource(){
  596. this.customerSource.open=false;
  597. this.getList();
  598. },
  599. changeVal() {
  600. console.log(1)
  601. this.$forceUpdate();//解决点击计数器失效问题
  602. },
  603. handleEditScource(){
  604. this.source.open=true;
  605. var that=this;
  606. setTimeout(() => {
  607. that.$refs.editSource.handleEdit(that.ids);
  608. }, 200);
  609. },
  610. closeSource(){
  611. this.source.open=false;
  612. this.getList();
  613. },
  614. closeSms(){
  615. this.addSms.open=false;
  616. },
  617. handleSendBatchSms(){
  618. const customerIds = this.ids;
  619. this.addSms.open=true;
  620. var that=this;
  621. setTimeout(() => {
  622. console.log(customerIds)
  623. that.$refs.sms.reset(customerIds);
  624. }, 500);
  625. },
  626. handleClick(tab, event) {
  627. this.queryParams.isReceive=tab.name;
  628. this.getList();
  629. },
  630. handleAssign(){
  631. var that=this;
  632. var ids=this.ids;
  633. that.assign.open=true;
  634. setTimeout(() => {
  635. if(that.queryParams.isReceive=="0"){
  636. that.$refs.assignUser.init(ids,2);
  637. }
  638. else if(that.queryParams.isReceive=="1"){
  639. that.$refs.assignUser.init(ids,3);
  640. }
  641. }, 200);
  642. },
  643. closeAssign(){
  644. this.assign.open=false;
  645. this.getList();
  646. },
  647. handleRecover(row) {
  648. this.$confirm('是否确认回收客户"' + row.customerName + '"?', "警告", {
  649. confirmButtonText: "确定",
  650. cancelButtonText: "取消",
  651. type: "warning"
  652. }).then(function() {
  653. var data={customerUserId:row.customerUserId}
  654. return recover(data);
  655. }).then(() => {
  656. this.getList();
  657. this.msgSuccess("操作成功");
  658. }).catch(function() {});
  659. },
  660. handleReceive(row) {
  661. this.$confirm('是否确认认领客户"' + row.customerName + '"?', "警告", {
  662. confirmButtonText: "确定",
  663. cancelButtonText: "取消",
  664. type: "warning"
  665. }).then(function() {
  666. var data={customerId:row.customerId}
  667. return receive(data);
  668. }).then(() => {
  669. this.getList();
  670. this.msgSuccess("操作成功");
  671. }).catch(function() {});
  672. },
  673. handleSwitchToTop(row) {
  674. switchToTop(row.customerId).then(response => {
  675. const {code} = response
  676. if (code === 200) {
  677. this.msgSuccess(row.isTop === 0 ? "已置顶" : "已取消置顶");
  678. this.getList();
  679. }
  680. })
  681. },
  682. getTreeselect() {
  683. treeselect().then((response) => {
  684. this.deptOptions = response.data;
  685. });
  686. },
  687. // 筛选节点
  688. filterNode(value, data) {
  689. if (!value) return true;
  690. return data.label.indexOf(value) !== -1;
  691. },
  692. // 节点单击事件
  693. handleNodeClick(data) {
  694. this.queryParams.deptId = data.id;
  695. this.getList();
  696. },
  697. handleCityChange(value) {
  698. console.log(value);
  699. var nodes=this.$refs.citySelect.getCheckedNodes();
  700. this.form.address=nodes[0].pathLabels[0]+"-"+nodes[0].pathLabels[1]+"-"+nodes[0].pathLabels[2];
  701. this.form.cityIds=value.toString();
  702. console.log(this.form.address);
  703. },
  704. getCitys(){
  705. getCitys().then(res => {
  706. this.loading = false;
  707. this.citys=res.data;
  708. })
  709. },
  710. /** 查询客户列表 */
  711. getList() {
  712. this.loading = true;
  713. if(this.visitStatusArr.length>0){
  714. this.queryParams.visitStatus=this.visitStatusArr.toString();
  715. }
  716. else{
  717. this.queryParams.visitStatus=null
  718. }
  719. if(this.ctsTypeArr.length>0){
  720. this.queryParams.customerType=this.ctsTypeArr.toString();
  721. }
  722. else{
  723. this.queryParams.customerType=null
  724. }
  725. if(this.sourceArr.length>0){
  726. this.queryParams.source=this.sourceArr.toString();
  727. }
  728. else{
  729. this.queryParams.source=null
  730. }
  731. if(this.tagIds.length>0){
  732. this.queryParams.tags=this.tagIds.toString();
  733. }
  734. else{
  735. this.queryParams.tags=null
  736. }
  737. getCustomerList(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
  738. this.customerList = response.rows;
  739. this.total = response.total;
  740. this.loading = false;
  741. });
  742. },
  743. // 取消按钮
  744. cancel() {
  745. this.open = false;
  746. this.reset();
  747. },
  748. // 表单重置
  749. reset() {
  750. this.form = {
  751. customerId: null,
  752. customerCode: null,
  753. customerName: null,
  754. mobile: null,
  755. sex: null,
  756. weixin: null,
  757. remark: null,
  758. userId: null,
  759. createUserId: null,
  760. receiveUserId: null,
  761. customerUserId: null,
  762. address: null,
  763. location: null,
  764. detailAddress: null,
  765. lng: null,
  766. lat: null,
  767. createTime: null,
  768. updateTime: null,
  769. status: 0,
  770. isReceive: null,
  771. deptId: null,
  772. isDel: null,
  773. customerType: null,
  774. receiveTime: null,
  775. poolTime: null,
  776. companyId: null,
  777. isLine: null,
  778. source: null,
  779. tags: null
  780. };
  781. this.tags=[];
  782. this.cityIds=[];
  783. this.resetForm("form");
  784. },
  785. /** 搜索按钮操作 */
  786. handleQuery() {
  787. this.queryParams.pageNum = 1;
  788. this.getList();
  789. },
  790. /** 重置按钮操作 */
  791. resetQuery() {
  792. this.resetForm("queryForm");
  793. this.handleQuery();
  794. },
  795. // 多选框选中数据
  796. handleSelectionChange(selection) {
  797. this.ids = selection.map(item => item.customerId)
  798. this.single = selection.length!==1
  799. this.multiple = !selection.length
  800. },
  801. /** 新增按钮操作 */
  802. handleAdd() {
  803. this.reset();
  804. this.open = true;
  805. this.title = "添加客户";
  806. },
  807. /** 修改按钮操作 */
  808. handleUpdate(row) {
  809. this.reset();
  810. var that=this;
  811. const customerId = row.customerId || this.ids.toString()
  812. var data={customerId:customerId}
  813. getCustomerDetails(data).then(response => {
  814. this.form = response.data;
  815. if(this.form.status!=null){
  816. this.form.status = this.form.status.toString();
  817. }
  818. if(this.form.customerType!=null){
  819. this.form.customerType = this.form.customerType.toString();
  820. }
  821. if(this.form.sex!=null){
  822. this.form.sex = this.form.sex.toString();
  823. }
  824. if(this.form.source!=null){
  825. this.form.source = this.form.source.toString();
  826. }
  827. if(this.form.tags!=null){
  828. this.tags = this.form.tags.split(",")
  829. }
  830. console.log(this.form.cityIds)
  831. if(this.form.cityIds!=null){
  832. var ids=this.form.cityIds.split(",");
  833. this.cityIds=[];
  834. ids.forEach(element => {
  835. var id=parseInt(element);
  836. that.cityIds.push(id)
  837. });
  838. }
  839. this.open = true;
  840. this.title = "修改客户";
  841. });
  842. },
  843. /** 提交按钮 */
  844. submitForm() {
  845. this.$refs["form"].validate(valid => {
  846. if (valid) {
  847. if (this.form.customerId != null) {
  848. updateCustomer(this.form).then(response => {
  849. if (response.code === 200) {
  850. this.msgSuccess("修改成功");
  851. this.open = false;
  852. this.getList();
  853. }
  854. });
  855. } else {
  856. addCustomer(this.form).then(response => {
  857. if (response.code === 200) {
  858. this.msgSuccess("新增成功");
  859. this.open = false;
  860. this.getList();
  861. }
  862. });
  863. }
  864. }
  865. });
  866. },
  867. /** 删除按钮操作 */
  868. handleDelete(row) {
  869. const customerIds = row.customerId || this.ids;
  870. this.$confirm('是否确认删除客户编号为"' + customerIds + '"的数据项?', "警告", {
  871. confirmButtonText: "确定",
  872. cancelButtonText: "取消",
  873. type: "warning"
  874. }).then(function() {
  875. return delLineCustomer(customerIds);
  876. }).then(() => {
  877. this.getList();
  878. this.msgSuccess("删除成功");
  879. }).catch(function() {});
  880. },
  881. /** 导出按钮操作 */
  882. /** 导出按钮操作 */
  883. handleExport() {
  884. const queryParams = this.queryParams;
  885. this.$confirm('是否确认导出所有客户数据项?', "警告", {
  886. confirmButtonText: "确定",
  887. cancelButtonText: "取消",
  888. type: "warning"
  889. }).then(function() {
  890. return exportCustomer(queryParams);
  891. }).then(response => {
  892. this.download(response.msg);
  893. }).catch(function() {});
  894. },
  895. /** 导入按钮操作 */
  896. handleImport() {
  897. this.upload.title = "客户跟进情况导入";
  898. this.upload.open = true;
  899. },
  900. /** 下载模板操作 */
  901. importTemplate() {
  902. importVisitTemplate().then((response) => {
  903. this.download(response.msg);
  904. });
  905. },
  906. // 文件上传中处理
  907. handleFileUploadProgress(event, file, fileList) {
  908. this.upload.isUploading = true;
  909. },
  910. // 文件上传成功处理
  911. handleFileSuccess(response, file, fileList) {
  912. this.upload.open = false;
  913. this.upload.isUploading = false;
  914. this.$refs.upload.clearFiles();
  915. this.importMsgOpen=true;
  916. this.importMsg=response.msg
  917. this.getList();
  918. },
  919. // 提交上传文件
  920. submitFileForm() {
  921. this.$refs.upload.submit();
  922. },
  923. }
  924. };
  925. </script>
  926. <style>
  927. .el-tag + .el-tag {
  928. margin-left: 10px;
  929. }
  930. .button-new-tag {
  931. margin-left: 10px;
  932. height: 32px;
  933. line-height: 30px;
  934. padding-top: 0;
  935. padding-bottom: 0;
  936. }
  937. .input-new-tag {
  938. width: 90px;
  939. margin-left: 10px;
  940. vertical-align: bottom;
  941. }
  942. .el-dialog__wrapper{
  943. z-index: 100000;
  944. }
  945. </style>