contactsList.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <template>
  2. <div class="container-contactsList">
  3. <div class="top-wrap">
  4. <el-input style="width: 200px; margin-right: 20px" v-model="contactWay" placeholder="手机号/邮箱/姓名/公司名" prefix-icon="el-icon-search" clearable></el-input>
  5. <el-select v-model="decisionValue" placeholder="是否KP" @change="handelGetData" clearable>
  6. <el-option v-for="item in decisionOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  7. </el-select>
  8. <el-select v-model="registerValue" placeholder="是否注册" @change="handelGetData" clearable>
  9. <el-option v-for="item in registerOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  10. </el-select>
  11. <el-select v-model="isFollowValue" placeholder="是否关注公众号" @change="handelGetData" clearable>
  12. <el-option v-for="item in decisionOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  13. </el-select>
  14. <el-cascader
  15. v-model="sales"
  16. placeholder="请选择销售"
  17. style="width: 200px; margin: 0 20px 20px 0"
  18. :options="salesArr"
  19. :props="defaultSalesProps"
  20. :show-all-levels="false"
  21. collapse-tags
  22. clearable
  23. filterable
  24. @change="handelGetData"
  25. >
  26. </el-cascader>
  27. <el-cascader
  28. style="width: 200px; margin-right: 20px"
  29. v-model="clientStatus"
  30. :options="clientOptions"
  31. placeholder="请选择客户状态"
  32. clearable
  33. :props="{ value: 'TryStage', label: 'Name', children: 'List', checkStrictly: true }"
  34. @change="handelGetData"
  35. ></el-cascader>
  36. <el-autocomplete
  37. style="width: 200px; margin-bottom: 20px"
  38. prefix-icon="el-icon-search"
  39. clearable
  40. class="inline-input"
  41. v-model="userLabel"
  42. :fetch-suggestions="querySearchHandler"
  43. placeholder="用户标签搜索"
  44. @clear="handelGetData"
  45. :trigger-on-focus="false"
  46. @select="handelGetData"
  47. >
  48. <template slot-scope="scope">
  49. <div v-if="scope.item.IndustryName">
  50. {{ scope.item.IndustryName }}
  51. </div>
  52. <div v-else style="text-align: center">暂无数据</div>
  53. </template>
  54. </el-autocomplete>
  55. </div>
  56. <el-card>
  57. <el-table :data="tableData" style="width: 100%" border @sort-change="sortChangeHandle">
  58. <el-table-column align="center" prop="RealName" width="90" label="姓名">
  59. <template slot-scope="{ row }">
  60. <span>{{ row.RealName }}</span>
  61. <img width="16" v-if="row.HaveMoveButton" style="vertical-align: middle; cursor: pointer" src="../../../assets/img/contact_transfer.jpg" alt="" @click="clickContactTransfer(row)" />
  62. </template>
  63. </el-table-column>
  64. <el-table-column align="center" prop="Mobile" width="110" label="手机号/邮箱">
  65. <template slot-scope="{ row }"> {{ row.Mobile || row.Email }} </template>
  66. </el-table-column>
  67. <el-table-column align="center" prop="CompanyName" label="公司名称">
  68. <template slot-scope="{ row }">
  69. <el-tooltip effect="dark" placement="top-start" content="过去4周,kp均未覆盖服务" v-if="row.IsUserMaker == -1">
  70. <span class="deletesty" @click="goDetail(row)">{{ row.CompanyName }}</span>
  71. </el-tooltip>
  72. <span v-else class="editsty" @click="goDetail(row)">{{ row.CompanyName }}</span>
  73. <!-- <span class="editsty" @click="goDetail(scope.row)">{{ scope.row.CompanyName }}</span> -->
  74. </template>
  75. </el-table-column>
  76. <el-table-column align="center" prop="Status" width="110" label="状态"> </el-table-column>
  77. <el-table-column align="center" prop="SellerName" width="110" label="所属销售"> </el-table-column>
  78. <el-table-column align="center" prop="IsMaker" width="80" label="是否KP">
  79. <template slot-scope="{ row }">
  80. {{ row.IsMaker == 1 ? "是" : "否" }}
  81. </template>
  82. </el-table-column>
  83. <el-table-column align="center" prop="RegisterTime" width="110" label="注册时间"> </el-table-column>
  84. <el-table-column align="center" width="120" label="是否关注公众号">
  85. <template slot-scope="{ row }">
  86. {{ row.IsSubscribeCygx == 1 ? "是" : "否" }}
  87. </template>
  88. </el-table-column>
  89. <el-table-column align="center" prop="InteractionNum" width="110" label="互动量" :render-header="renderHeader" sortable="custom">
  90. <template slot-scope="{ row }">
  91. <span class="editsty" @click="lookInteraction(row, '个人')">{{ row.InteractionNum }}</span> /
  92. <el-popover trigger="hover" placement="right" @show="isShowOrganization(row)">
  93. <table class="table-wrap-table-popover">
  94. <tr v-for="(item, index) in organizationTableL" :key="index">
  95. <td class="table-item">{{ item.DateTime }}</td>
  96. <td class="table-item">{{ item.InteractionNum }}</td>
  97. </tr>
  98. </table>
  99. <span slot="reference" class="editsty" @click="lookInteraction(row, '机构')">{{ row.CompanyInteractionNum }}</span>
  100. </el-popover>
  101. </template>
  102. </el-table-column>
  103. <el-table-column prop="" width="350">
  104. <div slot="header" slot-scope="{}" style="text-align: center">标签</div>
  105. <template slot-scope="{ row }">
  106. <div class="popover-item">
  107. <el-tag size="mini" style="margin: 5px 8px; cursor: pointer" v-for="item in lookLabelListNumber(row)" :key="item" :type="userLabel == item && 'danger'" @click="labelChildren(item, row)">
  108. {{ item }}
  109. </el-tag>
  110. <span @click="showLabelDlg(row)" style="font-weight: 700; padding: 5px 10px" class="editsty" v-if="row.Labels && row.Labels.split(',').length > 10">...</span>
  111. </div>
  112. </template>
  113. </el-table-column>
  114. <el-table-column align="center" prop="" label="备注" width="90">
  115. <template slot-scope="{ row }">
  116. <div class="remark-list">
  117. <div class="button">
  118. <span class="editsty" @click="lookOver(row, '添加')">添加</span>
  119. <span v-if="row.Content" style="font-weight: 700; padding: 5px 10px" class="editsty" @click="lookOver(row, '历史')">...</span>
  120. </div>
  121. </div>
  122. </template>
  123. </el-table-column>
  124. <el-table-column align="center" prop="" label="操作" width="160">
  125. <template slot-scope="{ row }">
  126. <span :class="row.IsRemind ? 'deletesty' : 'editsty'" @click="remindHandler(row)">{{ row.IsRemind ? "取消提醒" : "互动提醒" }}</span>
  127. &nbsp;&nbsp;&nbsp;&nbsp;
  128. <span class="editsty" @click="feedbackHandler(row)">交流反馈</span>
  129. </template>
  130. </el-table-column>
  131. </el-table>
  132. <!-- 分页 -->
  133. <el-col :span="24" class="toolbar">
  134. <m-page :total="total" :page_no="page_no" :pageSize="10" @handleCurrentChange="handleCurrentChange" />
  135. </el-col>
  136. </el-card>
  137. <el-dialog v-dialogDrag :visible.sync="remarkDlgShow" :close-on-click-modal="false" :modal-append-to-body="false" @close="cancelHandle" center :width="addRemarFrom.IsShowSee ? '800px' : '500px'">
  138. <div slot="title">
  139. <i class="el-icon-close" style="fontsize: 24px; cursor: pointer; position: absolute; right: 20px; top: 50%; transform: translateY(-50%)" @click="cancelHandle"></i>
  140. <span style="fontsize: 16px">{{ addRemarFrom.IsShowSee ? "历史备注" : "添加备注" }}</span>
  141. </div>
  142. <div v-if="addRemarFrom.IsShowSee">
  143. <el-table :data="lableRemarkList" style="width: 100%" border height="350">
  144. <el-table-column align="center" prop="Content" label="备注信息"> </el-table-column>
  145. <el-table-column align="center" prop="CreateTime" label="备注时间"> </el-table-column>
  146. </el-table>
  147. </div>
  148. <div v-else>
  149. <el-input type="textarea" :rows="4" placeholder="请输入备注信息" v-model.trim="addRemarText"> </el-input>
  150. </div>
  151. <div style="display: flex; justify-content: center; margin: 40px 0">
  152. <template v-if="!addRemarFrom.IsShowSee">
  153. <el-button type="primary" @click="saveHandle">确定</el-button>
  154. <el-button type="primary" plain @click="cancelHandle">取消</el-button>
  155. </template>
  156. </div>
  157. </el-dialog>
  158. <InteractionDlg :interactionDlg.sync="interactionDlg" :interactionFrom="interactionFrom" />
  159. <label-dlg :isShowLabelDlg.sync="isShowLabelDlg" :dlgLabelList.sync="dlgLabelList" @labelChildren="labelChildren" :userLabel="userLabel" />
  160. <remind-dlg :isShowRemindDlg.sync="isShowRemindDlg" :remindList.sync="remindList" />
  161. <FeedbackDlg :showFeedbackDlg.sync="showFeedbackDlg" :remindList.sync="remindList" />
  162. <ContactTransfer :contactTransferDlgVisible.sync="contactTransferDlgVisible" :TransferMobile.sync="TransferMobile" />
  163. </div>
  164. </template>
  165. <script>
  166. import { customInterence, equityContacts } from "@/api/api.js";
  167. import mPage from "@/components/mPage.vue";
  168. import mDialog from "@/components/mDialog.vue";
  169. import InteractionDlg from "./compontents/interactionDlg.vue";
  170. import LabelDlg from "./compontents/labelDlg.vue";
  171. import RemindDlg from "./compontents/remindDlg.vue";
  172. import FeedbackDlg from "./compontents/feedbackDlg.vue";
  173. import ContactTransfer from "../customList/components/ContactTransferDlg.vue";
  174. export default {
  175. name: "",
  176. components: { mPage, mDialog, InteractionDlg, LabelDlg, RemindDlg, FeedbackDlg, ContactTransfer },
  177. props: {},
  178. data() {
  179. return {
  180. contactWay: "", //手机号/邮箱/姓名/公司名
  181. decisionValue: "",
  182. isFollowValue: "", //是否关注公众号
  183. decisionOptions: [
  184. {
  185. label: "是",
  186. value: 1,
  187. },
  188. {
  189. label: "否",
  190. value: 0,
  191. },
  192. ],
  193. registerValue: 1,
  194. registerOptions: [
  195. {
  196. label: "已注册",
  197. value: 1,
  198. },
  199. {
  200. label: "未注册",
  201. value: 0,
  202. },
  203. ],
  204. sales: [],
  205. salesArr: [], //销售
  206. defaultSalesProps: {
  207. multiple: true,
  208. label: "RealName",
  209. children: "ChildrenList",
  210. value: "AdminId",
  211. }, //销售级联配置
  212. clientStatus: "",
  213. clientOptions: ["试用", "冻结", "正式"],
  214. tableData: [],
  215. total: 0, //条数
  216. pageSize: 10, //每页显示几条
  217. page_no: sessionStorage.getItem("contactsListBack") ? JSON.parse(sessionStorage.getItem("contactsListBack")).page_no : 1,
  218. remarkDlgShow: false, // 查看
  219. addRemarFrom: {}, //、添加备注
  220. addRemarText: "",
  221. lableRemarkList: [],
  222. lookLabelList: "啤酒,冷冻烘焙,立高食品,鸿合科技,智能交互平板,速冻火锅料及预制菜,安井食品,千味央厨,速冻米面,视源股份,xx",
  223. userLabel: "",
  224. interactionDlg: false, //互助的弹框
  225. interactionFrom: {}, //互助的数据
  226. orderTable: "",
  227. organizationTableL: [], //互助量机构的
  228. isShowLabelDlg: false, //
  229. dlgLabelList: {}, //
  230. isShowRemindDlg: false, // 消息提醒的弹框
  231. remindList: {}, // 消息提醒的数据
  232. showFeedbackDlg: false, // 交流反馈的弹框
  233. TransferMobile: 0,
  234. contactTransferDlgVisible: false, //联系人转移的弹框
  235. };
  236. },
  237. computed: {},
  238. watch: {
  239. contactWay: {
  240. handler(newval) {
  241. this.clientStatus = "";
  242. this.decisionValue = "";
  243. this.registerValue = "";
  244. this.selesArr = [];
  245. this.page_no = 1;
  246. this.getCygxContactsList();
  247. },
  248. },
  249. },
  250. created() {},
  251. mounted() {
  252. if (sessionStorage.getItem("contactsListBack")) {
  253. const { keyword, decisionValue, registerValue, sales, clientStatus, userLabel, isFollowValue } = JSON.parse(sessionStorage.getItem("contactsListBack"));
  254. this.contactWay = keyword;
  255. this.decisionValue = decisionValue;
  256. this.registerValue = registerValue;
  257. this.sales = sales;
  258. this.clientStatus = clientStatus;
  259. this.userLabel = userLabel;
  260. this.isFollowValue = isFollowValue;
  261. }
  262. this.getUserStatusTable();
  263. this.getCygxContactsList();
  264. this.getSale();
  265. },
  266. methods: {
  267. async getUserStatusTable() {
  268. const res = await equityContacts.getUserStatusTable();
  269. if (res.Ret == 200) {
  270. this.clientOptions = res.Data.List || [];
  271. }
  272. },
  273. /* 获取销售 */
  274. getSale() {
  275. customInterence.getSalesRaiData().then((res) => {
  276. if (res.Ret === 200) {
  277. this.salesArr = res.Data.List;
  278. }
  279. });
  280. },
  281. /* 获取列表 */
  282. async getCygxContactsList() {
  283. let salesArr = [];
  284. if (this.sales.length) {
  285. salesArr = this.sales.map((item) => {
  286. return item[item.length - 1];
  287. });
  288. }
  289. const res = await equityContacts.getCygxContactsList({
  290. PageSize: this.pageSize,
  291. CurrentIndex: this.page_no,
  292. Status: this.clientStatus[0] ? this.clientStatus[0] : "",
  293. TryStage: this.clientStatus[1] ? this.clientStatus[1] : "",
  294. IsMaker: this.decisionValue === 1 ? this.decisionValue : this.decisionValue === 0 ? this.decisionValue : 2,
  295. IsRegister: this.registerValue === 1 ? this.registerValue : this.registerValue === 0 ? this.registerValue : 2,
  296. AdminId: salesArr.join(","),
  297. KeyWord: this.contactWay,
  298. Label: this.userLabel,
  299. SortType: this.orderTable,
  300. IsSubscribeCygx: this.isFollowValue,
  301. });
  302. if (res.Ret === 200) {
  303. this.tableData = res.Data.List || [];
  304. this.total = res.Data.Paging.Totals;
  305. }
  306. },
  307. //table表头自定义
  308. renderHeader(h, { column, $index }) {
  309. return h("div", { attrs: { style: "display:inline-block;" } }, [
  310. h("span", column.label),
  311. h("el-tooltip", { props: { placement: "top" } }, [
  312. h("p", { slot: "content", attrs: { style: "display:block;width:280px;text-align: center" } }, "个人互动量 / 机构总互动量"),
  313. h("p", { slot: "content", attrs: { style: "display:block;width:280px;" } }, "点击右侧排序按钮可按照个人互动量升序/降序排列"),
  314. h("el-button", { props: { icon: "el-icon-info" }, attrs: { style: "border:none;background:none;width:20px;padding:0 0 0 5px;" } }, ""),
  315. ]),
  316. ]);
  317. },
  318. /* 页码改变事件 */
  319. handleCurrentChange(page) {
  320. this.page_no = page;
  321. this.getCygxContactsList();
  322. },
  323. /* 详情页 */
  324. goDetail(item) {
  325. this.$router.push({
  326. path: "/customDetail",
  327. query: {
  328. id: item.CompanyId,
  329. },
  330. });
  331. },
  332. /* 点击了添加备注 和查看 */
  333. async lookOver(item, type) {
  334. this.addRemarFrom = _.cloneDeep(item);
  335. this.addRemarFrom.IsShowSee = type === "历史";
  336. this.remarkDlgShow = true;
  337. if (this.addRemarFrom.IsShowSee) {
  338. const res = await equityContacts.getCygxRemarkList({ UserId: this.addRemarFrom.UserId });
  339. if (res.Ret === 200) {
  340. this.$nextTick(() => {
  341. this.lableRemarkList = res.Data.List || [];
  342. });
  343. }
  344. }
  345. },
  346. /* 弹框的关闭 */
  347. cancelHandle() {
  348. this.remarkDlgShow = false;
  349. this.addRemarText = "";
  350. this.addRemarFrom = {};
  351. },
  352. /* 弹框的确认 */
  353. async saveHandle() {
  354. if (this.addRemarFrom.IsShowSee) {
  355. this.addRemarFrom.IsShowSee = false;
  356. } else {
  357. if (this.addRemarText == "") return this.$message.error("请输入备注信息");
  358. const res = await equityContacts.getCygxAddRemarks({
  359. Content: this.addRemarText,
  360. UserId: this.addRemarFrom.UserId,
  361. });
  362. if (res.Ret === 200) {
  363. this.$message.success("添加成功");
  364. this.getCygxContactsList();
  365. this.remarkDlgShow = false;
  366. this.addRemarText = "";
  367. this.addRemarFrom = {};
  368. }
  369. }
  370. },
  371. /* 筛选的change 事件 */
  372. handelGetData() {
  373. this.page_no = 1;
  374. this.getCygxContactsList();
  375. },
  376. /* 互助量点击 */
  377. lookInteraction(item, type) {
  378. const { href } = this.$router.resolve({
  379. path: type === "个人" ? "/mutualList" : "/organizationList",
  380. query: {
  381. id: item.UserId,
  382. CompanyId: item.CompanyId,
  383. },
  384. });
  385. window.open(href, "_blank");
  386. },
  387. /* 标签下的单独的某一个 */
  388. labelChildren(key, row) {
  389. this.interactionDlg = true;
  390. this.interactionFrom = {
  391. id: row.UserId,
  392. key,
  393. };
  394. },
  395. //鼠标经过了 机构互助量
  396. async isShowOrganization(row) {
  397. const res = await equityContacts.getInteractionNum({
  398. UserId: row.UserId,
  399. });
  400. if (res.Ret === 200) {
  401. this.organizationTableL = res.Data.List || [];
  402. }
  403. },
  404. // 查看标签
  405. async lookLabels(item) {
  406. this.lookLabelList = [];
  407. const res = await equityContacts.getCygxLabelDetail({
  408. UserId: item.UserId,
  409. });
  410. if (res.Ret === 200) {
  411. this.lookLabelList = res.Data.Label && res.Data.Label.split(",");
  412. }
  413. },
  414. async querySearchHandler(query, cb) {
  415. cb([]);
  416. if (!query) return;
  417. const res = await equityContacts.industrialManagementSearch({ KeyWord: query });
  418. if (res.Ret === 200) {
  419. if (res.Data && res.Data.List.length > 0) {
  420. let arr = res.Data.List.map((item) => {
  421. return { value: item.IndustryName, ...item };
  422. });
  423. cb(arr);
  424. } else {
  425. cb([{}]);
  426. }
  427. }
  428. },
  429. //点击操作的互助提醒
  430. async remindHandler(item) {
  431. this.remindList = item;
  432. this.isShowRemindDlg = true;
  433. },
  434. sortChangeHandle(item) {
  435. console.log(item.order);
  436. this.orderTable = item.order === "ascending" ? "asc" : item.order === "descending" ? "desc" : "";
  437. this.getCygxContactsList();
  438. },
  439. // 处理标签不能超过10个
  440. lookLabelListNumber(row) {
  441. let arr = row.Labels ? row.Labels.split(",").splice(0, 10) : [];
  442. return arr;
  443. },
  444. // 展示弹框
  445. showLabelDlg(row) {
  446. this.dlgLabelList = row;
  447. this.isShowLabelDlg = true;
  448. },
  449. // 点击了交流反馈
  450. feedbackHandler(item) {
  451. this.remindList = item;
  452. this.showFeedbackDlg = true;
  453. },
  454. // 点击了共享联系人
  455. clickContactTransfer(item) {
  456. this.contactTransferDlgVisible = true;
  457. this.TransferMobile = item.Mobile;
  458. },
  459. },
  460. /* 页面跳转前记录参数 */
  461. beforeRouteLeave(to, from, next) {
  462. let backData = {
  463. page_no: this.page_no,
  464. keyword: this.contactWay,
  465. decisionValue: this.decisionValue,
  466. registerValue: this.registerValue,
  467. sales: this.sales,
  468. clientStatus: this.clientStatus,
  469. userLabel: this.userLabel,
  470. isFollowValue: this.isFollowValue,
  471. };
  472. sessionStorage.setItem("contactsListBack", JSON.stringify(backData));
  473. next();
  474. },
  475. /* 页面进入前是否清除参数 */
  476. beforeRouteEnter(to, from, next) {
  477. if (from.path !== "/mutualList" && from.path !== "/customDetail") {
  478. sessionStorage.removeItem("contactsListBack");
  479. }
  480. next();
  481. },
  482. };
  483. </script>
  484. <style scoped lang="scss">
  485. .container-contactsList {
  486. .el-select {
  487. width: 200px;
  488. margin-right: 20px;
  489. margin-bottom: 20px;
  490. }
  491. .top-wrap {
  492. margin-bottom: 28px;
  493. padding: 20px 30px 0;
  494. background: #fff;
  495. border: 1px solid #ececec;
  496. border-radius: 4px;
  497. box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
  498. }
  499. .table-item {
  500. display: inline-block;
  501. width: 90px;
  502. height: 22px;
  503. background: #e8f3ff;
  504. border-radius: 4px;
  505. color: #2d8cf0;
  506. text-align: center;
  507. line-height: 22px;
  508. margin-bottom: 5px;
  509. margin-left: 5px;
  510. &:last-child {
  511. margin-bottom: 0px;
  512. }
  513. }
  514. .remark-list {
  515. .button {
  516. display: flex;
  517. flex-direction: row-reverse;
  518. justify-content: space-between;
  519. align-content: center;
  520. flex-shrink: 0;
  521. }
  522. }
  523. }
  524. .table-wrap-table-popover {
  525. color: #666;
  526. width: 100%;
  527. border-top: 1px solid #dcdfe6;
  528. border-left: 1px solid #dcdfe6;
  529. .table-item {
  530. padding: 5px 10px;
  531. border-right: 1px solid #dcdfe6;
  532. border-bottom: 1px solid #dcdfe6;
  533. }
  534. }
  535. .popover-item {
  536. overflow: hidden;
  537. overflow-y: auto;
  538. }
  539. .popover-not-have {
  540. width: 100%;
  541. text-align: center;
  542. }
  543. </style>