| | |
| | | <Modal |
| | | v-model="showCustomerInfo" |
| | | :title="modelTitle" |
| | | width="700" |
| | | width="850" |
| | | :mask-closable="false" |
| | | > |
| | | <div class="customer-detail"> |
| | | <div class="avatar-section"> |
| | | <Avatar :src="customerInfo.face" size="large" /> |
| | | <div class="basic-info"> |
| | | <h3>{{ customerInfo.nickName || '微信用户' }}</h3> |
| | | <p>ID: {{ customerInfo.id }}</p> |
| | | <p>用户名: {{ customerInfo.username }}</p> |
| | | </div> |
| | | </div> |
| | | |
| | | <Divider /> |
| | | <!-- 主内容区 --> |
| | | <Tabs v-model="activeTab" @on-click="handleTabChange"> |
| | | <TabPane label="基础资料" name="basic"> |
| | | <div class="customer-detail"> |
| | | <div class="avatar-section"> |
| | | <Avatar :src="customerInfo.face" size="large" /> |
| | | <div class="basic-info"> |
| | | <h3>{{ customerInfo.nickName || '微信用户' }}</h3> |
| | | <p>ID: {{ customerInfo.id }}</p> |
| | | <p>用户名: {{ customerInfo.username }}</p> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="detail-grid"> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">性别:</span> |
| | | <span class="detail-value">{{ customerInfo.sex === 0 ? "女" : "男"}}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">地区:</span> |
| | | <span class="detail-value">{{ customerInfo.region || '未设置' }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">手机号:</span> |
| | | <span class="detail-value">{{ customerInfo.mobile || '未绑定' }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">当前积分:</span> |
| | | <span class="detail-value">{{ customerInfo.point }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">总积分:</span> |
| | | <span class="detail-value">{{ customerInfo.totalPoint }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">账号状态:</span> |
| | | <span class="detail-value"> |
| | | <Divider /> |
| | | <div class="detail-grid"> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">性别:</span> |
| | | <span class="detail-value">{{ customerInfo.sex === 0 ? "女" : "男"}}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">地区:</span> |
| | | <span class="detail-value">{{ customerInfo.region || '未设置' }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">手机号:</span> |
| | | <span class="detail-value">{{ customerInfo.mobile || '未绑定' }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">当前积分:</span> |
| | | <span class="detail-value">{{ customerInfo.point }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">总积分:</span> |
| | | <span class="detail-value">{{ customerInfo.totalPoint }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">账号状态:</span> |
| | | <span class="detail-value"> |
| | | <Tag :color="customerInfo.disabled ? 'error' : 'success'"> |
| | | {{ customerInfo.disabled ? '已禁用' : '正常' }} |
| | | </Tag> |
| | | </span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">是否关联店铺:</span> |
| | | <span class="detail-value">{{ customerInfo.haveStore ? '是' : '否' }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">注册时间:</span> |
| | | <span class="detail-value">{{ customerInfo.createTime }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">最后登录时间:</span> |
| | | <span class="detail-value">{{ customerInfo.lastLoginDate }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">是否关联店铺:</span> |
| | | <span class="detail-value">{{ customerInfo.haveStore ? '是' : '否' }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">注册时间:</span> |
| | | <span class="detail-value">{{ customerInfo.createTime }}</span> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <span class="detail-label">最后登录时间:</span> |
| | | <span class="detail-value">{{ customerInfo.lastLoginDate }}</span> |
| | | <div v-if="customerInfo.customerTagList && customerInfo.customerTagList.length > 0" class="tags-section"> |
| | | <h4>用户标签</h4> |
| | | <div> |
| | | <Tag v-for="tag in customerInfo.customerTagList" :key="tag" color="default" style="margin-right: 8px;"> |
| | | {{ tag }} |
| | | </Tag> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </TabPane> |
| | | <TabPane label="视频浏览历史" name="history"> |
| | | <watch-history |
| | | ref="watchHistoryRef" |
| | | :memberId="customerInfo.id" |
| | | key="history"/> |
| | | </TabPane> |
| | | <TabPane label="行为分析" name="actionAnalyse" > |
| | | <div class="chart-container"> |
| | | <div ref="chart" class="chart-content"></div> |
| | | </div> |
| | | </TabPane> |
| | | </Tabs> |
| | | |
| | | <div v-if="customerInfo.customerTagList && customerInfo.customerTagList.length > 0" class="tags-section"> |
| | | <h4>用户标签</h4> |
| | | <div> |
| | | <Tag v-for="tag in customerInfo.customerTagList" :key="tag" color="default" style="margin-right: 8px;"> |
| | | {{ tag }} |
| | | </Tag> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div slot="footer"> |
| | | <Button type="primary" @click="showCustomerInfo = false">关闭</Button> |
| | |
| | | |
| | | <script> |
| | | import JsonExcel from "vue-json-excel"; |
| | | import {getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions,getCustomerInfo} from "@/api/customer"; |
| | | import {memberActionAnalyse,getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions,getCustomerInfo} from "@/api/customer"; |
| | | import {addCustomerBlackByPC} from "@/api/customer-black.js" |
| | | import WatchHistory from "./WatchHistory.vue"; |
| | | import * as echarts from 'echarts'; |
| | | |
| | | export default { |
| | | name:"customer", |
| | | components:{ |
| | | "download-excel": JsonExcel, |
| | | WatchHistory, |
| | | "download-excel": JsonExcel |
| | | |
| | | }, |
| | | |
| | | data(){ |
| | | return{ |
| | | myChart: null, |
| | | activeTab: 'basic', // 当前激活的标签页 |
| | | userId: '', // 当前查看的用户ID |
| | | |
| | | customerInfo: { |
| | | birthday: null, |
| | | blackId: null, |
| | |
| | | blackParam:{ |
| | | storeId:'', |
| | | userId:'', |
| | | } |
| | | }, |
| | | |
| | | |
| | | |
| | | } |
| | | }, |
| | | |
| | | mounted(){ |
| | | this.init(); |
| | | }, |
| | | methods:{ |
| | | showLoading() { |
| | | if (this.myChart) { |
| | | this.myChart.showLoading({ |
| | | text: '数据加载中...', |
| | | color: '#1890ff', |
| | | textColor: '#333', |
| | | maskColor: 'rgba(255, 255, 255, 0.8)', |
| | | zlevel: 0, |
| | | fontSize: 14, |
| | | showSpinner: true, |
| | | spinnerRadius: 10, |
| | | lineWidth: 2, |
| | | fontWeight: 'normal' |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | hideLoading() { |
| | | if (this.myChart) { |
| | | this.myChart.hideLoading(); |
| | | } |
| | | }, |
| | | getEmptyOption() { |
| | | return { |
| | | title: { |
| | | text: '暂无数据', |
| | | left: 'center', |
| | | top: 'center', |
| | | textStyle: { |
| | | color: '#999', |
| | | fontWeight: 'normal', |
| | | fontSize: 16 |
| | | } |
| | | }, |
| | | series: [] |
| | | }; |
| | | }, |
| | | initEcharts(id){ |
| | | // 销毁旧实例 |
| | | if (this.myChart) { |
| | | this.myChart.dispose(); |
| | | } |
| | | |
| | | this.myChart = echarts.init(this.$refs.chart); |
| | | this.showLoading() |
| | | memberActionAnalyse(id).then(res =>{ |
| | | let option; |
| | | this.hideLoading() |
| | | if (res.code === 200){ |
| | | const chartData = Object.entries(res.data).map(([name, value]) => ({ |
| | | value, |
| | | name |
| | | })); |
| | | console.log(chartData) |
| | | if (chartData.length ===0){ |
| | | option = this.getEmptyOption(); |
| | | }else { |
| | | option = { |
| | | title: { |
| | | text: '用户行为分析', |
| | | left: 'center' |
| | | }, |
| | | |
| | | tooltip: { |
| | | trigger: 'item' |
| | | }, |
| | | series: [{ |
| | | radius: ['40%', '70%'], |
| | | type: 'pie', |
| | | data: chartData, |
| | | emphasis: { |
| | | itemStyle: { |
| | | shadowBlur: 10, |
| | | shadowOffsetX: 0, |
| | | shadowColor: 'rgba(0, 0, 0, 0.5)' |
| | | } |
| | | } |
| | | }] |
| | | }; |
| | | } |
| | | |
| | | this.myChart.setOption(option); |
| | | } |
| | | }) |
| | | }, |
| | | // 标签页切换处理 |
| | | handleTabChange(tabName) { |
| | | this.activeTab = tabName; |
| | | }, |
| | | |
| | | // 获得商家下拉框数据 |
| | | getStoreSelectOptions(){ |
| | | this.storeSelectLoading = true; |
| | |
| | | // 获得客户标签下拉框数据 |
| | | getCustomerTagSelectOptions(){ |
| | | this.selectLoading = true; |
| | | getTagList().then(res =>{ |
| | | this.selectLoading = false; |
| | | if (res.code === 200){ |
| | | this.tagList = res.data; |
| | | } |
| | | }) |
| | | // getTagList().then(res =>{ |
| | | // this.selectLoading = false; |
| | | // if (res.code === 200){ |
| | | // this.tagList = res.data; |
| | | // } |
| | | // }) |
| | | }, |
| | | init(){ |
| | | this.getCustomerList(); |
| | |
| | | this.selectList = e.map(d => d.id); |
| | | this.selectCount = e.length; |
| | | }, |
| | | memberActionAnalyse(id){ |
| | | |
| | | }, |
| | | //查看详情 |
| | | openInfo(row){ |
| | | this.showCustomerInfo = true; |
| | | this.modelTitle = "用户详情" |
| | | |
| | | this.activeTab = "basic" |
| | | |
| | | getCustomerInfo(row.id).then(res =>{ |
| | | if(res.code === 200){ |
| | | this.customerInfo = { |
| | |
| | | }; |
| | | } |
| | | }) |
| | | |
| | | this.initEcharts(row.id); |
| | | }, |
| | | // 编辑标签 |
| | | openEdit(row){ |
| | |
| | | |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .chart-container { |
| | | width: 100%; |
| | | height: 100%; /* 改为100%填充父容器 */ |
| | | min-height: 400px; /* 最小高度保障 */ |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | position: relative; |
| | | margin: auto; /* 新增 */ |
| | | } |
| | | .chart-content { |
| | | width: 400px; |
| | | height: 400px; |
| | | margin: 0 auto; |
| | | } |
| | | .customer-detail { |
| | | padding: 16px; |
| | | } |