|
|
@@ -0,0 +1,3976 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="en">
|
|
|
+
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
+ <meta name="viewport"
|
|
|
+ content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no, viewport-fit=cover" />
|
|
|
+ <title></title>
|
|
|
+ <!-- 引入样式文件 -->
|
|
|
+ <link rel="stylesheet"
|
|
|
+ href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012584633/vant.css" />
|
|
|
+ <!-- 必须先引入vue, 后使用vant-ui -->
|
|
|
+ <script
|
|
|
+ src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
|
|
|
+ <!-- 引入vant的组件库-->
|
|
|
+ <!-- 引入 Vant 的 JS 文件 -->
|
|
|
+ <script
|
|
|
+ src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758012748487/vant.min.js"></script>
|
|
|
+
|
|
|
+ <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
|
|
+ <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
|
|
|
+ <script src="js/select-date.js"></script>
|
|
|
+ <script
|
|
|
+ src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1758187289797/echarts.js"></script>
|
|
|
+ <script src="js/echarts-wordcloud.js"></script>
|
|
|
+ <!-- <script src="js/vconsole.min.js"></script>
|
|
|
+ <script>
|
|
|
+ var vConsole = new window.VConsole();
|
|
|
+ </script> -->
|
|
|
+</head>
|
|
|
+<style>
|
|
|
+ body {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .box {
|
|
|
+ width: 100vw;
|
|
|
+ /* height: 100vh; */
|
|
|
+ box-sizing: border-box;
|
|
|
+ background: #FAFAFA;
|
|
|
+ }
|
|
|
+
|
|
|
+ .page4 {
|
|
|
+ width: 100vw;
|
|
|
+ /* height: 100vh; */
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup_list {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: 44px 30px 10px;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup_item {
|
|
|
+ padding: 15px 0;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #222222;
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup_line {
|
|
|
+ height: 1px;
|
|
|
+ background: linear-gradient(90deg, #000000 0%, rgba(0, 0, 0, 0) 100%);
|
|
|
+ opacity: 0.1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mer_item {
|
|
|
+ padding: 15px 0;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #222222;
|
|
|
+ line-height: 24px;
|
|
|
+ border-bottom: 1px solid transparent;
|
|
|
+ /* 占位 */
|
|
|
+ border-image: linear-gradient(90deg, rgba(0, 0, 0, 0.1) 0%, transparent 100%) 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mer_item_active {
|
|
|
+ color: #1677FF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-nav-bar__content {
|
|
|
+ height: 44px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-nav-bar__title {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #222222;
|
|
|
+ }
|
|
|
+
|
|
|
+ .explain_list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: 10px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: 18px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .explain_list div {
|
|
|
+ padding-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .explain_list div:last-child {
|
|
|
+ padding-bottom: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .explain_icon {
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ margin-left: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .navbar_icon {
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-nav-bar__left {
|
|
|
+ padding: 0 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-nav-bar__right {
|
|
|
+ padding: 0 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-hairline--bottom::after {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .top_data {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 10px;
|
|
|
+ height: 54px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ box-sizing: border-box;
|
|
|
+ position: fixed;
|
|
|
+ top: 44px;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ z-index: 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ .top_data_bottom {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-end;
|
|
|
+ position: fixed;
|
|
|
+ top: 98px;
|
|
|
+ right: 0;
|
|
|
+ width: 100%;
|
|
|
+ z-index: 1;
|
|
|
+ padding-right: 10px;
|
|
|
+ background: #FAFAFA;
|
|
|
+ }
|
|
|
+
|
|
|
+ .outlet_data {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-end;
|
|
|
+ height: 34px;
|
|
|
+ background: #FAFAFA;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close_icon {
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .memberReply_title {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #222222;
|
|
|
+ line-height: 20px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ height: 44px;
|
|
|
+ padding: 0 10px;
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .pop_content {
|
|
|
+ padding: 10px 10px 10px;
|
|
|
+ background: #FAFAFA;
|
|
|
+ height: calc(100vh - 44px);
|
|
|
+ overflow: auto;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .select_box {
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .select_day {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background: #FFFFFF;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 10px 15px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ margin-right: 10px;
|
|
|
+ border-radius: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search_input {
|
|
|
+ width: 160px;
|
|
|
+ height: 38px;
|
|
|
+ border-radius: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-search__content {
|
|
|
+ background: #FFFFFF;
|
|
|
+ padding-left: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-search__label {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ width: unset;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-popover__wrapper {
|
|
|
+ height: unset;
|
|
|
+ }
|
|
|
+
|
|
|
+ .top_data_title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .top_data_right {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item_gap {
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .top_data_title_text {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #222222;
|
|
|
+ padding-left: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .top_data_title_branch {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ max-width: 90px;
|
|
|
+ white-space: nowrap;
|
|
|
+ /* 禁止换行 */
|
|
|
+ overflow: hidden;
|
|
|
+ /* 隐藏溢出内容 */
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ /* 显示省略号 */
|
|
|
+ }
|
|
|
+
|
|
|
+ .triangle {
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border: 6px solid transparent;
|
|
|
+ border-top-color: #222222;
|
|
|
+ margin-top: 6px;
|
|
|
+ border-radius: 5px;
|
|
|
+ margin-left: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .page4_content {
|
|
|
+ padding: 113px 10px 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .page4_content2 {
|
|
|
+ padding: 131px 10px 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .box_connect {
|
|
|
+ width: 100%;
|
|
|
+ background: #FFFFFF;
|
|
|
+ padding: 10px 10px 15px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ border-radius: 10px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .clientCharts_title_box {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+
|
|
|
+ .clientCharts_title {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .clientCharts_title::before {
|
|
|
+ content: '';
|
|
|
+ width: 2px;
|
|
|
+ height: 13px;
|
|
|
+ background: #1677FF;
|
|
|
+ border-radius: 1px;
|
|
|
+ margin-right: 5px;
|
|
|
+ display: inline-block;
|
|
|
+ }
|
|
|
+
|
|
|
+ .clientCharts_title_right {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #1677FF;
|
|
|
+ text-decoration-line: underline;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .all_data {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ margin-top: 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .add_data_p {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #999999;
|
|
|
+ padding: 4px 10px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 5px;
|
|
|
+ border: 1px solid #CCCCCC;
|
|
|
+ margin-top: 0;
|
|
|
+ margin-right: 15px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .allData_bg {
|
|
|
+ background: #1677FF;
|
|
|
+ border-radius: 5px;
|
|
|
+ border: 1px solid #1677FF;
|
|
|
+ color: #FFFFFF;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 选择日期组件开始 */
|
|
|
+ .select_date {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date_list {
|
|
|
+ width: 212px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ background: #EDF3F8;
|
|
|
+ border-radius: 20px;
|
|
|
+ padding: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter_time_item {
|
|
|
+ padding: 4px 0 3px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ line-height: 17px;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter_time1 {
|
|
|
+ padding-left: 14px;
|
|
|
+ padding-right: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter_time2 {
|
|
|
+ padding-left: 11px;
|
|
|
+ padding-right: 11px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter_time3 {
|
|
|
+ padding-left: 7px;
|
|
|
+ padding-right: 7px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter_time4 {
|
|
|
+ padding-left: 8px;
|
|
|
+ padding-right: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .current_date {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #1677FF;
|
|
|
+ line-height: 17px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 选择日期组件结束 */
|
|
|
+ .num_item_title {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 17px;
|
|
|
+ padding-bottom: 5px;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+
|
|
|
+ .num_item_count {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 24px;
|
|
|
+ padding-bottom: 5px;
|
|
|
+ color: #222222;
|
|
|
+ }
|
|
|
+
|
|
|
+ .num_item_data {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 10px;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .selected_color {
|
|
|
+ color: #1677FF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .client_item_icon {
|
|
|
+ width: 12px;
|
|
|
+ height: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .branch_table {
|
|
|
+ overflow-x: auto;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .branch_header {
|
|
|
+ padding: 10px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ background: #F7F9FC;
|
|
|
+ border-radius: 10px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ min-width: max-content;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .branch_header div {
|
|
|
+ min-width: 30px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .branch_item {
|
|
|
+ padding: 10px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ border-bottom: 1px solid #E5E8ED;
|
|
|
+ text-align: center;
|
|
|
+ word-wrap: break-word;
|
|
|
+ min-width: max-content;
|
|
|
+ }
|
|
|
+
|
|
|
+ .branch_item div {
|
|
|
+ min-width: 30px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .interact_box_bottom {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+
|
|
|
+ .interact_box_bottom {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+
|
|
|
+ .interact_line {
|
|
|
+ width: 1px;
|
|
|
+ /* margin: 0 8px; */
|
|
|
+ height: 66px;
|
|
|
+ background: linear-gradient(180deg, rgba(229, 232, 237, 0) 0%, #E5E8ED 51%, rgba(229, 232, 237, 0) 100%);
|
|
|
+ }
|
|
|
+
|
|
|
+ .interact_item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leadGen_box {
|
|
|
+ padding: 10px;
|
|
|
+ background: #FAFAFA;
|
|
|
+ border-radius: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leadGen_box {
|
|
|
+ padding: 10px;
|
|
|
+ background: #FAFAFA;
|
|
|
+ border-radius: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .table_carList {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ overflow-x: auto;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .table_carBox {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #222222;
|
|
|
+ border-radius: 34px;
|
|
|
+ margin-right: 10px;
|
|
|
+ padding: 0 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .table_carBox_bg {
|
|
|
+ background: linear-gradient(#FFFFFF 0%, #E6F0FF 100%);
|
|
|
+ }
|
|
|
+
|
|
|
+ .table_car {
|
|
|
+ width: 90px;
|
|
|
+ height: 45px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .table_carline {
|
|
|
+ width: 16px;
|
|
|
+ height: 3px;
|
|
|
+ border-radius: 34px;
|
|
|
+ margin-top: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .table_carline_bg {
|
|
|
+ background: #1677FF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data_tips {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 17px;
|
|
|
+ color: #C4CFDA;
|
|
|
+ text-align: center;
|
|
|
+ margin: 5px 0 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step_list {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ overflow-x: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step_box {
|
|
|
+ min-width: 125px;
|
|
|
+ padding: 10px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #666666;
|
|
|
+ background: #F7F9FC;
|
|
|
+ border-radius: 10px;
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step_box_bg {
|
|
|
+ background: #1677FF;
|
|
|
+ color: #FFFFFF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step_num {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #1677FF;
|
|
|
+ padding-top: 10px;
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .step_num_bg {
|
|
|
+ color: #FFFFFF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .van_loading {
|
|
|
+ height: 400px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+</style>
|
|
|
+
|
|
|
+<body>
|
|
|
+ <div id="box" class="box">
|
|
|
+ <!-- 数据查看 -->
|
|
|
+ <div class="page4">
|
|
|
+ <van-nav-bar :title="jxsName" class="navbar" fixed>
|
|
|
+ <template #left>
|
|
|
+ <image class="navbar_icon" src="./img/jxs1.png"></image>
|
|
|
+ </template>
|
|
|
+ <template #right>
|
|
|
+ <image class="navbar_icon" src="./img/jxs2.png" @click="handleShowPopup"></image>
|
|
|
+ </template>
|
|
|
+ </van-nav-bar>
|
|
|
+ <div class="top_data">
|
|
|
+ <div class="top_data_title">
|
|
|
+ <image class="navbar_icon" src="./img/jxs6.png"></image>
|
|
|
+ <div class="top_data_title_text">{{pageTitle}}</div>
|
|
|
+ </div>
|
|
|
+ <div class="top_data_right" v-if="pageTitle === '客户资产'">
|
|
|
+ <div class="top_data_title item_gap" @click="showPicker = true">
|
|
|
+ <div class="top_data_title_branch">网点:{{outletName}}</div>
|
|
|
+ <div class="triangle"></div>
|
|
|
+ </div>
|
|
|
+ <div class="top_data_title" @click="showDeptPicker = true">
|
|
|
+ <div class="top_data_title_branch">部门:{{deptName}}</div>
|
|
|
+ <div class="triangle"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <select-date v-else :page-date="pageDate" @change-date="handleChangeDate"></select-date>
|
|
|
+ </div>
|
|
|
+ <div class="top_data_bottom" v-show="pageTitle !== '客户资产'">
|
|
|
+ <div class="outlet_data item_gap" @click="showPicker = true">
|
|
|
+ <div class="top_data_title_branch">网点:{{outletName}}</div>
|
|
|
+ <div class="triangle"></div>
|
|
|
+ </div>
|
|
|
+ <div class="outlet_data" @click="showDeptPicker = true">
|
|
|
+ <div class="top_data_title_branch">部门:{{deptName}}</div>
|
|
|
+ <div class="triangle"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <van-popup v-model="showPopup" duration="0.2" closeable position="top" :lock-scroll="false"
|
|
|
+ :style="{ height: '100vh' }" @close="handleClosePopup">
|
|
|
+ <div class="popup_list" v-show="!showMer">
|
|
|
+ <div class="popup_item" @click="handlePage(1)">客户资产</div>
|
|
|
+ <div class="popup_line"></div>
|
|
|
+ <div class="popup_item" @click="handlePage(2)">聊天分析</div>
|
|
|
+ <div class="popup_line"></div>
|
|
|
+ <div class="popup_item" @click="handlePage(3)">员工监测</div>
|
|
|
+ <div class="popup_line"></div>
|
|
|
+ <div class="popup_item" @click="handlePage(4)">运营任务</div>
|
|
|
+ <div class="popup_line"></div>
|
|
|
+ <div class="popup_item" @click="showMer = true">切换商户</div>
|
|
|
+ <div class="popup_line"></div>
|
|
|
+ <div class="popup_item" @click="handleLoginOut">退出登录</div>
|
|
|
+ </div>
|
|
|
+ <div class="popup_list" v-show="showMer">
|
|
|
+ <div class="mer_item" :class="{'mer_item_active': tenancyId == item.id}" v-for="(item, index) in merList"
|
|
|
+ :key="index" @click="handleSelectMer(item)">{{item.name}}</div>
|
|
|
+ </div>
|
|
|
+ </van-popup>
|
|
|
+ <van-popup v-model="showPicker" duration="0.2" round position="bottom">
|
|
|
+ <van-picker title="网点" show-toolbar :columns="outletsData" @confirm="onConfirm" @cancel="showPicker = false" />
|
|
|
+ </van-popup>
|
|
|
+ <van-popup v-model="showDeptPicker" duration="0.2" round position="bottom">
|
|
|
+ <van-picker title="部门" show-toolbar :columns="deptData" @confirm="onDeptConfirm"
|
|
|
+ @cancel="showDeptPicker = false" />
|
|
|
+ </van-popup>
|
|
|
+ <!-- 顾问响应统计 -->
|
|
|
+ <van-popup v-model="showMemberReply" duration="0.2" position="right" :overlay="false" :lock-scroll="false"
|
|
|
+ :style="{ width: '100%', height: '100vh' }">
|
|
|
+ <div class="memberReply_title">
|
|
|
+ <image class="close_icon" src="./img/close.png" @click="closeReply"></image>
|
|
|
+ <div>顾问响应统计</div>
|
|
|
+ <div class="close_icon"></div>
|
|
|
+ </div>
|
|
|
+ <div class="pop_content">
|
|
|
+ <div class="select_box">
|
|
|
+ <van-popover v-model="showDatePicker" trigger="click" close-on-click-action close-on-click-outside
|
|
|
+ :actions="actions" @select="onSelect">
|
|
|
+ <template #reference>
|
|
|
+ <div class="select_day">
|
|
|
+ <div class="top_data_title_branch">时间:{{timeData}}</div>
|
|
|
+ <div class="triangle"></div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </van-popover>
|
|
|
+ <van-search class="search_input" v-model="keyword" search :clearable="false" label="顾问:" left-icon=""
|
|
|
+ right-icon="search" @search="handleSearch" @click-right-icon="handleSearch"></van-search>
|
|
|
+ <van-calendar type="range" v-model="showSelfDate" @confirm="onSelfConfirm" color="#1677FF"
|
|
|
+ :min-date="minDate" :max-date="maxDate" :allow-same-day="true"></van-calendar>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <van-loading type="spinner" color="#1989fa" class="van_loading" v-if="loading"></van-loading>
|
|
|
+ <div class="branch_table" style="margin-bottom: 20px;" v-if="!loading">
|
|
|
+ <div class="branch_header" style="box-sizing: border-box;">
|
|
|
+ <div style="width: 80px;">顾问</div>
|
|
|
+ <div style="width: 50px;">今日处理<br />消息数</div>
|
|
|
+ <div style="width: 40px;">超时<br />消息数</div>
|
|
|
+ <div style="width: 50px;">平均响应<br />时间</div>
|
|
|
+ <div style="width: 30px;">管理</div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in memberReplyData"
|
|
|
+ :key="index">
|
|
|
+ <div style="width: 80px;max-width: 80px;">{{item.memberName}}</div>
|
|
|
+ <div style="width: 50px;">{{item.replyMsg}}</div>
|
|
|
+ <div style="width: 40px;">{{item.timeoutMsg}}</div>
|
|
|
+ <div style="width: 50px;">{{formatTime(item.avgReplyDuration)}}</div>
|
|
|
+ <div style="width: 30px;color: #1677FF;" @click="handleItemMemberReply(item)">详情</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <van-pagination v-model="currentPage" :total-items="totalItems" :show-page-size="3" force-ellipses
|
|
|
+ @change="handleChangePage" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </van-popup>
|
|
|
+ <!-- 顾问响应统计详情 -->
|
|
|
+ <van-popup v-model="showItemMemberReply" position="right" duration="0.2" :lock-scroll="false" :overlay="false"
|
|
|
+ :style="{ width: '100%', height: '100vh' }">
|
|
|
+ <div class="memberReply_title">
|
|
|
+ <image class="close_icon" src="./img/close.png" @click="closeItemMemberReply"></image>
|
|
|
+ <div>顾问:{{currentMemberName}}</div>
|
|
|
+ <div class="close_icon"></div>
|
|
|
+ </div>
|
|
|
+ <div class="pop_content">
|
|
|
+ <div class="select_box">
|
|
|
+ <van-popover v-model="showDatePicker2" trigger="click" close-on-click-action close-on-click-outside
|
|
|
+ :actions="actions" @select="onSelect">
|
|
|
+ <template #reference>
|
|
|
+ <div class="select_day">
|
|
|
+ <div class="top_data_title_branch">时间:{{timeData}}</div>
|
|
|
+ <div class="triangle"></div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </van-popover>
|
|
|
+ <van-calendar type="range" v-model="showSelfDate" @confirm="onSelfConfirm" color="#1677FF"
|
|
|
+ :min-date="minDate" :max-date="maxDate" :allow-same-day="true"></van-calendar>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <van-loading type="spinner" color="#1989fa" class="van_loading" v-if="loading"></van-loading>
|
|
|
+ <div class="branch_table" style="margin-bottom: 20px;" v-if="!loading">
|
|
|
+ <div class="branch_header">
|
|
|
+ <div style="width: 60px;">客户昵称</div>
|
|
|
+ <div style="width: 100px;">手机号</div>
|
|
|
+ <div style="width: 80px;">最新消息<br />时间</div>
|
|
|
+ <div style="width: 60px;">等待时间</div>
|
|
|
+ <div style="width: 100px;">最新消息<br />内容</div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_item" v-for="(item, index) in memberDetailReplyData" :key="index">
|
|
|
+ <div style="width: 60px;">{{item.clientName}}</div>
|
|
|
+ <div style="width: 100px;">{{item.clientPhone}}</div>
|
|
|
+ <div style="width: 80px;">{{timeFormat(item.msgTime)}}</div>
|
|
|
+ <div style="width: 60px;">{{formatTime(item.waitSeconds)}}</div>
|
|
|
+ <div style="width: 100px;">{{item.content}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <van-pagination v-model="currentItemPage" :total-items="itemTotalItems" :show-page-size="3" force-ellipses
|
|
|
+ @change="handleChangeItemPage" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </van-popup>
|
|
|
+ <!-- 顾问完成情况统计 -->
|
|
|
+ <van-popup v-model="showDoneReply" position="right" duration="0.2" :overlay="false" :lock-scroll="false"
|
|
|
+ :style="{ width: '100%', height: '100vh' }">
|
|
|
+ <div class="memberReply_title">
|
|
|
+ <image class="close_icon" src="./img/close.png" @click="closeReply"></image>
|
|
|
+ <div>顾问完成情况统计</div>
|
|
|
+ <div class="close_icon"></div>
|
|
|
+ </div>
|
|
|
+ <div class="pop_content">
|
|
|
+ <div class="select_box">
|
|
|
+ <van-popover v-model="showDatePicker3" trigger="click" close-on-click-action close-on-click-outside
|
|
|
+ :actions="actions" @select="onSelect">
|
|
|
+ <template #reference>
|
|
|
+ <div class="select_day">
|
|
|
+ <div class="top_data_title_branch">时间:{{timeData}}</div>
|
|
|
+ <div class="triangle"></div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </van-popover>
|
|
|
+ <van-calendar type="range" v-model="showSelfDate" @confirm="onSelfConfirm" color="#1677FF"
|
|
|
+ :min-date="minDate" :max-date="maxDate" :allow-same-day="true"></van-calendar>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="branch_table" style="margin-bottom: 20px;">
|
|
|
+ <div class="branch_header" style="box-sizing: border-box;">
|
|
|
+ <div style="width: 60px;">顾问</div>
|
|
|
+ <div style="width: 60px;">网点</div>
|
|
|
+ <div style="width: 60px;">下发任务数</div>
|
|
|
+ <div style="width: 60px;">完成任务数</div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in doneReplyData"
|
|
|
+ :key="index">
|
|
|
+ <div style="width: 60px;">{{item.memberName}}</div>
|
|
|
+ <div style="width: 60px;">{{item.outletName}}</div>
|
|
|
+ <div style="width: 60px;">{{item.taskNum}}</div>
|
|
|
+ <div style="width: 60px;">{{item.completeNum}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <van-pagination v-model="currentPage" :total-items="totalItems" :show-page-size="3" force-ellipses
|
|
|
+ @change="handleChangePage" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </van-popup>
|
|
|
+ <div class="page4_content" v-show="pageTitle === '客户资产'">
|
|
|
+ <!-- 客户资产 -->
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title" style="margin-bottom: 0;">总数据
|
|
|
+ <van-popover style="height: 20px;" v-model="showPopover" trigger="click" theme="dark" placement="right">
|
|
|
+ <div class="explain_list">
|
|
|
+ <div>总客户数:添加企微的客户总数</div>
|
|
|
+ <div>互动客户数:有产生过客户动态(包括不限于内容浏览、活动浏览、聊天等)的客户数</div>
|
|
|
+ <div>留资报名客户数:填写过表单(含留资/活动报名等)的客户数</div>
|
|
|
+ <div>到店客户:展厅进店及售后回站客户数</div>
|
|
|
+ <div>成交客户:已购车的客户数(不含下订客戶)</div>
|
|
|
+ </div>
|
|
|
+ <template #reference>
|
|
|
+ <image class="explain_icon" src="./img/jxs7.png"></image>
|
|
|
+ </template>
|
|
|
+ </van-popover>
|
|
|
+ </div>
|
|
|
+ <div id="funnelChart" :style="{ width: '100%', height: '200px', marginBottom: '20px' }"></div>
|
|
|
+ <select-date :page-date="pageDate" @change-date="handleChangeDate"></select-date>
|
|
|
+ <div class="all_data">
|
|
|
+ <p class="add_data_p" :class="{'allData_bg': index === 1}" @click="handleClickItem(1)">总客户数</p>
|
|
|
+ <p class="add_data_p" :class="{'allData_bg': index === 2}" @click="handleClickItem(2)">互动客户数</p>
|
|
|
+ <p class="add_data_p" :class="{'allData_bg': index === 3}" @click="handleClickItem(3)">留资/报名客户数</p>
|
|
|
+ <p class="add_data_p" :class="{'allData_bg': index === 4}" @click="handleClickItem(4)">邀约到店客户数</p>
|
|
|
+ <p class="add_data_p" :class="{'allData_bg': index === 5}" @click="handleClickItem(5)">成交客户数</p>
|
|
|
+ </div>
|
|
|
+ <div id="adviserChart" v-if="index === 1" style="width: 100%;height: 200px;"></div>
|
|
|
+ <div id="labelChart" v-else style="width: 100%;height: 200px;"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">客群包分布</div>
|
|
|
+ <div class="table_carList">
|
|
|
+ <div class="table_carBox" :class="{'table_carBox_bg': carIndex === index}"
|
|
|
+ v-for="(item, index) in tableList" :key="index" @click="handleClickCar(item, index)">
|
|
|
+ <image class="table_car" :src="item.carModelImg"></image>
|
|
|
+ <div>{{item.carModel}}</div>
|
|
|
+ <div class="table_carline" :class="{'table_carline_bg': carIndex === index}"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_table" v-if="carStepData.length > 0">
|
|
|
+ <div class="branch_header">
|
|
|
+ <div style="width: 40px;">阶段</div>
|
|
|
+ <div style="width: 60px;" v-for="(item, index) in carStepData[0].packageList[0].cols" :key="index">
|
|
|
+ {{item.name}}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_item" v-for="(item, index) in carStepData[0].packageList" :key="index">
|
|
|
+ <div style="width: 40px;">{{item.stepName}}</div>
|
|
|
+ <!-- 此处先循环carStepData[0].packageList[0].cols,是表格头以第一条数据为准 -->
|
|
|
+ <div style="min-width: 60px;" v-for="(val, valIndex) in carStepData[0].packageList[0].cols"
|
|
|
+ :key="valIndex">
|
|
|
+ <span style="min-width: 60px;" v-for="(col, colIndex) in item.cols" :key="colIndex">
|
|
|
+ {{val.name === col.name ? col.value[0] : ''}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">意向车型标签排名</div>
|
|
|
+ <div id="intentRankChart" style="width: 100%;height: 100%;"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">已购车型标签排名</div>
|
|
|
+ <div id="buyRankChart" style="width: 100%;height: 100%;"></div>
|
|
|
+ </div>
|
|
|
+ <div class="data_tips">—— 每日5:00更新数据 ——</div>
|
|
|
+ </div>
|
|
|
+ <div class="page4_content2" v-show="pageTitle === '聊天分析'">
|
|
|
+ <!-- 聊天分析 -->
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">总数据</div>
|
|
|
+ <div class="leadGen_box">
|
|
|
+ <div class="interact_box_bottom">
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">私聊客户数</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.privateChat}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>昨日新增:
|
|
|
+ <span class="selected_color">{{chatIndicators.yda.privateChat}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" src="./img/jxs-up1.png"></image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="interact_line"></div>
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">私聊消息数</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.privateMsgNum}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>昨日新增:
|
|
|
+ <span class="selected_color">{{chatIndicators.yda.privateMsgNum}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" src="./img/jxs-up1.png"></image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="interact_line"></div>
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">群消息数</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.groupMsgNum}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>昨日新增:
|
|
|
+ <span class="selected_color">{{chatIndicators.yda.groupMsgNum}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" src="./img/jxs-up1.png"></image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div id="interactChart" style="width: 100%;height: 200px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">员工服务</div>
|
|
|
+ <div class="leadGen_box">
|
|
|
+ <div class="interact_box_bottom">
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">主动服务会话数</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.proactiveServe}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>昨日新增:
|
|
|
+ <span class="selected_color">{{chatIndicators.yda.proactiveServe}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" src="./img/jxs-up1.png"></image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="interact_line"></div>
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">客户回复会话数</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.clientReply}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>昨日新增:
|
|
|
+ <span class="selected_color">{{chatIndicators.yda.clientReply}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" src="./img/jxs-up1.png"></image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="interact_line"></div>
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">客户回复率</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.clientReplyPercent ?
|
|
|
+ chatIndicators.total.clientReplyPercent + '%' : ''}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>较昨日:
|
|
|
+ <span v-if="chatIndicators.yda.clientReplyPercent" class="selected_color"
|
|
|
+ :style="{color: chatIndicators.yda.clientReplyPercent > 0 ? '#1677FF' : '#FF4E4E'}">
|
|
|
+ {{chatIndicators.yda.clientReplyPercent > 0 ? '+' :
|
|
|
+ ''}}{{chatIndicators.yda.clientReplyPercent}}%</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" v-if="chatIndicators.yda.clientReplyPercent"
|
|
|
+ :src="chatIndicators.yda.clientReplyPercent > 0 ? './img/jxs-up1.png' : './img/jxs-down2.png'">
|
|
|
+ </image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div id="staffChart" style="width: 100%;height: 200px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">客户咨询</div>
|
|
|
+ <div class="leadGen_box">
|
|
|
+ <div class="interact_box_bottom">
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">主动咨询会话数</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.proactiveConsult}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>昨日新增:
|
|
|
+ <span class="selected_color">{{chatIndicators.yda.proactiveConsult}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" src="./img/jxs-up1.png"></image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="interact_line"></div>
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">员工回复会话数</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.memberReply}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>昨日新增:
|
|
|
+ <span class="selected_color">{{chatIndicators.yda.memberReply}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" src="./img/jxs-up1.png"></image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="interact_line"></div>
|
|
|
+ <div class="interact_item">
|
|
|
+ <div class="num_item_title">员工平均响应时长</div>
|
|
|
+ <div class="num_item_count">{{chatIndicators.total.avgReplyDuration ?
|
|
|
+ formatTime(chatIndicators.total.avgReplyDuration) : ''}}</div>
|
|
|
+ <div class="num_item_data">
|
|
|
+ <div>较昨日:
|
|
|
+ <span v-if="chatIndicators.yda.avgReplyDuration" class="selected_color"
|
|
|
+ :style="{color: chatIndicators.yda.avgReplyDuration > 0 ? '#FF4E4E' : '#1677FF'}">
|
|
|
+ {{chatIndicators.yda.avgReplyDuration > 0 ? '+' :
|
|
|
+ ''}}{{formatTime(chatIndicators.yda.avgReplyDuration)}}</span>
|
|
|
+ </div>
|
|
|
+ <image class="client_item_icon" v-if="chatIndicators.yda.avgReplyDuration"
|
|
|
+ :src="chatIndicators.yda.avgReplyDuration > 0 ? './img/jxs-up2.png' : './img/jxs-down1.png'">
|
|
|
+ </image>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div id="clientChart" style="width: 100%;height: 200px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">消息舆情分析</div>
|
|
|
+ <div id="opinionChart" style="width: 100%;height: 380px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">客户关注词云图</div>
|
|
|
+ <div id="wordCloudChart" style="width: 100%;height: 200px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="data_tips">—— 每日5:00更新数据 ——</div>
|
|
|
+ </div>
|
|
|
+ <div class="page4_content2" v-show="pageTitle === '员工监测'">
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">销售进程客户数</div>
|
|
|
+ <div class="step_list">
|
|
|
+ <div class="step_box" :class="{'step_box_bg': clientIndex === index}"
|
|
|
+ v-for="(item, index) in saleIndicators" :key="index" @click="handleClickClient(item, index)">
|
|
|
+ <div>{{item.processName}}</div>
|
|
|
+ <div class="step_num" :class="{'step_num_bg': clientIndex === index}">{{item.clientNum}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div id="clientStepChart" style="width: 100%;height: 200px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">销售统计排名</div>
|
|
|
+ <div class="branch_table" v-if="saleRankData.length > 0">
|
|
|
+ <div class="branch_header">
|
|
|
+ <div style="width: 30px;">排名</div>
|
|
|
+ <div style="width: 80px;">顾问</div>
|
|
|
+ <div style="width: 40px;">网点</div>
|
|
|
+ <div style="width: 60px;" v-for="(item, index) in saleRankData[0].cols" :key="index">
|
|
|
+ {{item.name}}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_item" v-for="(item, index) in saleRankData" :key="index">
|
|
|
+ <div style="width: 30px;">{{index + 1}}</div>
|
|
|
+ <div style="width: 80px;max-width: 80px;">{{item.memberName}}</div>
|
|
|
+ <div style="width: 40px;">{{item.outletName}}</div>
|
|
|
+ <!-- 此处先循环saleRankData[0].cols,是表格头以第一条数据为准 -->
|
|
|
+ <div style="min-width: 60px;" v-for="(val, valIndex) in saleRankData[0].cols" :key="valIndex">
|
|
|
+ <span style="min-width: 60px;" v-for="(col, colIndex) in item.cols" :key="colIndex">
|
|
|
+ {{val.name === col.name ? (col.value ? col.value[0] : '-') : ''}}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title_box">
|
|
|
+ <div class="clientCharts_title">聊天超时监测</div>
|
|
|
+ <div class="clientCharts_title_right" @click="handleMemberReply">查看详情</div>
|
|
|
+ </div>
|
|
|
+ <div id="timeOutTrendChart" style="width: 100%;height: 230px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">聊天排行榜</div>
|
|
|
+ <div class="branch_table">
|
|
|
+ <div class="branch_header" style="box-sizing: border-box;">
|
|
|
+ <div style="width: 30px;">排名</div>
|
|
|
+ <div style="width: 80px;">员工</div>
|
|
|
+ <div style="width: 50px;">聊天客户数</div>
|
|
|
+ <div style="width: 50px;">主动会话<br />服务数</div>
|
|
|
+ <div style="width: 50px;">客户回复<br />会话数</div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in chatRankData" :key="index">
|
|
|
+ <div style="width: 30px;">{{index + 1}}</div>
|
|
|
+ <div style="width: 80px;max-width: 80px;">{{item.memberName}}</div>
|
|
|
+ <div style="width: 50px;">{{item.privateChat}}</div>
|
|
|
+ <div style="width: 50px;">{{item.proactiveServe}}</div>
|
|
|
+ <div style="width: 50px;">{{item.clientReply}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="data_tips">—— 每日5:00更新数据 ——</div>
|
|
|
+ </div>
|
|
|
+ <div class="page4_content2" v-show="pageTitle === '运营任务'">
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title_box">
|
|
|
+ <div class="clientCharts_title">总数据</div>
|
|
|
+ <div class="clientCharts_title_right" @click="handleDoneReply">查看更多</div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_table">
|
|
|
+ <div class="branch_header" style="box-sizing: border-box;">
|
|
|
+ <div style="width: 60px;">网点</div>
|
|
|
+ <div style="width: 60px;">下发任务数</div>
|
|
|
+ <div style="width: 60px;">任务完成率</div>
|
|
|
+ <div style="width: 60px;">互动客户数</div>
|
|
|
+ <div>激活率</div>
|
|
|
+ </div>
|
|
|
+ <div class="branch_item" style="box-sizing: border-box;" v-for="(item, index) in outletCount" :key="index">
|
|
|
+ <div style="width: 60px;">{{item.outletName}}</div>
|
|
|
+ <div style="width: 60px;">{{item.taskNum}}</div>
|
|
|
+ <div style="width: 60px;">{{item.taskCompletePercent ? item.taskCompletePercent + '%' : '-'}}</div>
|
|
|
+ <div style="width: 60px;">{{item.interactClient}}</div>
|
|
|
+ <div>{{item.activatePercent ? item.activatePercent + '%' : '-'}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">任务完成率</div>
|
|
|
+ <div id="taskCompleteChart" style="width: 100%;height: 200px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">互动客户数</div>
|
|
|
+ <div id="opInteractChart" style="width: 100%;height: 200px"></div>
|
|
|
+ </div>
|
|
|
+ <div class="box_connect">
|
|
|
+ <div class="clientCharts_title">素材排行榜</div>
|
|
|
+ <div id="contentRank" style="width: 100%;"></div>
|
|
|
+ </div>
|
|
|
+ <div class="data_tips">—— 每日5:00更新数据 ——</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</body>
|
|
|
+<script>
|
|
|
+ new Vue({
|
|
|
+ el: '#box',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ httpUrl: '',
|
|
|
+ bId: null,
|
|
|
+ env: '',
|
|
|
+ jxsName: '',
|
|
|
+ token: '',
|
|
|
+ tenancyId: '',
|
|
|
+ showPopup: false,
|
|
|
+ showMer: false,
|
|
|
+ showDatePicker: false,
|
|
|
+ showDatePicker2: false,
|
|
|
+ showDatePicker3: false,
|
|
|
+ actions: [
|
|
|
+ { text: '昨日' }, { text: '近7天' }, { text: '近30天' }, { text: '自定义' }
|
|
|
+ ],
|
|
|
+ keyword: '',
|
|
|
+ showSelfDate: false,
|
|
|
+ minDate: '',
|
|
|
+ maxDate: '',
|
|
|
+
|
|
|
+ merList: [], // 商户列表
|
|
|
+ outletsList: [], // 网点列表
|
|
|
+ outletsData: [], // 网点列表数据
|
|
|
+ deptList: [], // 部门列表
|
|
|
+ deptData: [], // 部门列表数据
|
|
|
+ pageTitle: '客户资产',
|
|
|
+ showPicker: false, // 网点选择器
|
|
|
+ showDeptPicker: false, // 部门选择器
|
|
|
+ deptName: '', // 部门名称
|
|
|
+ deptId: null, // 部门id
|
|
|
+ outletName: '', // 网点名称
|
|
|
+ outletId: null, // 网点id
|
|
|
+
|
|
|
+ clientIndicators: [], // 客户资产-总数据
|
|
|
+ pageStartTime: '',
|
|
|
+ pageEndTime: '',
|
|
|
+ index: 1,
|
|
|
+ showPopover: false,
|
|
|
+
|
|
|
+ lineDate: [], // 客户资产-统计趋势图
|
|
|
+ saleAdd: [],
|
|
|
+ serveAdd: [],
|
|
|
+ interactClient: [],
|
|
|
+ formClient: [],
|
|
|
+ storeClient: [],
|
|
|
+ dealClient: [],
|
|
|
+
|
|
|
+ tableList: [], // 客群包阶段车型
|
|
|
+ carIndex: 0,
|
|
|
+ carStepData: [], // 客群包阶段车型数据
|
|
|
+
|
|
|
+ intentRankData: [], // 意向车型标签排名
|
|
|
+ buyRankData: [], // 已购车型标签排名
|
|
|
+
|
|
|
+ chatIndicators: {
|
|
|
+ dayList: [], // 聊天分析-日数据
|
|
|
+ opinion: {},
|
|
|
+ total: {
|
|
|
+ privateChat: 0,
|
|
|
+ privateMsgNum: 0,
|
|
|
+ groupMsgNum: 0,
|
|
|
+ proactiveServe: 0,
|
|
|
+ clientReply: 0,
|
|
|
+ clientReplyPercent: 0,
|
|
|
+ proactiveConsult: 0,
|
|
|
+ memberReply: 0,
|
|
|
+ avgReplyDuration: 0,
|
|
|
+
|
|
|
+ },
|
|
|
+ yda: {
|
|
|
+ privateChat: 0,
|
|
|
+ privateMsgNum: 0,
|
|
|
+ groupMsgNum: 0,
|
|
|
+ proactiveServe: 0,
|
|
|
+ clientReply: 0,
|
|
|
+ clientReplyPercent: 0,
|
|
|
+ proactiveConsult: 0,
|
|
|
+ memberReply: 0,
|
|
|
+ avgReplyDuration: 0,
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ interactDate: [], // 聊天分析-总数据图数据
|
|
|
+ privateChat: [],
|
|
|
+ privateMsgNum: [],
|
|
|
+ groupMsgNum: [],
|
|
|
+ proactiveServe: [],
|
|
|
+ clientReply: [],
|
|
|
+ clientReplyPercent: [],
|
|
|
+ proactiveConsult: [],
|
|
|
+
|
|
|
+ memberReply: [],
|
|
|
+
|
|
|
+ showItemMemberReply: false, // 显示客户详情响应数据
|
|
|
+ currentMemberName: '', // 当前客户名称
|
|
|
+ memberId: '', // 当前客户id
|
|
|
+ memberDetailReplyData: [], // 客户详情响应数据
|
|
|
+ currentItemPage: 1, // 当前客户详情响应数据页码
|
|
|
+ itemTotalItems: 0, // 客户详情响应数据总页数
|
|
|
+
|
|
|
+ avgReplyDuration: [],
|
|
|
+ totalMsg: [],
|
|
|
+ privateMsg: [],
|
|
|
+ groupMsg: [],
|
|
|
+ maxValue: null,
|
|
|
+
|
|
|
+ wordCloudMap: [], // 客户关注词云图
|
|
|
+
|
|
|
+ saleIndicators: [], // 销售进程客户数
|
|
|
+ clientIndex: 0, // 销售进程客户数索引
|
|
|
+ clientStepDate: [], // 销售进程客户数-日期
|
|
|
+ clientStepNum: [], // 销售进程客户数-客户数
|
|
|
+
|
|
|
+ saleRankData: [], // 销售统计排名数据
|
|
|
+ timeOutDate: [], // 聊天超时监测-日期
|
|
|
+ timeoutMember: [], // 聊天超时监测-超时客户数
|
|
|
+ timeData: '',
|
|
|
+ memberStartTime: '',
|
|
|
+ memberEndTime: '',
|
|
|
+ showDoneReply: false, // 显示已完成响应数据
|
|
|
+ doneReplyData: [], // 已完成响应数据
|
|
|
+
|
|
|
+ showMemberReply: false,
|
|
|
+ currentPage: 1,
|
|
|
+ totalItems: 0,
|
|
|
+ memberReplyData: [], // 顾问响应统计数据
|
|
|
+ chatRankData: [], // 聊天排行榜数据
|
|
|
+
|
|
|
+ outletCount: [], // 运营任务-总数据
|
|
|
+ taskCompleteDate: [], // 运营任务-任务完成率-日期
|
|
|
+ taskCompletePercent: [], // 运营任务-任务完成率
|
|
|
+ opInteractDate: [], // 运营任务-互动客户数-日期
|
|
|
+ opInteractClient: [], // 运营任务-互动客户数
|
|
|
+
|
|
|
+ contentRankData: [], // 运营任务-素材排行榜
|
|
|
+ loading: false,
|
|
|
+ pageDate: [], // 日期范围
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ let nowDat = new Date();
|
|
|
+ let dateY = nowDat.getFullYear()
|
|
|
+ let dateM = nowDat.getMonth()
|
|
|
+ let dateD = nowDat.getDate()
|
|
|
+ // 设置日期可选最小值minDate、最大值maxDate
|
|
|
+ this.minDate = new Date(dateY - 1, dateM, dateD)
|
|
|
+ //日历可选范围为一年,dateY + 1
|
|
|
+ this.maxDate = new Date(dateY, dateM, dateD - 1)
|
|
|
+
|
|
|
+ this.bId = this.getQueryParam('bId')
|
|
|
+ this.env = this.getQueryParam('env')
|
|
|
+
|
|
|
+ if (!this.env || this.env === 'prod') {
|
|
|
+ this.httpUrl = 'https://wlapi.wefanbot.com'
|
|
|
+ // this.httpUrl = 'http://192.168.1.128:18993'
|
|
|
+ } else {
|
|
|
+ this.httpUrl = 'http://test.wefanbot.com:18993'
|
|
|
+ // this.httpUrl = 'http://192.168.1.128:18993'
|
|
|
+ }
|
|
|
+ this.token = localStorage.getItem('tokenValue')
|
|
|
+ this.tenancyId = localStorage.getItem('tenancyIdValue')
|
|
|
+ this.jxsName = localStorage.getItem('tenancyNameValue') || ''
|
|
|
+
|
|
|
+ this.pageStartTime = this.getDateTime(-7)
|
|
|
+ this.pageEndTime = this.getDateTime(-1)
|
|
|
+ this.memberStartTime = this.getDateTime(-7)
|
|
|
+ this.memberEndTime = this.getDateTime(-1)
|
|
|
+
|
|
|
+ this.initialization()
|
|
|
+ this.getAdminList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 初始化
|
|
|
+ initialization() {
|
|
|
+ this.clientIndicators = []
|
|
|
+ this.pageStartTime = this.getDateTime(-7)
|
|
|
+ this.pageEndTime = this.getDateTime(-1)
|
|
|
+ this.index = 1
|
|
|
+ this.outletName = ''
|
|
|
+ this.outletId = null
|
|
|
+ this.getOutletsData()
|
|
|
+ this.deptName = ''
|
|
|
+ this.deptId = null
|
|
|
+ this.getDeptData() // 部门列表数据
|
|
|
+ },
|
|
|
+ requestData() {
|
|
|
+ if (this.pageTitle === '客户资产') {
|
|
|
+ this.getClientIndicators() // 客户资产-总数据
|
|
|
+ this.getTrend() // 客户资产-统计趋势图
|
|
|
+ this.stepStatistic() // 客户资产-客群包分布
|
|
|
+ this.getIntentRank() // 意向车型标签排名
|
|
|
+ this.getBuyRank() // 已购车型标签排名
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.funnelDraw()
|
|
|
+ this.passValue()
|
|
|
+ this.intentRankChart()
|
|
|
+ this.buyRankChart()
|
|
|
+ })
|
|
|
+ } else if (this.pageTitle === '聊天分析') {
|
|
|
+ this.handlePage(2)
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.interactChart()
|
|
|
+ this.staffChart()
|
|
|
+ this.clientChart()
|
|
|
+ this.opinionChart()
|
|
|
+ this.wordCloudChart()
|
|
|
+ })
|
|
|
+ } else if (this.pageTitle === '员工监测') {
|
|
|
+ this.handlePage(3)
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.clientStepChart()
|
|
|
+ this.timeOutTrendChart()
|
|
|
+ })
|
|
|
+ } else if (this.pageTitle === '运营任务') {
|
|
|
+ this.handlePage(4)
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.taskCompleteChart()
|
|
|
+ this.opInteractChart()
|
|
|
+ this.contentRankChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取商户列表(右上角)
|
|
|
+ getAdminList() {
|
|
|
+ const headers = new Headers()
|
|
|
+ headers.append('token', this.token)
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/user-info/o/adminList`, {
|
|
|
+ method: 'GET',
|
|
|
+ headers: headers
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.merList = data || []
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取网点列表
|
|
|
+ getOutletsData() {
|
|
|
+ const headers = new Headers()
|
|
|
+ headers.append('token', this.token)
|
|
|
+ headers.append('tenancyId', this.tenancyId)
|
|
|
+ this.outletsList = []
|
|
|
+ this.outletsData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/tenancy-outlet/options`, {
|
|
|
+ method: 'GET',
|
|
|
+ headers: headers
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.outletsList = data || []
|
|
|
+ this.outletsData = data && data.length > 0 ? data.map(item => item.name) : []
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ if (this.outletsList.length === 1) {
|
|
|
+ this.outletName = this.outletsData[0]
|
|
|
+ this.outletId = this.outletsList.find(item => item.name === this.outletName).id || null
|
|
|
+ } else if (this.outletsList.length === 0 || this.outletsList.length > 1) {
|
|
|
+ this.outletsData.unshift('全部')
|
|
|
+ this.outletName = '全部'
|
|
|
+ this.outletId = null
|
|
|
+ }
|
|
|
+ this.requestData()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取网点列表
|
|
|
+ getDeptData() {
|
|
|
+ const headers = new Headers()
|
|
|
+ headers.append('token', this.token)
|
|
|
+ headers.append('tenancyId', this.tenancyId)
|
|
|
+ this.deptList = []
|
|
|
+ this.deptData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/tenancy-outlet-department/options`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletIds: this.outletId ? [this.outletId] : []
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.deptList = data || []
|
|
|
+ this.deptData = data && data.length > 0 ? data.map(item => item.name) : []
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ if (this.deptList.length === 1) {
|
|
|
+ this.deptName = this.deptData[0]
|
|
|
+ this.deptId = this.deptList.find(item => item.name === this.deptName).id || null
|
|
|
+ } else if (this.deptList.length === 0 || this.deptList.length > 1) {
|
|
|
+ this.deptData.unshift('全部')
|
|
|
+ this.deptName = '全部'
|
|
|
+ this.deptId = null
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onConfirm(val) {
|
|
|
+ this.outletName = val
|
|
|
+ if (this.outletName === '全部') {
|
|
|
+ this.outletId = null
|
|
|
+ } else {
|
|
|
+ this.outletId = this.outletsList.find(item => item.name === this.outletName).id || null
|
|
|
+ }
|
|
|
+ this.showPicker = false
|
|
|
+ this.deptId = null
|
|
|
+ this.deptName = '全部'
|
|
|
+ this.getDeptData()
|
|
|
+ if (this.pageTitle === '客户资产') {
|
|
|
+ this.getClientIndicators() // 客户资产-总数据
|
|
|
+ this.getTrend() // 客户资产-统计趋势图
|
|
|
+ this.stepStatistic() // 客户资产-客群包分布
|
|
|
+ this.getIntentRank() // 意向车型标签排名
|
|
|
+ this.getBuyRank() // 已购车型标签排名
|
|
|
+ } else if (this.pageTitle === '聊天分析') {
|
|
|
+ this.handlePage(2)
|
|
|
+ } else if (this.pageTitle === '员工监测') {
|
|
|
+ this.handlePage(3)
|
|
|
+ } else if (this.pageTitle === '运营任务') {
|
|
|
+ this.handlePage(4)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onDeptConfirm(val) {
|
|
|
+ this.deptName = val
|
|
|
+ if (this.deptName === '全部') {
|
|
|
+ this.deptId = null
|
|
|
+ } else {
|
|
|
+ this.deptId = this.deptList.find(item => item.name === this.deptName).id || null
|
|
|
+ }
|
|
|
+ this.showDeptPicker = false
|
|
|
+ if (this.pageTitle === '客户资产') {
|
|
|
+ this.getClientIndicators() // 客户资产-总数据
|
|
|
+ this.getTrend() // 客户资产-统计趋势图
|
|
|
+ this.stepStatistic() // 客户资产-客群包分布
|
|
|
+ this.getIntentRank() // 意向车型标签排名
|
|
|
+ this.getBuyRank() // 已购车型标签排名
|
|
|
+ } else if (this.pageTitle === '聊天分析') {
|
|
|
+ this.handlePage(2)
|
|
|
+ } else if (this.pageTitle === '员工监测') {
|
|
|
+ this.handlePage(3)
|
|
|
+ } else if (this.pageTitle === '运营任务') {
|
|
|
+ this.handlePage(4)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handlePage(index) {
|
|
|
+ switch (index) {
|
|
|
+ case 1:
|
|
|
+ this.pageTitle = '客户资产'
|
|
|
+ this.initialization()
|
|
|
+ break
|
|
|
+ case 2:
|
|
|
+ this.pageTitle = '聊天分析'
|
|
|
+ this.getChatIndicators() // 聊天分析 - 总数据
|
|
|
+ this.getWordCloudMap() // 聊天分析 - 词云图
|
|
|
+ break
|
|
|
+ case 3:
|
|
|
+ this.pageTitle = '员工监测'
|
|
|
+ this.getSaleIndicators() // 员工监测 - 销售进程
|
|
|
+ this.getSaleRank() // 员工监测 - 销售统计排名
|
|
|
+ this.getTimeOutTrendChart() // 员工监测 - 聊天超时监测
|
|
|
+ this.getChatRank() // 员工监测 - 聊天统计排名
|
|
|
+ break
|
|
|
+ case 4:
|
|
|
+ this.pageTitle = '运营任务'
|
|
|
+ this.getOutletCount() // 运营任务 - 总数据
|
|
|
+ this.getTaskCompleteChart() // 运营任务 - 任务完成率
|
|
|
+ this.getOpInteractChart() // 运营任务 - 互动客户数
|
|
|
+ this.getContentRank() // 运营任务 - 素材排行榜
|
|
|
+ break
|
|
|
+ }
|
|
|
+ this.showPopup = false
|
|
|
+ },
|
|
|
+ // 客户资产-总数据
|
|
|
+ getClientIndicators() {
|
|
|
+ this.clientIndicators = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/clientIndicators`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : []
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.clientIndicators = data.reverse() || []
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.funnelDraw()
|
|
|
+ })
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 客户资产-总数据(梯形图)
|
|
|
+ funnelDraw() {
|
|
|
+ let clientIndicators = this.clientIndicators
|
|
|
+ let funnelChart = echarts.getInstanceByDom(document.getElementById('funnelChart'))
|
|
|
+ if (funnelChart == null) {
|
|
|
+ funnelChart = echarts.init(document.getElementById('funnelChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ funnelChart.resize()
|
|
|
+ })
|
|
|
+ funnelChart.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ formatter(param) {
|
|
|
+ let label = ''
|
|
|
+ clientIndicators.forEach(item => {
|
|
|
+ if (item.name === param.data.name) {
|
|
|
+ label = item.value
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return param.data.name + ':' + label
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'funnel',
|
|
|
+ min: 0,
|
|
|
+ max: 100,
|
|
|
+ width: '50%',
|
|
|
+ minSize: '0%', //漏斗最小值的宽度
|
|
|
+ maxSize: '100%', //漏斗最大值的宽度
|
|
|
+ left: '0%',
|
|
|
+ right: '8%',
|
|
|
+ top: '8%',
|
|
|
+ bottom: '2%',
|
|
|
+ gap: 2,
|
|
|
+ label: {
|
|
|
+ show: false,
|
|
|
+ position: 'inside',
|
|
|
+ color: '#fff',
|
|
|
+ },
|
|
|
+ data: clientIndicators.map((item, index) => {
|
|
|
+ return {
|
|
|
+ value: 40 + (index + 1) * 10,
|
|
|
+ name: item.name,
|
|
|
+ itemStyle: {
|
|
|
+ color: `hsl(215, 100%, ${54 + index * 8}%)`
|
|
|
+ },
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'funnel',
|
|
|
+ label: {
|
|
|
+ position: 'right',
|
|
|
+ lineHeight: 20,
|
|
|
+ padding: [0, 0, 0, 10],
|
|
|
+ formatter: function (param) {
|
|
|
+ let label = ''
|
|
|
+ let percent = ''
|
|
|
+ let showPercent = true; // 默认显示占比
|
|
|
+ clientIndicators.forEach(item => {
|
|
|
+ if (item.name === param.data.name) {
|
|
|
+ label = item.value
|
|
|
+ percent = item.percent
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 特殊处理长文本换行
|
|
|
+ const secondLineText = label
|
|
|
+ ? `${label}人`
|
|
|
+ : (['到店客户', '成交客户'].includes(param.data.name)
|
|
|
+ ? '待ONE-ID\n数据打通' // 手动插入换行符
|
|
|
+ : '');
|
|
|
+ // 关键修改:当显示特殊文本时隐藏占比行
|
|
|
+ if (['到店客户', '成交客户'].includes(param.data.name) && !label) {
|
|
|
+ showPercent = false;
|
|
|
+ }
|
|
|
+ const lines = [];
|
|
|
+ lines.push(`{firstLine|${param.data.name}:}{secondLine|${secondLineText}}`);
|
|
|
+
|
|
|
+ // 只有需要显示占比时才添加第三行
|
|
|
+ if (showPercent) {
|
|
|
+ lines.push(`{thirdLine|占比:${percent ? percent + '%' : ''}}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ return lines.join('\n');
|
|
|
+ },
|
|
|
+ // 新增 rich 样式定义
|
|
|
+ rich: {
|
|
|
+ firstLine: {
|
|
|
+ color: '#899EB2', // 第一行颜色
|
|
|
+ fontSize: 12, // 第一行字号
|
|
|
+ lineHeight: 20 // 保持与外层 lineHeight 一致
|
|
|
+ },
|
|
|
+ secondLine: {
|
|
|
+ color: '#1677FF',
|
|
|
+ fontWeight: 'bold',
|
|
|
+ fontSize: 14,
|
|
|
+ lineHeight: 20,
|
|
|
+ width: 150, // 关键:限制宽度触发自动换行
|
|
|
+ overflow: 'break', // 允许文本换行
|
|
|
+ },
|
|
|
+ thirdLine: {
|
|
|
+ color: '#1677FF', // 第二行颜色(示例用红色)
|
|
|
+ fontSize: 10, // 第二行字号
|
|
|
+ lineHeight: 10, // 保持与外层 lineHeight 一致
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: true,
|
|
|
+ length: 40, // label拉线的长度根据自己的场景进行设置即可
|
|
|
+ lineStyle: {
|
|
|
+ width: 1,
|
|
|
+ type: 'solid'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ min: 0,
|
|
|
+ max: 100,
|
|
|
+ minSize: '0%',
|
|
|
+ maxSize: 0,
|
|
|
+ left: '-20%',
|
|
|
+ right: '8%',
|
|
|
+ top: '10%',
|
|
|
+ bottom: '2%',
|
|
|
+ z: 1,
|
|
|
+ gap: 2,
|
|
|
+ data: clientIndicators.map((item, index) => {
|
|
|
+ return {
|
|
|
+ value: 40 + (index + 1) * 10,
|
|
|
+ name: item.name,
|
|
|
+ itemStyle: {
|
|
|
+ color: `hsl(215, 100%, ${54 + index * 8}%)`
|
|
|
+ },
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 切换日期范围
|
|
|
+ handleChangeDate(date) {
|
|
|
+ this.pageStartTime = date[0]
|
|
|
+ this.pageEndTime = date[1]
|
|
|
+ this.pageDate = date
|
|
|
+ if (this.pageTitle === '客户资产') {
|
|
|
+ this.getTrend() // 客户资产-统计趋势图
|
|
|
+ } else if (this.pageTitle === '聊天分析') {
|
|
|
+ this.handlePage(2)
|
|
|
+ } else if (this.pageTitle === '员工监测') {
|
|
|
+ this.handlePage(3)
|
|
|
+ } else if (this.pageTitle === '运营任务') {
|
|
|
+ this.handlePage(4)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 客户资产-统计趋势图
|
|
|
+ getTrend() {
|
|
|
+ this.lineDate = []
|
|
|
+ this.saleAdd = []
|
|
|
+ this.serveAdd = []
|
|
|
+ this.interactClient = []
|
|
|
+ this.formClient = []
|
|
|
+ this.storeClient = []
|
|
|
+ this.dealClient = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/trend`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ if (data && data.length > 0) {
|
|
|
+ data.forEach(item => {
|
|
|
+ this.lineDate.push(item.time)
|
|
|
+ this.saleAdd.push(item.saleAdd)
|
|
|
+ this.serveAdd.push(item.serveAdd)
|
|
|
+ this.interactClient.push(item.interactClient)
|
|
|
+ this.formClient.push(item.formClient)
|
|
|
+ this.storeClient.push(item.storeClient)
|
|
|
+ this.dealClient.push(item.dealClient)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.passValue()
|
|
|
+ })
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 切换5个模块(总客户数、互动客户数、留资/报名客户数、邀约到店客户数、成交客户数)
|
|
|
+ handleClickItem(index) {
|
|
|
+ this.index = index
|
|
|
+ this.passValue()
|
|
|
+ },
|
|
|
+ // 切换三个图表(总客户数、一客一群、销售顾问+服务顾问)
|
|
|
+ passValue() {
|
|
|
+ if (this.index === 1) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.adviserChart()
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.labelChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 互动客户数、留资/报名客户数、邀约到店客户数、成交客户数(趋势图)
|
|
|
+ labelChart() {
|
|
|
+ let labelChart = echarts.getInstanceByDom(document.getElementById('labelChart'))
|
|
|
+ if (labelChart == null) {
|
|
|
+ labelChart = echarts.init(document.getElementById('labelChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ labelChart.resize()
|
|
|
+ })
|
|
|
+ let dataText = ''
|
|
|
+ let labelData = []
|
|
|
+ if (this.index === 2) {
|
|
|
+ labelData = this.interactClient
|
|
|
+ dataText = '互动客户数'
|
|
|
+ } else if (this.index === 3) {
|
|
|
+ labelData = this.formClient
|
|
|
+ dataText = '留资/报名客户数'
|
|
|
+ } else if (this.index === 4) {
|
|
|
+ labelData = this.storeClient
|
|
|
+ dataText = '邀约到店客户数'
|
|
|
+ } else if (this.index === 5) {
|
|
|
+ labelData = this.dealClient
|
|
|
+ dataText = '成交客户数'
|
|
|
+ }
|
|
|
+ labelChart.setOption({
|
|
|
+ legend: {
|
|
|
+ data: [dataText],
|
|
|
+ orient: 'horizontal',
|
|
|
+ x: 'center',
|
|
|
+ y: 'top',
|
|
|
+ align: 'right',
|
|
|
+ itemWidth: 20,
|
|
|
+ itemHeight: 5,
|
|
|
+ itemGap: 20,
|
|
|
+ textStyle: {//图例文字的样式
|
|
|
+ color: '#666666', //图例文字颜色
|
|
|
+ fontSize: 10//图例文字大小
|
|
|
+ }
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow'
|
|
|
+ },
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '10%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.lineDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...labelData),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...labelData) / 5,
|
|
|
+
|
|
|
+ position: 'left',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: dataText,
|
|
|
+ type: 'bar',
|
|
|
+ stack: 'total',
|
|
|
+ color: '#1677FF ',
|
|
|
+ data: labelData,
|
|
|
+ itemStyle: {
|
|
|
+ // 设置柱形图圆角 [左上角,右上角,右下角,左下角]
|
|
|
+ borderRadius: [5, 5, 0, 0]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 销售顾问+服务顾问(趋势图)
|
|
|
+ adviserChart() {
|
|
|
+ let adviserChart = echarts.getInstanceByDom(document.getElementById('adviserChart'))
|
|
|
+ if (adviserChart == null) {
|
|
|
+ adviserChart = echarts.init(document.getElementById('adviserChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ adviserChart.resize()
|
|
|
+ })
|
|
|
+ adviserChart.setOption({
|
|
|
+ legend: {
|
|
|
+ show: true,
|
|
|
+ data: ['销售', '服务'],
|
|
|
+ orient: 'horizontal',
|
|
|
+ x: 'center',
|
|
|
+ y: 'top',
|
|
|
+ align: 'right',
|
|
|
+ itemWidth: 20,
|
|
|
+ itemHeight: 5,
|
|
|
+ itemGap: 20,
|
|
|
+ textStyle: {//图例文字的样式
|
|
|
+ color: '#666666', //图例文字颜色
|
|
|
+ fontSize: 10,//图例文字大小
|
|
|
+ }
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow'
|
|
|
+ },
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '10%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: '#666666',
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.lineDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.saleAdd, ...this.serveAdd) * 2,
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.saleAdd, ...this.serveAdd) * 2 / 5,
|
|
|
+
|
|
|
+ position: 'left',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: '#222222',
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '销售',
|
|
|
+ type: 'bar',
|
|
|
+ stack: 'total',
|
|
|
+ color: '#1677FF',
|
|
|
+ data: this.saleAdd,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '服务',
|
|
|
+ type: 'bar',
|
|
|
+ stack: 'total',
|
|
|
+ color: '#5CE56E ',
|
|
|
+ data: this.serveAdd,
|
|
|
+ itemStyle: {
|
|
|
+ // 设置柱形图圆角 [左上角,右上角,右下角,左下角]
|
|
|
+ borderRadius: [5, 5, 0, 0]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 切换车型(客户资产-客群包统计)
|
|
|
+ handleClickCar(item, index) {
|
|
|
+ this.carIndex = index
|
|
|
+ this.carStepData = []
|
|
|
+ this.carStepData.push(this.tableList.find(ele => ele.carModel === item.carModel))
|
|
|
+ },
|
|
|
+ // 客户资产-客群包统计数据
|
|
|
+ stepStatistic() {
|
|
|
+ this.tableList = []
|
|
|
+ this.carStepData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/stepStatistic`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.tableList = data || []
|
|
|
+ if (this.tableList.length > 0) {
|
|
|
+ this.carStepData.push(this.tableList[0])
|
|
|
+ }
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 意向车型标签排名
|
|
|
+ getIntentRank() {
|
|
|
+ this.intentRankData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/intentRank`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.intentRankData = data || []
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.intentRankChart()
|
|
|
+ })
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ intentRankChart() {
|
|
|
+ let intentRankData = this.intentRankData.sort((a, b) => a.clientNum - b.clientNum)
|
|
|
+ let rankChart = echarts.getInstanceByDom(document.getElementById('intentRankChart'))
|
|
|
+ if (rankChart == null) {
|
|
|
+ rankChart = echarts.init(document.getElementById('intentRankChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ rankChart.resize({ height: this.intentRankData.length * 50 + 20 })
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ rankChart.resize()
|
|
|
+ })
|
|
|
+ rankChart.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ formatter: '{b}: {c}'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ left: 'center',
|
|
|
+ icon: 'circle', //小圆点
|
|
|
+ itemWidth: 10,
|
|
|
+ itemHeight: 10,
|
|
|
+ itemGap: 10, //间隔
|
|
|
+ bottom: '10%',
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ bottom: "0",
|
|
|
+ top: "0",
|
|
|
+ left: "0",
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'value',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: '#666666',
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed' // 设置为虚线
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ formatter: function (value) {
|
|
|
+ return value.length > 4 ? value.substring(0, 4) + '...' : value
|
|
|
+ },
|
|
|
+ showTooltip: true,
|
|
|
+ },
|
|
|
+ data: this.intentRankData.map(item => {
|
|
|
+ return item.tagName
|
|
|
+ }) || [],
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: 24,
|
|
|
+ barGap: 12,
|
|
|
+ itemStyle: {
|
|
|
+ color: function (p) {
|
|
|
+ // 亮度随索引递增实现渐变
|
|
|
+ const lightness = 94 - p.dataIndex * 8;
|
|
|
+ return `hsl(127.9, 72.5%, ${Math.min(100, lightness)}%)`;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: this.intentRankData.map(item => {
|
|
|
+ return item.clientNum
|
|
|
+ }) || []
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 已购车型标签排名
|
|
|
+ getBuyRank() {
|
|
|
+ this.buyRankData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/buyRank`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.buyRankData = data || []
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.buyRankChart()
|
|
|
+ })
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ buyRankChart() {
|
|
|
+ let buyRankData = this.buyRankData.sort((a, b) => a.clientNum - b.clientNum)
|
|
|
+ let rankChart = echarts.getInstanceByDom(document.getElementById('buyRankChart'))
|
|
|
+ if (rankChart == null) {
|
|
|
+ rankChart = echarts.init(document.getElementById('buyRankChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ rankChart.resize({ height: this.buyRankData.length * 50 + 20 })
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ rankChart.resize()
|
|
|
+ })
|
|
|
+ rankChart.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ formatter: '{b}: {c}'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ left: 'center',
|
|
|
+ icon: 'circle', //小圆点
|
|
|
+ itemWidth: 10,
|
|
|
+ itemHeight: 10,
|
|
|
+ itemGap: 10, //间隔
|
|
|
+ bottom: '10%',
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ bottom: "0",
|
|
|
+ top: "0",
|
|
|
+ left: "0",
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'value',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: '#666666',
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed' // 设置为虚线
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ formatter: function (value) {
|
|
|
+ return value.length > 4 ? value.substring(0, 4) + '...' : value
|
|
|
+ },
|
|
|
+ showTooltip: true,
|
|
|
+ },
|
|
|
+ data: this.buyRankData.map(item => {
|
|
|
+ return item.tagName
|
|
|
+ }) || [],
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: 24,
|
|
|
+ barGap: 12,
|
|
|
+ itemStyle: {
|
|
|
+ color: function (p) {
|
|
|
+ // 亮度随索引递增实现渐变
|
|
|
+ const lightness = 87 - p.dataIndex * 8;
|
|
|
+ return `hsl(215, 100%, ${Math.min(100, lightness)}%)`;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: this.buyRankData.map(item => {
|
|
|
+ return item.clientNum
|
|
|
+ }) || []
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 聊天分析 - 总数据
|
|
|
+ getChatIndicators() {
|
|
|
+ this.chatIndicators = {
|
|
|
+ dayList: [], // 聊天分析-日数据
|
|
|
+ opinion: {},
|
|
|
+ total: {
|
|
|
+ privateChat: 0,
|
|
|
+ privateMsgNum: 0,
|
|
|
+ groupMsgNum: 0,
|
|
|
+ proactiveServe: 0,
|
|
|
+ clientReply: 0,
|
|
|
+ clientReplyPercent: 0,
|
|
|
+ proactiveConsult: 0,
|
|
|
+ memberReply: 0,
|
|
|
+ avgReplyDuration: 0,
|
|
|
+
|
|
|
+ },
|
|
|
+ yda: {
|
|
|
+ privateChat: 0,
|
|
|
+ privateMsgNum: 0,
|
|
|
+ groupMsgNum: 0,
|
|
|
+ proactiveServe: 0,
|
|
|
+ clientReply: 0,
|
|
|
+ clientReplyPercent: 0,
|
|
|
+ proactiveConsult: 0,
|
|
|
+ memberReply: 0,
|
|
|
+ avgReplyDuration: 0,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ this.interactDate = []
|
|
|
+ this.privateChat = []
|
|
|
+ this.privateMsgNum = []
|
|
|
+ this.groupMsgNum = []
|
|
|
+ this.proactiveServe = []
|
|
|
+ this.clientReply = []
|
|
|
+ this.clientReplyPercent = []
|
|
|
+ this.proactiveConsult = []
|
|
|
+ this.memberReply = []
|
|
|
+ this.avgReplyDuration = []
|
|
|
+ this.totalMsg = []
|
|
|
+ this.privateMsg = []
|
|
|
+ this.groupMsg = []
|
|
|
+ this.maxValue = null
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/chatIndicators`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.chatIndicators = {
|
|
|
+ dayList: data.dayList || [], // 聊天分析-日数据
|
|
|
+ opinion: data.opinion ? data.opinion : {
|
|
|
+ negativeGroup: 0,
|
|
|
+ positiveGroup: 0,
|
|
|
+ neutralGroup: 0,
|
|
|
+ negativePrivate: 0,
|
|
|
+ positivePrivate: 0,
|
|
|
+ neutralPrivate: 0,
|
|
|
+ negativeTotal: 0,
|
|
|
+ positiveTotal: 0,
|
|
|
+ neutralTotal: 0,
|
|
|
+ },
|
|
|
+ total: data.total ? data.total : {
|
|
|
+ privateChat: 0,
|
|
|
+ privateMsgNum: 0,
|
|
|
+ groupMsgNum: 0,
|
|
|
+ proactiveServe: 0,
|
|
|
+ clientReply: 0,
|
|
|
+ clientReplyPercent: 0,
|
|
|
+ proactiveConsult: 0,
|
|
|
+ memberReply: 0,
|
|
|
+ avgReplyDuration: 0,
|
|
|
+ },
|
|
|
+ yda: data.yda ? data.yda : {
|
|
|
+ privateChat: 0,
|
|
|
+ privateMsgNum: 0,
|
|
|
+ groupMsgNum: 0,
|
|
|
+ proactiveServe: 0,
|
|
|
+ clientReply: 0,
|
|
|
+ clientReplyPercent: 0,
|
|
|
+ proactiveConsult: 0,
|
|
|
+ memberReply: 0,
|
|
|
+ avgReplyDuration: 0,
|
|
|
+ }, // 昨日数据
|
|
|
+ }
|
|
|
+
|
|
|
+ this.interactDate = []
|
|
|
+ this.privateChat = []
|
|
|
+ this.privateMsgNum = []
|
|
|
+ this.groupMsgNum = []
|
|
|
+ this.proactiveServe = []
|
|
|
+ this.clientReply = []
|
|
|
+ this.clientReplyPercent = []
|
|
|
+ this.proactiveConsult = []
|
|
|
+ this.memberReply = []
|
|
|
+ this.avgReplyDuration = []
|
|
|
+
|
|
|
+ if (data.dayList && data.dayList.length > 0) {
|
|
|
+ data.dayList.forEach(item => {
|
|
|
+ this.interactDate.push(item.time)
|
|
|
+ this.privateChat.push(item.privateChat)
|
|
|
+ this.privateMsgNum.push(item.privateMsgNum)
|
|
|
+ this.groupMsgNum.push(item.groupMsgNum)
|
|
|
+ this.proactiveServe.push(item.proactiveServe)
|
|
|
+ this.clientReply.push(item.clientReply)
|
|
|
+ this.clientReplyPercent.push(item.clientReplyPercent)
|
|
|
+ this.proactiveConsult.push(item.proactiveConsult)
|
|
|
+ this.memberReply.push(item.memberReply)
|
|
|
+ this.avgReplyDuration.push(item.avgReplyDuration)
|
|
|
+ })
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.interactChart()
|
|
|
+ this.staffChart()
|
|
|
+ this.clientChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ this.totalMsg = []
|
|
|
+ this.privateMsg = []
|
|
|
+ this.groupMsg = []
|
|
|
+ this.maxValue = null
|
|
|
+ if (data.opinion) {
|
|
|
+ this.totalMsg = [data.opinion.negativeTotal, data.opinion.positiveTotal, data.opinion.neutralTotal]
|
|
|
+ this.privateMsg = [data.opinion.positivePrivate, data.opinion.negativePrivate, data.opinion.neutralPrivate]
|
|
|
+ this.groupMsg = [data.opinion.positiveGroup, data.opinion.negativeGroup, data.opinion.neutralGroup]
|
|
|
+ this.maxValue = Math.max.apply(null, [...this.totalMsg, ...this.privateMsg, ...this.groupMsg])
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.opinionChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 聊天分析-总数据趋势图数据
|
|
|
+ interactChart() {
|
|
|
+ let interactChart = echarts.getInstanceByDom(document.getElementById('interactChart'))
|
|
|
+ if (interactChart == null) {
|
|
|
+ interactChart = echarts.init(document.getElementById('interactChart'))
|
|
|
+ }
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ interactChart.resize()
|
|
|
+ })
|
|
|
+ interactChart.setOption({
|
|
|
+ legend: {
|
|
|
+ x: 'center',
|
|
|
+ y: 10,
|
|
|
+ align: 'right',
|
|
|
+ itemWidth: 20,
|
|
|
+ itemHeight: 5,
|
|
|
+ itemGap: 20,
|
|
|
+ textStyle: {//图例文字的样式
|
|
|
+ color: '#666666', //图例文字颜色
|
|
|
+ fontSize: 10//图例文字大小
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ name: "私聊客户数",
|
|
|
+ // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
|
|
|
+ itemStyle: {
|
|
|
+ color: "#fff",
|
|
|
+ borderColor: '#1677FF',
|
|
|
+ borderWidth: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "私聊消息数",
|
|
|
+ // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
|
|
|
+ itemStyle: {
|
|
|
+ color: "#fff",
|
|
|
+ borderColor: '#5CE56E',
|
|
|
+ borderWidth: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "群消息数",
|
|
|
+ itemStyle: {
|
|
|
+ width: 20,
|
|
|
+ height: 5,
|
|
|
+ color: "#E6F0FF",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis'
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '20%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.interactDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.privateMsgNum, ...this.privateChat, ...this.groupMsgNum),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.privateMsgNum, ...this.privateChat, ...this.groupMsgNum) / 5,
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '私聊客户数',
|
|
|
+ type: 'line',
|
|
|
+ color: '#1677FF',
|
|
|
+ data: this.privateChat,
|
|
|
+ symbol: 'none', //去掉折线图中的节点
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '私聊消息数',
|
|
|
+ type: 'line',
|
|
|
+ color: '#5CE56E',
|
|
|
+ data: this.privateMsgNum,
|
|
|
+ symbol: 'none', //去掉折线图中的节点
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '群消息数',
|
|
|
+ type: 'bar', //形状为柱状图
|
|
|
+ data: this.groupMsgNum,
|
|
|
+ itemStyle: {
|
|
|
+ color: ' #E6F0FF',
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ color: 'rgb(0, 157, 255)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 聊天分析-员工服务趋势图数据
|
|
|
+ staffChart() {
|
|
|
+ let staffChart = echarts.getInstanceByDom(document.getElementById('staffChart'))
|
|
|
+ if (staffChart == null) {
|
|
|
+ staffChart = echarts.init(document.getElementById('staffChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ staffChart.resize()
|
|
|
+ })
|
|
|
+ staffChart.setOption({
|
|
|
+ legend: {
|
|
|
+ orient: 'horizontal',
|
|
|
+ x: 'center',
|
|
|
+ y: 10,
|
|
|
+ align: 'right',
|
|
|
+ itemWidth: 20,
|
|
|
+ itemHeight: 5,
|
|
|
+ itemGap: 20,
|
|
|
+ textStyle: {//图例文字的样式
|
|
|
+ color: '#666666', //图例文字颜色
|
|
|
+ fontSize: 10//图例文字大小
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ name: "主动服务会话数",
|
|
|
+ // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
|
|
|
+ itemStyle: {
|
|
|
+ width: 20,
|
|
|
+ height: 5,
|
|
|
+ color: "#1677FF",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "客户回复会话数",
|
|
|
+ // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
|
|
|
+ itemStyle: {
|
|
|
+ width: 20,
|
|
|
+ height: 5,
|
|
|
+ color: "#5CE56E",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "客户回复率",
|
|
|
+ itemStyle: {
|
|
|
+ color: "#fff",
|
|
|
+ borderColor: '#FFA64E',
|
|
|
+ borderWidth: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis'
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '20%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.interactDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.proactiveServe, ...this.clientReply),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.proactiveServe, ...this.clientReply) / 5,
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ {// 第二种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.clientReplyPercent),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.clientReplyPercent) / 5,
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) + ' %'; //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '主动服务会话数',
|
|
|
+ type: 'bar', //形状为柱状图
|
|
|
+ data: this.proactiveServe,
|
|
|
+ itemStyle: {
|
|
|
+ color: ' #1677FF',
|
|
|
+ borderRadius: [5, 5, 0, 0]
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ color: 'rgb(0, 157, 255)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '客户回复会话数',
|
|
|
+ type: 'bar', //形状为柱状图
|
|
|
+ data: this.clientReply,
|
|
|
+ itemStyle: {
|
|
|
+ color: ' #5CE56E',
|
|
|
+ borderRadius: [5, 5, 0, 0]
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ color: 'rgb(0, 157, 255)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '客户回复率',
|
|
|
+ type: 'line',
|
|
|
+ color: '#FFA64E',
|
|
|
+ symbol: 'none',
|
|
|
+ yAxisIndex: 1,
|
|
|
+ data: this.clientReplyPercent,
|
|
|
+ tooltip: {
|
|
|
+ valueFormatter: function (value) {
|
|
|
+ return value ? value + ' %' : ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 聊天分析-客户咨询趋势图数据
|
|
|
+ clientChart() {
|
|
|
+ let clientChart = echarts.getInstanceByDom(document.getElementById('clientChart'))
|
|
|
+ if (clientChart == null) {
|
|
|
+ clientChart = echarts.init(document.getElementById('clientChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ clientChart.resize()
|
|
|
+ })
|
|
|
+ clientChart.setOption({
|
|
|
+ legend: {
|
|
|
+ orient: 'horizontal',
|
|
|
+ x: 'center',
|
|
|
+ y: 10,
|
|
|
+ align: 'right',
|
|
|
+ itemWidth: 16,
|
|
|
+ itemHeight: 4,
|
|
|
+ itemGap: 10,
|
|
|
+ textStyle: {//图例文字的样式
|
|
|
+ color: '#666666', //图例文字颜色
|
|
|
+ fontSize: 10//图例文字大小
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ name: "主动咨询会话数",
|
|
|
+ // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
|
|
|
+ itemStyle: {
|
|
|
+ width: 20,
|
|
|
+ height: 5,
|
|
|
+ color: "#1677FF",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "员工回复会话数",
|
|
|
+ // 单独设置图例空心圆,通过设置边框颜色+背景颜色白色实现空心圆
|
|
|
+ itemStyle: {
|
|
|
+ width: 20,
|
|
|
+ height: 5,
|
|
|
+ color: "#5CE56E",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "员工平均响应时长",
|
|
|
+ itemStyle: {
|
|
|
+ color: "#fff",
|
|
|
+ borderColor: '#FFA64E',
|
|
|
+ borderWidth: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis'
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '20%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.interactDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.proactiveConsult, ...this.memberReply),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.proactiveConsult, ...this.memberReply) / 5,
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ {// 第二种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.avgReplyDuration),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.avgReplyDuration) / 5,
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) + ' s'; //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '主动咨询会话数',
|
|
|
+ type: 'bar', //形状为柱状图
|
|
|
+ data: this.proactiveConsult,
|
|
|
+ itemStyle: {
|
|
|
+ color: ' #1677FF',
|
|
|
+ borderRadius: [5, 5, 0, 0]
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ color: 'rgb(0, 157, 255)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '员工回复会话数',
|
|
|
+ type: 'bar', //形状为柱状图
|
|
|
+ data: this.memberReply,
|
|
|
+ itemStyle: {
|
|
|
+ color: ' #5CE56E',
|
|
|
+ borderRadius: [5, 5, 0, 0]
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ color: 'rgb(0, 157, 255)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '员工平均响应时长',
|
|
|
+ type: 'line',
|
|
|
+ color: '#FFA64E',
|
|
|
+ symbol: 'none',
|
|
|
+ yAxisIndex: 1,
|
|
|
+ tooltip: {
|
|
|
+ valueFormatter: function (value) {
|
|
|
+ return value ? value.toFixed(0) + ' s' : ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: this.avgReplyDuration,
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 聊天分析-消息舆情分析
|
|
|
+ opinionChart() {
|
|
|
+ let opinionChart = echarts.getInstanceByDom(document.getElementById('opinionChart'))
|
|
|
+ if (opinionChart == null) {
|
|
|
+ opinionChart = echarts.init(document.getElementById('opinionChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ opinionChart.resize()
|
|
|
+ })
|
|
|
+ opinionChart.setOption({
|
|
|
+ legend: {
|
|
|
+ orient: 'horizontal',
|
|
|
+ align: 'right',
|
|
|
+ itemWidth: 20,
|
|
|
+ itemHeight: 4,
|
|
|
+ itemGap: 20,
|
|
|
+ textStyle: {//图例文字的样式
|
|
|
+ color: '#666666', //图例文字颜色
|
|
|
+ fontSize: 10//图例文字大小
|
|
|
+ }
|
|
|
+ },
|
|
|
+ radar: {
|
|
|
+ indicator: [
|
|
|
+ { name: '负面', max: this.maxValue },
|
|
|
+ { name: '中性', max: this.maxValue },
|
|
|
+ { name: '正面', max: this.maxValue },
|
|
|
+ ],
|
|
|
+ radius: 150,
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'radar',
|
|
|
+ color: '#1677FF',
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ value: this.totalMsg,
|
|
|
+ name: '全部消息',
|
|
|
+ itemStyle: {
|
|
|
+ color: '#1677FF',
|
|
|
+ lineStyle: {
|
|
|
+ color: '#1677FF',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: this.privateMsg,
|
|
|
+ name: '单聊消息',
|
|
|
+ itemStyle: {
|
|
|
+ color: '#5CE56E',
|
|
|
+ lineStyle: {
|
|
|
+ color: '#5CE56E',
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: this.groupMsg,
|
|
|
+ name: '群聊消息',
|
|
|
+ itemStyle: {
|
|
|
+ color: '#FFA64E',
|
|
|
+ lineStyle: {
|
|
|
+ color: '#FFA64E',
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 聊天分析-词云图
|
|
|
+ getWordCloudMap() {
|
|
|
+ this.wordCloudMap = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/wordCloudMap`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.wordCloudMap = data || []
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.wordCloudChart()
|
|
|
+ })
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ wordCloudChart() {
|
|
|
+ let wordCloudChart = echarts.getInstanceByDom(document.getElementById('wordCloudChart'))
|
|
|
+ if (wordCloudChart == null) {
|
|
|
+ wordCloudChart = echarts.init(document.getElementById('wordCloudChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ wordCloudChart.resize()
|
|
|
+ })
|
|
|
+ wordCloudChart.setOption({
|
|
|
+ series: [{
|
|
|
+ type: 'wordCloud',
|
|
|
+ //maskImage: maskImage,
|
|
|
+ sizeRange: [12, 24],
|
|
|
+ rotationRange: [0, 0],
|
|
|
+ rotationStep: 45,
|
|
|
+ gridSize: 8,
|
|
|
+ shape: 'pentagon',
|
|
|
+ width: '100%',
|
|
|
+ height: '100%',
|
|
|
+ textStyle: {
|
|
|
+ fontFamily: '微软雅黑',
|
|
|
+ color: (v) => {
|
|
|
+ switch (true) {
|
|
|
+ case v.dataIndex <= 5:
|
|
|
+ return '#1677FF'
|
|
|
+ case 5 < v.dataIndex && v.dataIndex <= 10:
|
|
|
+ return 'rgba(22, 119, 255, 0.6)'
|
|
|
+ default:
|
|
|
+ return 'rgba(22, 119, 255, 0.4)'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: this.wordCloudMap,
|
|
|
+ }]
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 销售进程客户数
|
|
|
+ getSaleIndicators() {
|
|
|
+ this.saleIndicators = []
|
|
|
+ this.clientStepDate = []
|
|
|
+ this.clientStepNum = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/saleIndicators`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.saleIndicators = data || []
|
|
|
+ if (data && data.length) {
|
|
|
+ data[0].dayList.forEach(item => {
|
|
|
+ this.clientStepDate.push(item.time)
|
|
|
+ this.clientStepNum.push(item.clientNum)
|
|
|
+ })
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.clientStepChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleClickClient(item, index) {
|
|
|
+ this.clientIndex = index
|
|
|
+ this.clientStepDate = []
|
|
|
+ this.clientStepNum = []
|
|
|
+
|
|
|
+ if (item.dayList && item.dayList.length) {
|
|
|
+ this.clientStepDate = item.dayList.map(item => item.time)
|
|
|
+ this.clientStepNum = item.dayList.map(item => item.clientNum)
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.clientStepChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ clientStepChart() {
|
|
|
+ let clientStepChart = echarts.getInstanceByDom(document.getElementById('clientStepChart'))
|
|
|
+ if (clientStepChart == null) {
|
|
|
+ clientStepChart = echarts.init(document.getElementById('clientStepChart'))
|
|
|
+ }
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ clientStepChart.resize()
|
|
|
+ })
|
|
|
+ let text = this.saleIndicators[this.clientIndex].processName
|
|
|
+ clientStepChart.setOption({
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ formatter: function (params) {
|
|
|
+ return params[0].name + '<br>'
|
|
|
+ + text + ': ' + params[0].value
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '10%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.clientStepDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.clientStepNum),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.clientStepNum) / 5,
|
|
|
+ position: 'left',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ color: '#1677FF',
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: 'rgba(22,119,255,0.43)' },
|
|
|
+ { offset: 1, color: 'rgba(22,119,255,0)' }
|
|
|
+ ])
|
|
|
+ }, //填充区域样式
|
|
|
+ data: this.clientStepNum,
|
|
|
+ symbol: 'none', //去掉折线图中的节点
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 销售统计排名
|
|
|
+ getSaleRank() {
|
|
|
+ this.saleRankData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/saleRank`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.saleRankData = data || []
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 聊天超时监测
|
|
|
+ getTimeOutTrendChart() {
|
|
|
+ this.timeOutDate = []
|
|
|
+ this.timeoutMember = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/timeOutTrend`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ if (data && data.length) {
|
|
|
+ data.forEach(item => {
|
|
|
+ this.timeOutDate.push(item.time)
|
|
|
+ this.timeoutMember.push(item.timeoutMember)
|
|
|
+ })
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.timeOutTrendChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ timeOutTrendChart() {
|
|
|
+ let timeOutTrendChart = echarts.getInstanceByDom(document.getElementById('timeOutTrendChart'))
|
|
|
+ if (timeOutTrendChart == null) {
|
|
|
+ timeOutTrendChart = echarts.init(document.getElementById('timeOutTrendChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ timeOutTrendChart.resize()
|
|
|
+ })
|
|
|
+ timeOutTrendChart.setOption({
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ formatter: function (params) {
|
|
|
+ return params[0].name + ': ' + params[0].value
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '10%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.timeOutDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.timeoutMember),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.timeoutMember) / 5,
|
|
|
+ position: 'left',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ color: '#FF4E4E',
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: 'rgba(255, 78, 78,0.43)' },
|
|
|
+ { offset: 1, color: 'rgba(255, 78, 78,0)' }
|
|
|
+ ])
|
|
|
+ }, //填充区域样式
|
|
|
+ data: this.timeoutMember,
|
|
|
+ symbol: 'none', //去掉折线图中的节点
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ returnOutsideDate() {
|
|
|
+ this.memberStartTime = this.pageStartTime
|
|
|
+ this.memberEndTime = this.pageEndTime
|
|
|
+ if (this.pageStartTime === this.getDateTime(-1) && this.pageEndTime === this.getDateTime(-1)) {
|
|
|
+ this.timeData = '昨日'
|
|
|
+ } else if (this.pageStartTime === this.getDateTime(-7) && this.pageEndTime === this.getDateTime(-1)) {
|
|
|
+ this.timeData = '近7天'
|
|
|
+ } else if (this.pageStartTime === this.getDateTime(-30) && this.pageEndTime === this.getDateTime(-1)) {
|
|
|
+ this.timeData = '近30天'
|
|
|
+ } else {
|
|
|
+ this.timeData = '自定义'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 顾问响应统计
|
|
|
+ handleMemberReply() {
|
|
|
+ this.showMemberReply = true
|
|
|
+ this.returnOutsideDate()
|
|
|
+ this.getMemberReply()
|
|
|
+ },
|
|
|
+ getMemberReply() {
|
|
|
+ this.loading = true
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/memberReply`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.memberStartTime,
|
|
|
+ endTime: this.memberEndTime,
|
|
|
+ page: this.currentPage,
|
|
|
+ pageCount: 10,
|
|
|
+ keyword: this.keyword,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.memberReplyData = data.records || []
|
|
|
+ this.totalItems = data.total || 0
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onSelect(val) {
|
|
|
+ this.timeData = val.text
|
|
|
+ if (this.timeData === '自定义') {
|
|
|
+ this.showSelfDate = true
|
|
|
+ } else {
|
|
|
+ if (this.timeData === '昨日') {
|
|
|
+ this.memberStartTime = this.getDateTime(-1)
|
|
|
+ this.memberEndTime = this.getDateTime(-1)
|
|
|
+ } else if (this.timeData === '近7天') {
|
|
|
+ this.memberStartTime = this.getDateTime(-7)
|
|
|
+ this.memberEndTime = this.getDateTime(-1)
|
|
|
+ } else if (this.timeData === '近30天') {
|
|
|
+ this.memberStartTime = this.getDateTime(-30)
|
|
|
+ this.memberEndTime = this.getDateTime(-1)
|
|
|
+ }
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.showDoneReply) {
|
|
|
+ this.getDoneReply()
|
|
|
+ } else {
|
|
|
+ if (this.memberId) {
|
|
|
+ this.handleItemMemberReplyDetail()
|
|
|
+ } else {
|
|
|
+ this.getMemberReply()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onSelfConfirm(date) {
|
|
|
+ const [start, end] = date
|
|
|
+ if (this.formatDate(new Date()) === this.formatDate(end)) {
|
|
|
+ this.formatDate(end) = this.formatDate(start)
|
|
|
+ }
|
|
|
+ this.memberStartTime = this.formatDate(start)
|
|
|
+ this.memberEndTime = this.formatDate(end)
|
|
|
+ this.showSelfDate = false
|
|
|
+ if (this.showDoneReply) {
|
|
|
+ this.getDoneReply()
|
|
|
+ } else {
|
|
|
+ if (this.memberId) {
|
|
|
+ this.handleItemMemberReplyDetail()
|
|
|
+ } else {
|
|
|
+ this.getMemberReply()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ formatDate(date) {
|
|
|
+ return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
|
|
|
+ },
|
|
|
+ handleSearch() {
|
|
|
+ this.getMemberReply()
|
|
|
+ },
|
|
|
+ handleChangePage(val) {
|
|
|
+ this.currentPage = val
|
|
|
+ if (this.showDoneReply) {
|
|
|
+ this.getDoneReply()
|
|
|
+ } else {
|
|
|
+ this.getMemberReply()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ closeReply() {
|
|
|
+ this.currentPage = 1
|
|
|
+ this.totalItems = 0
|
|
|
+ this.keyword = ''
|
|
|
+ this.timeData = '近7天'
|
|
|
+ this.memberStartTime = this.getDateTime(-7)
|
|
|
+ this.memberEndTime = this.getDateTime(-1)
|
|
|
+ this.memberReplyData = []
|
|
|
+ this.showMemberReply = false
|
|
|
+ this.showDoneReply = false
|
|
|
+ },
|
|
|
+ handleItemMemberReply(item) {
|
|
|
+ this.showItemMemberReply = true
|
|
|
+ this.currentMemberName = item.memberName
|
|
|
+ this.memberId = item.memberId
|
|
|
+ this.currentItemPage = 1
|
|
|
+ this.itemTotalItems = 0
|
|
|
+ this.memberDetailReplyData = []
|
|
|
+ this.handleItemMemberReplyDetail(item)
|
|
|
+ },
|
|
|
+ closeItemMemberReply() {
|
|
|
+ this.showItemMemberReply = false
|
|
|
+ },
|
|
|
+ handleChangeItemPage(val) {
|
|
|
+ this.currentItemPage = val
|
|
|
+ this.handleItemMemberReplyDetail()
|
|
|
+ },
|
|
|
+ // 顾客响应统计-详情
|
|
|
+ handleItemMemberReplyDetail() {
|
|
|
+ this.loading = true
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/memberReplyDetail`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.memberStartTime,
|
|
|
+ endTime: this.memberEndTime,
|
|
|
+ page: this.currentItemPage,
|
|
|
+ pageCount: 10,
|
|
|
+ memberId: this.memberId,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.memberDetailReplyData = data.records || []
|
|
|
+ this.itemTotalItems = data.total || 0
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 顾客完成情况统计
|
|
|
+ handleDoneReply() {
|
|
|
+ this.showDoneReply = true
|
|
|
+ this.returnOutsideDate()
|
|
|
+ this.getDoneReply()
|
|
|
+ },
|
|
|
+ getDoneReply() {
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/operationMemberCnt`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.memberStartTime,
|
|
|
+ endTime: this.memberEndTime,
|
|
|
+ page: this.currentPage,
|
|
|
+ pageCount: 10,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.doneReplyData = data.records || []
|
|
|
+ this.totalItems = data.total || 0
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 聊天排行榜
|
|
|
+ getChatRank() {
|
|
|
+ this.chatRankData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/chatRank`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.chatRankData = data || []
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 运营任务-总数据
|
|
|
+ getOutletCount() {
|
|
|
+ this.outletCount = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/outletCount`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.outletCount = data || []
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 运营任务-任务完成率
|
|
|
+ getTaskCompleteChart() {
|
|
|
+ this.taskCompleteDate = []
|
|
|
+ this.taskCompletePercent = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/taskCompletePercent`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ if (data && data.length) {
|
|
|
+ data.forEach(item => {
|
|
|
+ this.taskCompleteDate.push(item.time)
|
|
|
+ this.taskCompletePercent.push(item.taskCompletePercent)
|
|
|
+ })
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.taskCompleteChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ taskCompleteChart() {
|
|
|
+ let taskCompleteChart = echarts.getInstanceByDom(document.getElementById('taskCompleteChart'))
|
|
|
+ if (taskCompleteChart == null) {
|
|
|
+ taskCompleteChart = echarts.init(document.getElementById('taskCompleteChart'))
|
|
|
+ }
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ taskCompleteChart.resize()
|
|
|
+ })
|
|
|
+ taskCompleteChart.setOption({
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ valueFormatter: function (value) {
|
|
|
+ return value ? value.toFixed(2) + ' %' : ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '10%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.taskCompleteDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.taskCompletePercent),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.taskCompletePercent) / 5,
|
|
|
+ position: 'left',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ color: '#1677FF',
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: 'rgba(22,119,255,0.43)' },
|
|
|
+ { offset: 1, color: 'rgba(22,119,255,0)' }
|
|
|
+ ])
|
|
|
+ }, //填充区域样式
|
|
|
+ data: this.taskCompletePercent,
|
|
|
+ symbol: 'none', //去掉折线图中的节点
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 运营任务 - 互动客户数
|
|
|
+ getOpInteractChart() {
|
|
|
+ this.opInteractDate = []
|
|
|
+ this.opInteractClient = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/interact`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ if (data && data.length) {
|
|
|
+ data.forEach(item => {
|
|
|
+ this.opInteractDate.push(item.time)
|
|
|
+ this.opInteractClient.push(item.interactClient)
|
|
|
+ })
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.opInteractChart()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ opInteractChart() {
|
|
|
+ let opInteractChart = echarts.getInstanceByDom(document.getElementById('opInteractChart'))
|
|
|
+ if (opInteractChart == null) {
|
|
|
+ opInteractChart = echarts.init(document.getElementById('opInteractChart'))
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ opInteractChart.resize()
|
|
|
+ })
|
|
|
+ opInteractChart.setOption({
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ formatter: function (params) {
|
|
|
+ return params[0].name + '<br>'
|
|
|
+ + '互动客户数: ' + params[0].value
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: '10%',
|
|
|
+ left: '10%',
|
|
|
+ right: '10%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#666666",
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ data: this.opInteractDate,
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {// 第一种方式
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: Math.max(...this.opInteractClient),
|
|
|
+ splitNumber: 5,
|
|
|
+ interval: Math.max(...this.opInteractClient) / 5,
|
|
|
+ position: 'left',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: "#222222",
|
|
|
+ fontSize: '8',
|
|
|
+ formatter: function (v) {
|
|
|
+ return v.toFixed(0) //0表示小数为0位,1表示1位小数,2表示2位小数
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: { //网格线
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed'//设置网格线类型 dotted:虚线 solid:实线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: { show: false },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ color: '#FFA64E',
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: 'rgba(255, 166, 78 ,0.43)' },
|
|
|
+ { offset: 1, color: 'rgba(255, 166, 78 ,0)' }
|
|
|
+ ])
|
|
|
+ }, //填充区域样式
|
|
|
+ data: this.opInteractClient,
|
|
|
+ symbol: 'none', //去掉折线图中的节点
|
|
|
+ smooth: true, //true 为平滑曲线,false为直线
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }, true)
|
|
|
+ },
|
|
|
+ // 运营任务 - 素材排行榜
|
|
|
+ getContentRank() {
|
|
|
+ this.contentRankData = []
|
|
|
+ fetch(this.httpUrl + `/scrm/v1/dw-dealer/m/contentRank`, {
|
|
|
+ method: 'post',
|
|
|
+ body: JSON.stringify({
|
|
|
+ outletId: this.outletId,
|
|
|
+ departmentIds: this.deptId ? [this.deptId] : [],
|
|
|
+ startTime: this.pageStartTime,
|
|
|
+ endTime: this.pageEndTime,
|
|
|
+ }),
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ 'token': this.token,
|
|
|
+ 'tenancyId': this.tenancyId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ return res.json()
|
|
|
+ }).then(result => {
|
|
|
+ let { data, code, msg } = result
|
|
|
+ if (code === 1) {
|
|
|
+ this.contentRankData = data.reverse() || []
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.contentRankChart()
|
|
|
+ })
|
|
|
+ } else if (code === 10001) {
|
|
|
+ this.loginOut()
|
|
|
+ } else {
|
|
|
+ vant.Toast.fail(msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ contentRankChart() {
|
|
|
+ let contentRankData = this.contentRankData.sort((a, b) => a.clientNum - b.clientNum)
|
|
|
+ let rankChart = echarts.getInstanceByDom(document.getElementById('contentRank'))
|
|
|
+ if (rankChart == null) {
|
|
|
+ rankChart = echarts.init(document.getElementById('contentRank'))
|
|
|
+ }
|
|
|
+ rankChart.resize({ height: this.contentRankData.length * 50 + 20 })
|
|
|
+ window.addEventListener('resize', function () {
|
|
|
+ rankChart.resize()
|
|
|
+ })
|
|
|
+ rankChart.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ confine: true,
|
|
|
+ extraCssText: 'max-width:200px; white-space:pre-wrap',
|
|
|
+ formatter: '{b}: {c}'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ left: 'center',
|
|
|
+ icon: 'circle', //小圆点
|
|
|
+ itemWidth: 10,
|
|
|
+ itemHeight: 10,
|
|
|
+ itemGap: 10, //间隔
|
|
|
+ bottom: '10%',
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ bottom: "0",
|
|
|
+ top: "0",
|
|
|
+ left: "0",
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'value',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: '#666666',
|
|
|
+ fontSize: '8',
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed' // 设置为虚线
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'category',
|
|
|
+ axisLabel: {
|
|
|
+ formatter: function (value) {
|
|
|
+ return value.length > 4 ? value.substring(0, 4) + '...' : value
|
|
|
+ },
|
|
|
+ showTooltip: true,
|
|
|
+ },
|
|
|
+ data: this.contentRankData.map(item => {
|
|
|
+ return item.title
|
|
|
+ }) || [],
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: 24,
|
|
|
+ barGap: 12,
|
|
|
+ itemStyle: {
|
|
|
+ color: function (p) {
|
|
|
+ // 亮度随索引递增实现渐变
|
|
|
+ const lightness = 87 - p.dataIndex * 8;
|
|
|
+ return `hsl(215, 100%, ${Math.min(100, lightness)}%)`;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: this.contentRankData.map(item => {
|
|
|
+ return item.readNum
|
|
|
+ }) || []
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 打开右上角弹窗
|
|
|
+ handleShowPopup() {
|
|
|
+ this.showPopup = true
|
|
|
+ },
|
|
|
+ // 关闭右上角弹窗
|
|
|
+ handleClosePopup() {
|
|
|
+ this.showPopup = false
|
|
|
+ this.showMer = false
|
|
|
+ },
|
|
|
+ // 切换商户
|
|
|
+ handleSelectMer(item) {
|
|
|
+ localStorage.setItem('tenancyIdValue', item.id)
|
|
|
+ localStorage.setItem('tenancyNameValue', item.name || '')
|
|
|
+ this.tenancyId = item.id
|
|
|
+ this.jxsName = item.name || ''
|
|
|
+ this.showPopup = false
|
|
|
+ this.showMer = false
|
|
|
+ this.initialization()
|
|
|
+ },
|
|
|
+ // 退出登录
|
|
|
+ handleLoginOut() {
|
|
|
+ localStorage.removeItem('tokenValue')
|
|
|
+ var currentQueryParams = window.location.search
|
|
|
+ window.location.replace('jxsLogin.html' + currentQueryParams)
|
|
|
+ },
|
|
|
+ // token过期,退出登录
|
|
|
+ loginOut() {
|
|
|
+ vant.Toast({
|
|
|
+ message: '登录信息过期,请重新登录',
|
|
|
+ })
|
|
|
+ this.handleLoginOut()
|
|
|
+ },
|
|
|
+ formatTime(seconds) {
|
|
|
+ // 处理无效输入(空值/非数字)
|
|
|
+ if (seconds == null || seconds === '' || typeof seconds !== 'number') {
|
|
|
+ return '--';
|
|
|
+ }
|
|
|
+ // 确定时间符号和绝对值
|
|
|
+ const isNegative = seconds < 0;
|
|
|
+ const absSeconds = Math.abs(seconds);
|
|
|
+ // 内部格式化函数(处理绝对值)
|
|
|
+ const format = (val, unit) => {
|
|
|
+ const num = Math.round(val);
|
|
|
+ return `${num}${unit}${num > 1 ? '' : ''}`;
|
|
|
+ };
|
|
|
+ // 根据绝对值大小转换单位
|
|
|
+ let formatted;
|
|
|
+ if (absSeconds >= 3600) {
|
|
|
+ formatted = format(absSeconds / 3600, '小时');
|
|
|
+ } else if (absSeconds >= 60) {
|
|
|
+ formatted = format(absSeconds / 60, '分钟');
|
|
|
+ } else {
|
|
|
+ formatted = format(absSeconds, '秒');
|
|
|
+ }
|
|
|
+ // 添加负号(当原始值为负时)
|
|
|
+ return isNegative ? `-${formatted}` : formatted;
|
|
|
+ },
|
|
|
+ formatNumber(num) {
|
|
|
+ const number = Number(num);
|
|
|
+
|
|
|
+ if (isNaN(number) || !isFinite(number)) {
|
|
|
+ return num;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 整数直接返回
|
|
|
+ if (Number.isInteger(number)) {
|
|
|
+ return number.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 非整数处理:先保留两位小数,再移除末尾的零
|
|
|
+ let str = number.toFixed(2);
|
|
|
+ // 正则表达式移除末尾的零(保留有效小数位)
|
|
|
+ return str.replace(/(\.[1-9]?0+)$|(\.[1-9])0+$/g, '$1$2');
|
|
|
+ },
|
|
|
+ // 日期格式处理
|
|
|
+ getDateTime(day) {
|
|
|
+ let today = new Date()
|
|
|
+ let targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day
|
|
|
+ today.setTime(targetday_milliseconds)
|
|
|
+ let tYear = today.getFullYear()
|
|
|
+ let tMonth = today.getMonth() + 1
|
|
|
+ let tDate = today.getDate()
|
|
|
+ if (tMonth < 10) {
|
|
|
+ tMonth = '0' + tMonth
|
|
|
+ }
|
|
|
+ if (tDate < 10) {
|
|
|
+ tDate = '0' + tDate
|
|
|
+ }
|
|
|
+ return tYear + '-' + tMonth + '-' + tDate
|
|
|
+ },
|
|
|
+ // 截取url中的数据
|
|
|
+ getQueryParam(paramName) {
|
|
|
+ // 获取当前URL的查询字符串部分
|
|
|
+ const queryString = window.location.search;
|
|
|
+ // 创建一个URLSearchParams对象
|
|
|
+ const urlParams = new URLSearchParams(queryString);
|
|
|
+ // 返回指定参数的值,如果不存在则返回null
|
|
|
+ return urlParams.get(paramName);
|
|
|
+ },
|
|
|
+ timeFormat(time, format = 'yyyy-MM-dd hh:mm:ss') {
|
|
|
+ if (time === undefined || time === '' || time === null) {
|
|
|
+ return '--'
|
|
|
+ } else {
|
|
|
+ const date = new Date(time)
|
|
|
+ const o = {
|
|
|
+ 'M+': date.getMonth() + 1,
|
|
|
+ 'd+': date.getDate(),
|
|
|
+ 'h+': date.getHours(),
|
|
|
+ 'm+': date.getMinutes(),
|
|
|
+ 's+': date.getSeconds(),
|
|
|
+ 'q+': Math.floor((date.getMonth() + 3) / 3),
|
|
|
+ 'S': date.getMilliseconds()
|
|
|
+ }
|
|
|
+ if (/(y+)/.test(format)) {
|
|
|
+ format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
|
|
|
+ }
|
|
|
+ for (let k in o) {
|
|
|
+ if (new RegExp('(' + k + ')').test(format)) {
|
|
|
+ format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return format
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+</script>
|
|
|
+
|
|
|
+</html>
|